Open SYS_REFCURSOR for DYNAMIC SQL
Hi!
I have stored procedure like below:
CREATE OR REPLACE
PROCEDURE MYPROCEDURE
cv_r OUT SYS_REFCURSOR
AS
lv_ExecuteString varchar(2000);
BEGIN
lv_ExecuteString := 'select 1 from dual';
open cv_r for lv_ExecuteString;
END MYPROCEDURE;and then
SQL> var y refcursor
SQL> execute myprocedure(:y);
BEGIN myprocedure(:y); END;
ERROR at line 1:
ORA-00911: invalid character
ORA-06512: at "BPATEL.MYPROCEDURE", line 9
ORA-06512: at line 1shouldnt it suppose to work??? If not then How can I fill up OUT SYS_REFCURSOR with dynamic sql string ???
although If I modify this below in my stored procedure it works fine:
-- open cv_r for lv_ExecuteString;
open cv_r for select 1 from dual;
SQL> var y refcursor
SQL> execute myprocedure(:y);
PL/SQL procedure successfully completed.
SQL> print y
1
1any idea?? why is it doing so???
What version are you on? Works fine for me....
ME_XE?CREATE OR REPLACE
2 PROCEDURE MYPROCEDURE
3 (
4 cv_r OUT SYS_REFCURSOR
5 )
6 AS
7 lv_ExecuteString varchar(2000);
8 BEGIN
9 lv_ExecuteString := 'select 1 from dual';
10 open cv_r for lv_ExecuteString;
11 END MYPROCEDURE;
12 /
Procedure created.
Elapsed: 00:00:00.71
ME_XE?var y refcursor
ME_XE?execute myprocedure(:y);
PL/SQL procedure successfully completed.
Elapsed: 00:00:00.03
ME_XE?print :y
1
1
1 row selected.
Elapsed: 00:00:00.00
ME_XE?@version
BANNER
Oracle Database 10g Express Edition Release 10.2.0.1.0 - Product
PL/SQL Release 10.2.0.1.0 - Production
CORE 10.2.0.1.0 Production
TNS for 32-bit Windows: Version 10.2.0.1.0 - Production
NLSRTL Version 10.2.0.1.0 - Production
5 rows selected.
Elapsed: 00:00:00.10
Similar Messages
-
Hi
I am using oracle 8.1.7 on solaris.
I have created
SQL> CREATE OR REPLACE PACKAGE TEST_PKG AS
2 TYPE row_cursor IS REF CURSOR RETURN TEMP_TAB%ROWTYPE;
3 PROCEDURE Return_Columns_proc (c_return IN OUT row_cursor);
4 END TEST_PKG;
5 /
Package created.
now i am trying to create the procedure Return_Columns_proc by
CREATE OR REPLACE PACKAGE BODY TEST_PKG AS
PROCEDURE Return_Columns_proc (c_return IN OUT row_cursor) AS
QUERY_STR VARCHAR2(850);
x number ;
BEGIN
x:=1;
QUERY_STR :='SELECT * FROM temp_tab where order_line_id = '||x;
OPEN c_return FOR QUERY_STR;
END Return_Columns_proc;
END TEST_PKG;
I am getting following error.
SQL> show error
Errors for PACKAGE BODY TEST_PKG:
LINE/COL ERROR
8/4 PL/SQL: Statement ignored
8/9 PLS-00455: cursor 'C_RETURN' cannot be used in dynamic SQL OPEN
statement
any help for this error.The error says it all. You have defined a strong ref cursor and it cannot be used with dynamic sql. However, that does not mean you cannot use the query directly in the OPEN clause
OPEN c_Return FOR SELECT * FROM temp_tab where order_line_id = X ; -
How can I open a cursor for dynamic sql statement
Hi,
I'm facing issues opening a cursor for dynamic sql statement : PLS-00455: cursor 'RESULT1' cannot be used in dynamic SQL OPEN statement.
CREATE OR REPLACE FUNCTION DEMO
(MN_I in VARCHAR)
return AB_OWNER.ABC_Type.NonCurTyp is
RESULT1 AB_OWNER.ABC_Type.NonCurTyp;
sql_stmt VARCHAR2(4000);
BEGIN
sql_stmt := 'SELECT * FROM AB_OWNER.DUN WHERE JZ_I in ('||mn_i||') ORDER BY app.ACC_I';
OPEN RESULT1 FOR sql_stmt;
END IF;
return RESULT1;
END DEMO;
What changes should I make in the code so that it doesn't fail? I can't change the definition of RESULT1 cursor though.Gangadhar Reddy wrote:
I used SYS REFCURSOR and was able to implement successfully.How many times did you run this successful implementation that does not use bind variables?
Because this is what will happen when it runs a lot.
http://download.oracle.com/docs/cd/E11882_01/server.112/e17766/e2100.htm#sthref1874
http://forums.oracle.com/forums/search.jspa?q=%2BORA-04031%20%2Bbind&objID=c84&dateRange=all&rankBy=10001&start=30
And you will have to regularly restart the server, or possibly slightly less invasive, flush the shared pool.
Flushing Shared Pool regularly
http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:1516005546092
>
Ok, this is an easy one to diagnose.
You are not using bind variables. This is terrible. Flushing the shared pool is a bad
solution -- you are literally killing the performance on your box by not using them.
If I was to write a book on how to build non scalable applications in Oracle, this
would be the first and last chapter. This is a major cause of performance issues and a
major inhibitor of scalability in Oracle. The way the Oracle shared pool (a very
important shared memory data structure) operates is predicated on developers using bind
variables. If you want to make Oracle run slowly, even grind to a total halt just
refuse to use them.
>
But, please feel free to go ahead with this successful implementation.
I just hope anyone else who reads this doesn't make the same mistake. -
Help required in changing to str for dynamic sql
Hi
I am trying to make this to string for dynamic sql, this is a part of the sql which is giving problem with p_..as parameters from proc. Help me in this , iam also seeing dbms _output but stil unable to format it to required error free string.
|| ' AND ( po.abbreviationprojectopportid LIKE '
|| '%'
|| 'NVL'
|| '('
|| p_opp_code
|| ', ''NULL'')'
|| '%'
|| ' OR co.companyname LIKE '
|| '%'
|| 'NVL'
|| '('
|| p_client_name
|| ', '' NULL'')'
|| '%'
|| ' OR le.line_item_amount = NVL '
|| ' ('
|| p_booking_amt
|| ', -0.197) '
|| 'OR po.dealcurrency = NVL '
|| '('
|| p_currency
|| ',''NULL'')'
|| 'OR be.booking_entry_id LIKE '
|| '%'
|| 'NVL ('
|| p_entry_id
|| ',''NULL'')'
|| '%'
|| ' OR le.line_item_id LIKE '
|| '%'
|| 'NVL ('
|| p_line_item
|| ',''null'')'
|| '%'
|| ' OR be.ticket_num LIKE '
|| '%'
|| 'NVL ('
|| p_ticket_num
|| ',''NULL'')'
|| '%'
|| ' OR be.updatedby LIKE '
|| '%'
|| 'NVL ('
|| p_user_name
|| ',''NULL'')'
|| '%'
|| ' OR credittransaction.acct_code ='
|| 'NVL ('
|| p_gl_account
|| ','
|| '-0.197)'
|| 'OR debittransaction.acct_code ='
|| 'NVL ('
|| p_gl_account
|| ', '
|| '-0.197) '
|| 'OR credittransaction.profit_ctr_code ='
|| 'NVL ('
|| p_profit_center
|| ','
|| ' -0.197)'
|| 'OR debittransaction.profit_ctr_code ='
|| 'NVL ('
|| p_profit_center
|| ','
|| '-0.197)'
|| ' OR le.sap_posting = NVL ('
|| p_sap_posting
|| ',''$'')'
|| 'OR cmis.cmis_code = NVL ('
|| p_cmis_nominal
|| ','' -0.197)'
|| 'OR sa.sap_code = NVL ('
|| p_sap_booking_entity
|| ', -0.197)'
|| ' OR (be.booking_date BETWEEN '
|| v_booking_date_from
|| 'AND '
|| v_booking_date_to
|| ')'
|| ' )'
|| 'ORDER BY '
|| p_sort_by
|| ' '
|| p_order;some errors.. Try this...
' SELECT be.booking_date bookingdate, '
|| ' be.booking_entry_id entryid, le.line_item_id itemid,'
|| ' po.abbreviationprojectopportid opportunitycode,'
|| ' co.companyname clientname, '
|| ' le.line_item_amount bookingamount,'
|| ' be.ticket_num ticketnum, po.dealcurrency currency,'
|| ' cmis.cmis_code cmis_nominal,'
|| ' sa.sap_code sap_booking_entity,'
|| ' (SELECT full_name '
|| ' FROM iba_employee '
|| ' WHERE TO_CHAR (employeeid) = be.updatedby) updatedby,'
|| ' be.updateddate updateddate, '
|| ' (SELECT le.line_item_amount * rate '
|| ' FROM iba_currencyconversion '
|| ' WHERE tocurrencycd = '
|| 'USD'
|| ' AND currencycd = po.dealcurrency '
|| ' AND conversiondate = be.booking_date) amountusd,'
|| 'debittransaction.acct_code debitglaccount,'
|| ' credittransaction.acct_code creditglaccount,'
|| ' debittransaction.profit_ctr_code debitprofitcenter,'
|| ' credittransaction.profit_ctr_code creditprofitcenter,'
|| ' debittransaction.amt debitamount,'
|| ' credittransaction.amt creditamount'
|| ' FROM rb_booking_entry be, '
|| ' rb_line_item le, '
|| ' rb_booking_period bp,'
|| ' rb_cmis_gl_account cmisgl,'
|| ' rb_cmis_account cmis,'
|| ' iba_projectopportunity po,'
|| ' iba_company co,'
|| ' rb_sap_account sa,'
|| ' (SELECT acctr.line_item_id line_item,'
|| ' sapgl_acc.account_code acct_code,'
|| ' acctr.amount amt,'
|| ' sappr.profit_center_code profit_ctr_code'
|| ' FROM rb_account_transaction acctr,'
|| ' rb_sap_profit_center sappr,'
|| ' rb_sap_gl_account sapgl_acc'
|| ' WHERE acctr.profit_center_id = sappr.profit_center_id '
|| ' AND acctr.gl_account_id = sapgl_acc.gl_account_id '
|| ' AND acctr.transaction_type = ''D'') debittransaction,'
|| ' (SELECT acctr.line_item_id line_item,'
|| ' sapgl_acc.account_code acct_code,'
|| ' acctr.amount amt,'
|| ' sappr.profit_center_code profit_ctr_code '
|| ' FROM rb_account_transaction acctr, '
|| ' rb_sap_profit_center sappr, '
|| ' rb_sap_gl_account sapgl_acc '
|| ' WHERE acctr.profit_center_id =sappr.profit_center_id '
|| ' AND acctr.gl_account_id = sapgl_acc.gl_account_id '
|| ' AND acctr.transaction_type = ''C'') credittransaction '
|| ' WHERE po.projectopportunityid = be.projectopportunityid '
|| ' AND be.booking_entry_id = le.booking_entry_id '
|| ' AND po.companyid = co.companyid '
|| ' AND bp.booking_period_id = be.booking_period_id '
|| ' AND cmis.cmis_id = cmisgl.cmis_id '
|| ' AND le.sap_id = sa.sap_id '
|| ' AND le.cmis_id = cmis.cmis_id '
|| ' AND debittransaction.line_item(+) = le.line_item_id '
|| ' AND credittransaction.line_item(+) = le.line_item_id '
|| ' AND ( po.abbreviationprojectopportid LIKE ' || '''%' || NVL(p_opp_code,'NULL') || '%'''
|| ' OR le.line_item_id LIKE '
|| '''%'
|| NVL (
|| p_line_item
|| ,'null')
|| '%'''
| ' OR le.line_item_amount = '
||NVL(|| p_booking_amt, -0.197)
|| ' OR po.dealcurrency ='
|| NVL(p_currency,'NULL')
|| ' OR be.booking_entry_id LIKE '
|| '''%'
|| NVL (p_entry_id,'NULL')
|| '%'''
|| ' OR be.ticket_num LIKE '
|| '''%'
|| NVL (p_ticket_num,'NULL')
|| '%'''
|| ' OR be.updatedby LIKE '
|| '''%'
|| NVL (p_user_name,'NULL')
|| '%'''
|| ' OR credittransaction.acct_code ='
|| NVL (p_gl_account,-0.197)
|| ' OR debittransaction.acct_code ='
|| NVL (p_gl_account, -0.197)
|| ' OR credittransaction.profit_ctr_code ='
|| NVL (p_profit_center, -0.197)
|| ' OR debittransaction.profit_ctr_code ='
|| NVL (p_profit_center, -0.197)
|| ' OR le.sap_posting = '
||NVL (p_sap_posting,'$')
|| ' OR cmis.cmis_code = '
||NVL (p_cmis_nominal, -0.197)
|| ' OR sa.sap_code = '
|| NVL (p_sap_booking_entity, -0.197)
|| ' OR (be.booking_date BETWEEN to_date('''
|| v_booking_date_from
|| ''') AND to_date('''
|| v_booking_date_to
|| ''')'
|| ' OR co.companyname LIKE '
|| '''%'
|| NVL(p_client_name,'NULL')
|| '%'''
|| ' )'
|| 'ORDER BY ' || p_sort_by || ',' || p_order; -
Open sys_refcursor for select from table variable?
Hi,
I've got a challenge for you! :-)
I've got a procedure that has a lot of logic to determine what data should be loaded into a table variable. Because of various application constraints, i can not create a global temporary table. Instead, i'd like to create a table variable and populate it with stuff as i go through the procedure.
The end result of the procedure is that i must be able to pass the results back as a sys_refcursor. This is a requirement that is beyond my control as well.
Is there a way to make this sort of procedure work?
Create Or Replace Procedure Xtst
Mu_Cur In Out Sys_Refcursor
Is
Type Xdmlrectype Is Record (Col1 Varchar2(66));
Type Xdmltype Is Table Of Xdmlrectype;
Rtn Xdmltype;
Begin
Select Internal_Id Bulk Collect Into Rtn From Zc_State;
open mu_cur for select col1 from table(rtn);
end;
11/42 PLS-00642: local collection types not allowed in SQL statements
11/36 PL/SQL: ORA-22905: cannot access rows from a non-nested table item
11/19 PL/SQL: SQL Statement ignored
Show Errors;Not anything i'd want to personally implement.
But for educational purposes only of course....
create table this_will_be_gross
column1 number,
column2 varchar2(30)
insert into this_will_be_gross values (1, 'begin the ugliness');
insert into this_will_be_gross values (2, 'end the ugliness');
variable x refcursor;
ME_XE?
declare
Rtn sys.ODCIVARCHAR2LIST;
BEGIN
SELECT
column1 || '-' || column2 Bulk Collect
INTO
Rtn
FROM
this_will_be_gross;
OPEN :x FOR
SELECT
regexp_substr (column_value, '[^-]+', 1, 1) as column1,
regexp_substr (column_value, '[^-]+', 1, 2) as column2
FROM TABLE(CAST(rtn AS sys.ODCIVARCHAR2LIST));
end;
17 /
PL/SQL procedure successfully completed.
Elapsed: 00:00:00.09
ME_XE?
ME_XE?print :x
COLUMN1 COLUMN2
1 begin the ugliness
2 end the ugliness
2 rows selected.
Elapsed: 00:00:00.11In the above example i 'knew' that a hypen was a safe character to use to break up my data elements (as it would not be found anywhere in the data itself).
I would strongly encourage you not to implement something like this. I realize it's tempting when you are working in strict environments where it can take a serious battle to get structures like temporary tables or SQL Types created, but that's really the proper approach to be taking. -
Dynamic fetch for dynamic sql query
Hi All,
I want to dynamically create a query and fetch it into a dynamic cursor record...The structure of the record should be the same as that of the query...
Can you suggest any method to do that.
eg
OPEN <dynamic cur> FOR <dynamic stmt>;
LOOP
FETCH <dynamic cur> INTO <dynamic rec>;
END LOOP;
CLOSE <dynamic cur>;
How do I declare the dynamic rec here?I would not know the columns in the query beforehand either.
Thanks,
Merz
Edited by: merz on Sep 12, 2011 5:02 PM
Edited by: merz on Sep 12, 2011 5:03 PMmerz wrote:
Hi All,
I want to dynamically create a query and fetch it into a dynamic cursor record...The structure of the record should be the same as that of the query...
Can you suggest any method to do that.And how are you expecting to write an application around a dynamic query and dynamic structure that you don't know?
Saying that, as others have said, there is the DBMS_SQL package which can be used for certain valid reasons such as the following example....
As sys user:
CREATE OR REPLACE DIRECTORY TEST_DIR AS '\tmp\myfiles'
GRANT READ, WRITE ON DIRECTORY TEST_DIR TO myuser
/As myuser:
CREATE OR REPLACE PROCEDURE run_query(p_sql IN VARCHAR2
,p_dir IN VARCHAR2
,p_header_file IN VARCHAR2
,p_data_file IN VARCHAR2 := NULL) IS
v_finaltxt VARCHAR2(4000);
v_v_val VARCHAR2(4000);
v_n_val NUMBER;
v_d_val DATE;
v_ret NUMBER;
c NUMBER;
d NUMBER;
col_cnt INTEGER;
f BOOLEAN;
rec_tab DBMS_SQL.DESC_TAB;
col_num NUMBER;
v_fh UTL_FILE.FILE_TYPE;
v_samefile BOOLEAN := (NVL(p_data_file,p_header_file) = p_header_file);
BEGIN
c := DBMS_SQL.OPEN_CURSOR;
DBMS_SQL.PARSE(c, p_sql, DBMS_SQL.NATIVE);
d := DBMS_SQL.EXECUTE(c);
DBMS_SQL.DESCRIBE_COLUMNS(c, col_cnt, rec_tab);
FOR j in 1..col_cnt
LOOP
CASE rec_tab(j).col_type
WHEN 1 THEN DBMS_SQL.DEFINE_COLUMN(c,j,v_v_val,2000);
WHEN 2 THEN DBMS_SQL.DEFINE_COLUMN(c,j,v_n_val);
WHEN 12 THEN DBMS_SQL.DEFINE_COLUMN(c,j,v_d_val);
ELSE
DBMS_SQL.DEFINE_COLUMN(c,j,v_v_val,2000);
END CASE;
END LOOP;
-- This part outputs the HEADER
v_fh := UTL_FILE.FOPEN(upper(p_dir),p_header_file,'w',32767);
FOR j in 1..col_cnt
LOOP
v_finaltxt := ltrim(v_finaltxt||','||lower(rec_tab(j).col_name),',');
END LOOP;
-- DBMS_OUTPUT.PUT_LINE(v_finaltxt);
UTL_FILE.PUT_LINE(v_fh, v_finaltxt);
IF NOT v_samefile THEN
UTL_FILE.FCLOSE(v_fh);
END IF;
-- This part outputs the DATA
IF NOT v_samefile THEN
v_fh := UTL_FILE.FOPEN(upper(p_dir),p_data_file,'w',32767);
END IF;
LOOP
v_ret := DBMS_SQL.FETCH_ROWS(c);
EXIT WHEN v_ret = 0;
v_finaltxt := NULL;
FOR j in 1..col_cnt
LOOP
CASE rec_tab(j).col_type
WHEN 1 THEN DBMS_SQL.COLUMN_VALUE(c,j,v_v_val);
v_finaltxt := ltrim(v_finaltxt||',"'||v_v_val||'"',',');
WHEN 2 THEN DBMS_SQL.COLUMN_VALUE(c,j,v_n_val);
v_finaltxt := ltrim(v_finaltxt||','||v_n_val,',');
WHEN 12 THEN DBMS_SQL.COLUMN_VALUE(c,j,v_d_val);
v_finaltxt := ltrim(v_finaltxt||','||to_char(v_d_val,'DD/MM/YYYY HH24:MI:SS'),',');
ELSE
v_finaltxt := ltrim(v_finaltxt||',"'||v_v_val||'"',',');
END CASE;
END LOOP;
-- DBMS_OUTPUT.PUT_LINE(v_finaltxt);
UTL_FILE.PUT_LINE(v_fh, v_finaltxt);
END LOOP;
UTL_FILE.FCLOSE(v_fh);
DBMS_SQL.CLOSE_CURSOR(c);
END;This allows for the header row and the data to be written to seperate files if required.
e.g.
SQL> exec run_query('select * from emp','TEST_DIR','output.txt');
PL/SQL procedure successfully completed.Output.txt file contains:
empno,ename,job,mgr,hiredate,sal,comm,deptno
7369,"SMITH","CLERK",7902,17/12/1980 00:00:00,800,,20
7499,"ALLEN","SALESMAN",7698,20/02/1981 00:00:00,1600,300,30
7521,"WARD","SALESMAN",7698,22/02/1981 00:00:00,1250,500,30
7566,"JONES","MANAGER",7839,02/04/1981 00:00:00,2975,,20
7654,"MARTIN","SALESMAN",7698,28/09/1981 00:00:00,1250,1400,30
7698,"BLAKE","MANAGER",7839,01/05/1981 00:00:00,2850,,30
7782,"CLARK","MANAGER",7839,09/06/1981 00:00:00,2450,,10
7788,"SCOTT","ANALYST",7566,19/04/1987 00:00:00,3000,,20
7839,"KING","PRESIDENT",,17/11/1981 00:00:00,5000,,10
7844,"TURNER","SALESMAN",7698,08/09/1981 00:00:00,1500,0,30
7876,"ADAMS","CLERK",7788,23/05/1987 00:00:00,1100,,20
7900,"JAMES","CLERK",7698,03/12/1981 00:00:00,950,,30
7902,"FORD","ANALYST",7566,03/12/1981 00:00:00,3000,,20
7934,"MILLER","CLERK",7782,23/01/1982 00:00:00,1300,,10The procedure allows for the header and data to go to seperate files if required. Just specifying the "header" filename will put the header and data in the one file.
Adapt to output different datatypes and styles are required. -
Concatenate problem for Dynamic SQL statements
Hi Experts ,
I am building Dynamic SQL statements depending on the values which the user enters into the select option parameters .This dynamic query is passed to cl_sql_connection object for querying from another databasse
So i wrote dynamic values for one select option spointof for the database field ppointofdelivery.
loop at spointof.
CONCATENATE ' pointofdelivery between ''' spointof-low''''
' AND ''' spointof-high''''
INTO where_clause .
endloop.
The whereclause has value pointofdelivery between '123' and '124'.(if the user has entered 123 and 124 as values)
This works fine . But my problem is I have to pass the fieldnames and operator dynamically into where_clause depending on User input.
when i am writing code like the below
field_name = ' pointofdelivery '.
operator = '='.
CONCATENATE field_name operator '''spointof-low''' INTO where_clause .
the where_clause contains value
pointofdelivery = ' spointof-low '
and not pointofdelivery = ' 123 ' as expected .
Do you know why this is haapening as it is not taking the value.
Thanks
ArshadHi,
there are lot of function modules..available...to build a where clause based on the select-options..
check the FM FREE_SELECTIONS_RANGE_2_WHERE
Thanks
Naren -
When Others not raised for Dynamic SQL occasionally
Hi All,
Please consider some part of my PL/SQL code below.
FOR rec IN cur_job_steps
LOOP
update_job_step_status(p_sector,
p_job_name,
rec.step_name,
'Running',
NULL,
SYSDATE,
NULL
-- Execute Job Step Function
EXECUTE IMMEDIATE 'BEGIN ' || rec.step_function || '; END;';
-- Set Job Step End Status
update_job_step_status(p_sector,
p_job_name,
rec.step_name,
'Successful',
NULL,
NULL,
SYSDATE
END LOOP;
EXCEPTION
WHEN OTHERS
THEN
ROLLBACK;
-- Set Job Failed Status
update_job_status(p_sector,
p_job_name,
'Failed',
'Could Not Complete DB Job: ' || SQLERRM,
NULL,
SYSDATE
-- Set Job Step Failed Status
END;
rec.step_function is a procedure without any "When Others" clause. When that exception occurs I am expecting the "When Others" clause of the calling procedure is not capturing it some times. Is there any limitation to this? Any info in this regards would be really useful.
Thanks in advance.
Best Regards
Srikanth TirandasCould not reproduce.
SQL> ed
Wrote file afiedt.buf
1 create or replace procedure my_proc
2 as
3 v_num number;
4 begin
5 v_num := 1 / 0;
6* end;
SQL> /
Procedure created.
SQL> ed
Wrote file afiedt.buf
1 begin
2 begin
3 execute immediate 'begin my_proc; end;' ;
4 end;
5 exception
6 when others then
7 dbms_output.put_line(sqlerrm);
8* end;
SQL> /
ORA-01476: divisor is equal to zero
PL/SQL procedure successfully completed.
Can you provide code for your function when it does not work ? It seems some "rec.step_function" are coded to handle exceptions and hence you don't get any in outer loop. -
For loops and dynamic sql string syntax
Hi
is there a why to loop through a dynamic sql string
normally you would have
FOR cur IN (select * from emp) LOOP
but I have a dynamic sql string called l_sql
I have tried the following
FOR cur IN l_sql LOOP
but I get
PLS-00456: item 'L_SQL' is not a cursorCompilation failed
Any ideas?You will need to use ref cursors and the OPEN v_rc FOR '<your sql string'> and then loop through it as you would with any other OPEN, LOOP, EXIT WHEN, END LOOP syntax
-
ORA-01008 with ref cursor and dynamic sql
When I run the follwing procedure:
variable x refcursor
set autoprint on
begin
Crosstab.pivot(p_max_cols => 4,
p_query => 'select job, count(*) cnt, deptno, row_number() over (partition by job order by deptno) rn from scott.emp group by job, deptno',
p_anchor => Crosstab.array('JOB'),
p_pivot => Crosstab.array('DEPTNO', 'CNT'),
p_cursor => :x );
end;I get the following error:
^----------------
Statement Ignored
set autoprint on
begin
adsmgr.Crosstab.pivot(p_max_cols => 4,
p_query => 'select job, count(*) cnt, deptno, row_number() over (partition by
p_anchor => adsmgr.Crosstab.array('JOB'),
p_pivot => adsmgr.Crosstab.array('DEPTNO', 'CNT'),
p_cursor => :x );
end;
ORA-01008: not all variables bound
I am running this on a stored procedure as follows:
create or replace package Crosstab
as
type refcursor is ref cursor;
type array is table of varchar2(30);
procedure pivot( p_max_cols in number default null,
p_max_cols_query in varchar2 default null,
p_query in varchar2,
p_anchor in array,
p_pivot in array,
p_cursor in out refcursor );
end;
create or replace package body Crosstab
as
procedure pivot( p_max_cols in number default null,
p_max_cols_query in varchar2 default null,
p_query in varchar2,
p_anchor in array,
p_pivot in array,
p_cursor in out refcursor )
as
l_max_cols number;
l_query long;
l_cnames array;
begin
-- figure out the number of columns we must support
-- we either KNOW this or we have a query that can tell us
if ( p_max_cols is not null )
then
l_max_cols := p_max_cols;
elsif ( p_max_cols_query is not null )
then
execute immediate p_max_cols_query into l_max_cols;
else
RAISE_APPLICATION_ERROR(-20001, 'Cannot figure out max cols');
end if;
-- Now, construct the query that can answer the question for us...
-- start with the C1, C2, ... CX columns:
l_query := 'select ';
for i in 1 .. p_anchor.count
loop
l_query := l_query || p_anchor(i) || ',';
end loop;
-- Now add in the C{x+1}... CN columns to be pivoted:
-- the format is "max(decode(rn,1,C{X+1},null)) cx+1_1"
for i in 1 .. l_max_cols
loop
for j in 1 .. p_pivot.count
loop
l_query := l_query ||
'max(decode(rn,'||i||','||
p_pivot(j)||',null)) ' ||
p_pivot(j) || '_' || i || ',';
end loop;
end loop;
-- Now just add in the original query
l_query := rtrim(l_query,',')||' from ( '||p_query||') group by ';
-- and then the group by columns...
for i in 1 .. p_anchor.count
loop
l_query := l_query || p_anchor(i) || ',';
end loop;
l_query := rtrim(l_query,',');
-- and return it
execute immediate 'alter session set cursor_sharing=force';
open p_cursor for l_query;
execute immediate 'alter session set cursor_sharing=exact';
end;
end;
/I can see from the error message that it is ignoring the x declaration, I assume it is because it does not recognise the type refcursor from the procedure.
How do I get it to recognise this?
Thank you in advanceThank you for your help
This is the version of Oracle I am running, so this may have something to do with that.
Oracle9i Enterprise Edition Release 9.2.0.8.0 - Production
With the Partitioning, OLAP and Oracle Data Mining options
JServer Release 9.2.0.8.0 - Production
I found this on Ask Tom (http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:3027089372477)
Hello, Tom.
I have one bind variable in a dynamic SQL expression.
When I open cursor for this sql, it gets me to ora-01008.
Please consider:
Connected to:
Oracle8i Enterprise Edition Release 8.1.7.4.1 - Production
JServer Release 8.1.7.4.1 - Production
SQL> declare
2 type cur is ref cursor;
3 res cur;
4 begin
5 open res for
6 'select * from (select * from dual where :p = 1) connect by 1 = 1'
7 using 1;
8 end;
9 /
declare
ERROR at line 1:
ORA-01008: not all variables bound
ORA-06512: at line 5
SQL> declare
2 type cur is ref cursor;
3 res cur;
4 begin
5 open res for
6 'select * from (select * from dual where :p = 1) connect by 1 = 1'
7 using 1, 2;
8 end;
9 /
PL/SQL procedure successfully completed.
And if I run the same thing on 10g -- all goes conversely. The first part runs ok, and the second
part reports "ORA-01006: bind variable does not exist" (as it should be, I think). Remember, there
is ONE bind variable in sql, not two. Is it a bug in 8i?
What should we do to avoid this error running the same plsql program code on different Oracle
versions?
P.S. Thank you for your invaluable work on this site.
Followup June 9, 2005 - 6pm US/Eastern:
what is the purpose of this query really?
but it would appear to be a bug in 8i (since it should need but one). You will have to work that
via support. I changed the type to tarray to see if the reserved word was causing a problem.
variable v_refcursor refcursor;
set autoprint on;
begin
crosstab.pivot (p_max_cols => 4,
p_query =>
'SELECT job, COUNT (*) cnt, deptno, ' ||
' ROW_NUMBER () OVER ( ' ||
' PARTITION BY job ' ||
' ORDER BY deptno) rn ' ||
'FROM emp ' ||
'GROUP BY job, deptno',
p_anchor => crosstab.tarray ('JOB'),
p_pivot => crosstab.tarray ('DEPTNO', 'CNT'),
p_cursor => :v_refcursor);
end;
/Was going to use this package as a stored procedure in forms but I not sure it's going to work now. -
Is there a solution for dynamic reports and using Denes' Export to Excel?
Oracle 10.2.0.4.0
Application Express 3.2.1.00.10
Hello all!
I am using Denes Kubicek's Export_Excel_Pkg in my application and I'm having trouble exporting reports based on report regions created using a PL/SQL function body returning SQL query. I realize this is not an Oracle supported package, but was hoping someone here could shed some light on it. When I open up the Excel file, I get an error such as: Report Values Error: ORA-06550: line 22, column 5: PL/SQL: ORA-00907: missing right parenthesis.
I've searched the forum and already have done as others suggested by modifying the REPLACE on the v_sql variable in Export_Excel_Pkg.Get_Usable_SQL, but it did not work. My assumption is that there is an issue with the value being passed to the wwv_flow_utilities.get_binds function. I could not find documentation on this function, but I'm thinking that it cannot extract the bind variables within a PL/SQL block. The report only works when I have just use SQL with bind variables...doesn't work for PL/SQL. Nor does it work for dynamic SQL reports that use a "lexical" parameter (e.g. using WHERE &p_and_condition.) to build the WHERE clause.
Has anyone come up with a work-around to this? I somehow need to be able to extract reports based on dynamic SQL (or PL/SQL) to Excel.
Help is appreciated!
This is my example of a report based on PL/SQL function:
DECLARE
v_sql VARCHAR2(4000);
BEGIN
v_sql := q'[SELECT UPPER(t1.olo_name) agency_title,
t1.class_code,
UPPER(t1.class_title) class_title,
t1.pay_plan,
t1.pay_grade_code,
COUNT(t1.appt_fte) total_employees,
SUM(t1.appt_fte) filled_fte,
AVG(DECODE(t2.pay_cycle_code,
'UB',((t1.wage_type1_amt_for_pay * 26)/t1.appt_fte),
'UM',((t1.wage_type1_amt_for_pay * 12)/t1.appt_fte),
0)) avg_annual_rate
FROM my_schema.table1 t1,
my_schema.table2 t2,
my_schema.table3 pro
WHERE t1.pos_wk = t2.pos_wk
AND t2.pos_rate_active_flag = 'Y'
AND t1.ops_ind = 'N'
AND t1.employee_type IN ('1','2')
AND pro.ROLE_CODE = :F101_DW_ROLE
AND pro.pos_role_orgs_active_flag = 'Y']';
IF :P_MULTI_OLO IS NOT NULL THEN
v_sql := v_sql || q'[ AND INSTR(':'||']' || v('P_MULTI_OLO') || q'['||':', ':'||t1.olo_code||':') > 0]';
END IF;
v_sql := v_sql || q'[GROUP BY UPPER(t1.olo_name), t1.class_code, UPPER(t1.class_title), t1.pay_plan, t1.pay_grade_code ORDER BY t1.class_code ASC, avg_annual_rate]';
RETURN v_sql;
END;This is my example using a SQL statement with a lexical parameter:
SELECT UPPER(t1.olo_name) agency_title,
t1.class_code,
UPPER(t1.class_title) class_title,
t1.pay_plan,
t1.pay_grade_code,
COUNT(t1.appt_fte) total_employees,
SUM(t1.appt_fte) filled_fte,
AVG(DECODE(t2.pay_cycle_code,
'UB',((t1.wage_type1_amt_for_pay * 26)/t1.appt_fte),
'UM',((t1.wage_type1_amt_for_pay * 12)/t1.appt_fte),
0)) avg_annual_rate
FROM my_schema.table1 t1,
my_schema.table2 t2,
my_schema.table3 pro
WHERE t1.pos_wk = t2.pos_wk
AND t2.pos_rate_active_flag = 'Y'
AND t1.ops_ind = 'N'
AND t1.employee_type IN ('1','2')
AND pro.ROLE_CODE = :F101_DW_ROLE
AND pro.pos_role_orgs_active_flag = 'Y'
&P63_AND_CONDITION.
GROUP BY UPPER(t1.olo_name),
t1.class_code,
UPPER(t1.class_title),
t1.pay_plan,
t1.pay_grade_code
ORDER BY t1.class_code ASC, avg_annual_rateThe *&P63_AND_CONDITION.* value is populated based on a "Before Header" computation under Page Rendering, using the logic below. It is then used by the SQL query defined in the reports region at run time.
DECLARE
v_sql VARCHAR2(4000) := NULL;
BEGIN
v_sql := ' ';
IF :P_MULTI_OLO IS NOT NULL THEN
v_sql := v_sql || q'[ AND INSTR(':'||']' || v('P_MULTI_OLO') || q'['||':', ':' || t1.olo_code || ':') > 0]';
END IF;
RETURN v_sql;
END;Did you get an answer for this?
-
Hello Everyone
I am using database 11g. Can someone pl suggest what are the rules for putting single quotes for dynamic sql like
1) how many single quotes before/after a sql statement .
2) Rules for putting single quotes if there exists i) a variable in the sql statement
ii) a constant for e.g 100 in the sql statment.
If you could give the answers with a simple select statement, it will be even better !!!
Thanks and regards
Gautamms wrote:
Hello Everyone
I am using database 11g. Can someone pl suggest what are the rules for putting single quotes for dynamic sql like
1) how many single quotes before/after a sql statement .
2) Rules for putting single quotes if there exists i) a variable in the sql statement
ii) a constant for e.g 100 in the sql statment.
If you could give the answers with a simple select statement, it will be even better !!!
Thanks and regards
Gautamwrite the SQL statement as you would for any SQL client & enclose it using Q-quote
http://askanantha.blogspot.com/2007/12/q-quote-operator-introduced-in-oracle.html
Handle: ms
Status Level: Newbie
Registered: Jun 3, 2007
Total Posts: 46
Total Questions: 17 (17 unresolved)
WOW!
*NEVER got any answer in 5+ years & still wasting time here again, still!
You must be an eternal optimist.
I hope I get credited for your FIRST answer. -
Doubt & Error Using Dynamic SQL
Hello,
According to oracle documentation for Dynamic SQL using ' Method 2 ' ... which says ...
Method 2
This method lets your program accept or build a dynamic SQL statement, then process it using the PREPARE and EXECUTE commands. The SQL statement must not be a query. The number of placeholders for input host variables and the datatypes of the input host variables must be known at precompile time. For example, the following host strings fall into this category:
'INSERT INTO EMP (ENAME, JOB) VALUES (:emp_name, :job_title)'
'DELETE FROM EMP WHERE EMPNO = :emp_number'
Now for trying this method i created a procedure .. named .. 'aj_proc_1'
CREATE OR REPLACE PROCEDURE aj_proc_1(p_id IN NUMBER)
IS
BEGIN
EXECUTE IMMEDIATE 'delete from aj_test_1 where id = :p_id';
END aj_proc_1;
And the table which m using in this procedure is ...
SQL> select * from aj_test_1;
ID NAME
1 aijaz
2 melwin
3 aasim
4 satish
5 ashok
So now whn m calling this Procedure & wanted to delete the record with id '2' ... m getting an Error...the way m executing this procedure is ...
SQL> execute aj_proc_1(2);
BEGIN aj_proc_1(2); END;
ERROR at line 1:
ORA-01008: not all variables bound
ORA-06512: at "FA.AJ_PROC_1", line 4
ORA-06512: at line 1
Please Help me .. As i have no idea ..wats goin wrong over here...Now whats Wrong with this 1 ....
CREATE OR REPLACE PROCEDURE aj_proc_1(p_id IN NUMBER)
IS
val_name varchar2(34);
BEGIN
EXECUTE IMMEDIATE 'select name into '||val_name||' from aj_test_1 where id = :p_id'
USING p_id ;
dbms_output.put_line(val_name);
END aj_proc_1;
SQL> exec aj_proc_1(2);
BEGIN aj_proc_1(2); END;
ERROR at line 1:
ORA-00936: missing expression
ORA-06512: at "FA.AJ_PROC_1", line 5
ORA-06512: at line 1
----------------------------------------------------------------------------------- -
SQL: Having problems passing a date value to dynamic SQL
SQL Version 2008 (not R2)
Problem: 1) I'm getting the following error message when trying to run the sql code below.
SQL "Messages" Returned when running code:
Msg 206, Level 16,
State 2, Procedure uspxc_WAWP_10_Get_VPData, Line 0
Operand type clash: int is incompatible with date
Loaded VP DATA for Month: 20121201
Problem Code Line:
SET @dynamicSQL = 'EXEC ' + @StoredProcedureName + ' ' + @DEVModeYN + ', ' + CAST(@WIPMonth as varchar);
Any help would be greatly appreciated. I've spent several hours trying to get around this error.
Full Code:
ALTER PROCEDURE [dbo].[uspxi_XIUD_98_DataConversionGET_VP_WIPJobHistory] (@DEVModeYN nchar(1) = 'D', @WIPMonth Date)
AS
BEGIN
SET NOCOUNT ON;
DECLARE @returnCode AS INT ,
@dynamicSQL AS VARCHAR(8000),
@msg as varchar(60),
@DEVModeYN nchar(1) = 'D',
@WIPMonth date = '20121201',
@StoredProcedureName AS VARCHAR(60)
SET @returnCode = 0
SET @StoredProcedureName = 'uspxc_WAWP_10_Get_VPData'
-- Check to see if @StoredProcedureName exists in the database.
IF EXISTS(SELECT name FROM sys.procedures WHERE name = @StoredProcedureName)
BEGIN
-- RUN SP to Import VP Data for each WIPMonth parameter value
SET @dynamicSQL = 'EXEC ' + @StoredProcedureName + ' ' + @DEVModeYN + ', ' + CAST(@WIPMonth as varchar);
SELECT @dynamicSQL;
-- RUN stored procedure for WIP Month
EXEC (@dynamicSQL);
SET @returnCode = 0;
SELECT @returnCode;
SET @msg = 'Loaded VP DATA for Month: ' + @WIPMonth;
PRINT @msg;
GoTo SPEND
END
ELSE
SET @returnCode = 1;
SET @msg = 'NO DATA IMPORTED for Month: ' + CAST(@WIPMonth as varchar(10))
PRINT @msg
SPEND:
END
Bob SutorWhen you work with dynamic SQL, you should never build a full SQL string by concatenating values, because this is more difficult to get right and also has problems with SQL injection and efficient use of the SQL Server cache.
So the correct way to do this in dynamic SQL would be:
SET @dynamicSQL = 'EXEC ' + quotename(@StoredProcedureName) '@DEVModeYN, @WIPMonth';
EXEC sp_executesql @SQL, N'DEVModeYN nchar(1), @WIPMonth date',
@DEVModeYN, @WIPMonth
A lot easier and cleaner! (Note that the variable @SQL must be declared as nvarchar.)
...however, in this particular case, this is still an overkill, and there is no need for dynamic SQL at all. EXEC accepts a variable for the procedure name, so:
EXEC @StoredProcedureName @DEVModeYN, @WIPMonth
...but it does not stop there. You can make all these changes, but you will get the same error. To wit, you get the error on Line 0, which means that it is the call to the procedure that fails. Apparently, you are passing an integer value, when you were
supposed to pass a date. Maybe you forgot to put the dates in quotes?
Erland Sommarskog, SQL Server MVP, [email protected] -
Dynamic SQL queries in HTMLDB application
How can i build a HTMLDB page only for dynamic sql queries like the features in the HTMLDB SQL-workshop.
I need a SQL interface for some power user running some ad-hoc queries.
Can i call this page directly from any other HTMLDB application?
Regards
MartinHello Martin,
I am a beginer in APEX but I have the same problem with you. What are your solution for dynamic sql query ? For report a solution is Pl Sql procedure which return a sql query. But for a form ?
Maybe you are looking for
-
Is it a bad idea to use Time Capsule to access my iTunes music?
I'm thinking about putting all of my music on my time capsule and making iTunes access it through that. Is this a bad idea for any reason? I'm thinking that there could be a few seconds of delay when playing a song or something, which I don't really
-
I got an iPhone five but my apps don't fit to my screen how do you do it?
my apps don't fit to the screen of my iPhone five how do you do it?
-
Hi, I am having a problem posting treasury deals to balance sheet accounts. All configuration in treasury is fine but posting returns the error "Field profit centre required for account xxxx xxxxxx". I have assigned a profit centre to these accounts
-
Where to get ABAP Development Workbench ?
Hello sap gurus, I alredy have SAP NetWeaver Enterprise Portal on MaxDB - Developer Edition Sneak Preview installed on my server. However I want to use the ABAP Development Workbench. I do now want to buy a book with cds or go to the sap shop site t
-
DBMS_ERROR_TEXT failure with Headstart Utilities Admin form
I have installed the Headstart Oracle Designer for Designer/Developer 6.0, following instructions found in the patch for 6.0. Whenever I try to start the Headstart Utilities Administration form, I get an error stating that DBMS_ERROR_TEXT failed. Has