Cursor bind variable syntax err
Any one help me in correcting the syntax, for cursor return.
Oracle version 10g
I am trying to execute the sproc and print the cursor results using bind variable, I am getting he below error
Variable V_REFCUR REFCURSOR
Variable V_REFCUR2 REFCURSOR
variable swp_ret_value NUMBER
exec DELETE_POSITION(0,0,2,'U',:swp_ret_value,:V_REFCUR,:V_REFCUR2)
print swp_ret_value
Print v_refcur
Print v_refcur2
-- output
Error starting at line 5 in command:
exec DELETE_POSITION(0,0,2,'U',:swp_ret_value,:V_REFCUR,:V_REFCUR2)
Error report:
Cursor is closed.
SWP_RET_VALUE
V_REFCUR
V_REFCUR2
------Edited by: NeilCSE on Jan 18, 2011 4:08 AM
it is calling another proc
PROCEDURE Assign_outRefcur2 (CurrentCursor IN OUT SYS_REFCURSOR
, v_ref_cur IN OUT SYS_REFCURSOR
, v_ref_cur2 IN OUT SYS_REFCURSOR
AS
InitCursor SYS_REFCURSOR;
BEGIN
IF NOT v_ref_cur%IsOpen THEN v_ref_cur := CurrentCursor;
ELSIF NOT v_ref_cur2%IsOpen THEN v_ref_cur2 := CurrentCursor;
END IF;
CurrentCursor:= InitCursor;
END;
Similar Messages
-
SLOW report performance with bind variable
Environment: 11.1.0.7.2, Apex 4.01.
I've got a simplified report page where the report runs slowly compared to running the same query in sqldeveloper. The report region is based on a pl/sql function returning a query. If I use a bind variable in the query inside apex it takes 13 seconds to run, and if I hard code a string it takes only a few hundredths of a second. The query returns one row from a table which has 1.6 million rows. Statistics are up-to-date and the columns in the joins and where clause are indexed.
I've run traces using p_trace=YES from Apex for both the bind variable and hard coded strings. They are below.
The sqldeveloper explain plan is identical to the bind variable plan from the trace, yet the query runs in 0.0x seconds in sqldeveloper.
What is it about bind variable syntax in Apex that is causing the bad execution plan? Apex Bug? 11g bug? Ideas?
tkprof output from Apex trace with bind variable is below...
select p.master_id link, p.first_name||' '||p.middle_name||' '||p.last_name||' '||p.suffix personname,
p.gender||' '||p.date_of_birth g_dob, p.master_id||'*****'||substr(p.ssn,-4) ssn, p.status status
from persons p
where
p.person_id in (select ps.person_id from person_systems ps where ps.source_key like LTRIM(RTRIM(:P71_SEARCH_SOURCE1)))
order by 1
call count cpu elapsed disk query current rows
Parse 1 0.00 0.00 0 0 0 0
Execute 1 0.00 0.01 0 1 27 0
Fetch 2 13.15 13.22 67694 72865 0 1
total 4 13.15 13.23 67694 72866 27 1
Misses in library cache during parse: 0
Optimizer mode: ALL_ROWS
Parsing user id: 62 (ODPS_PRIVACYVAULT) (recursive depth: 1)
Rows Row Source Operation
1 SORT ORDER BY (cr=72869 pr=67694 pw=0 time=0 us cost=29615 size=14255040 card=178188)
1 FILTER (cr=72869 pr=67694 pw=0 time=0 us)
1 HASH JOIN RIGHT SEMI (cr=72865 pr=67694 pw=0 time=0 us cost=26308 size=14255040 card=178188)
1 INDEX FAST FULL SCAN IDX$$_0A300001 (cr=18545 pr=13379 pw=0 time=0 us cost=4993 size=2937776 card=183611)(object id 68485)
1696485 TABLE ACCESS FULL PERSONS (cr=54320 pr=54315 pw=0 time=21965 us cost=14958 size=108575040 card=1696485)
Rows Execution Plan
0 SELECT STATEMENT MODE: ALL_ROWS
1 SORT (ORDER BY)
1 FILTER
1 HASH JOIN (RIGHT SEMI)
1 INDEX MODE: ANALYZED (FAST FULL SCAN) OF
'IDX$$_0A300001' (INDEX)
1696485 TABLE ACCESS MODE: ANALYZED (FULL) OF 'PERSONS' (TABLE)
Elapsed times include waiting on following events:
Event waited on Times Max. Wait Total Waited
---------------------------------------- Waited ---------- ------------
db file scattered read 1276 0.00 0.16
db file sequential read 812 0.00 0.02
direct path read 1552 0.00 0.61
********************************************************************************Here's the tkprof output with a hard coded string:
select p.master_id link, p.first_name||' '||p.middle_name||' '||p.last_name||' '||p.suffix personname,
p.gender||' '||p.date_of_birth g_dob, p.master_id||'*****'||substr(p.ssn,-4) ssn, p.status status
from persons p
where
p.person_id in (select ps.person_id from person_systems ps where ps.source_key like LTRIM(RTRIM('0b')))
order by 1
call count cpu elapsed disk query current rows
Parse 1 0.02 0.04 0 0 0 0
Execute 1 0.00 0.00 0 0 13 0
Fetch 2 0.00 0.00 0 8 0 1
total 4 0.02 0.04 0 8 13 1
Misses in library cache during parse: 1
Optimizer mode: ALL_ROWS
Parsing user id: 62 (ODPS_PRIVACYVAULT) (recursive depth: 1)
Rows Row Source Operation
1 SORT ORDER BY (cr=10 pr=0 pw=0 time=0 us cost=9 size=80 card=1)
1 FILTER (cr=10 pr=0 pw=0 time=0 us)
1 NESTED LOOPS (cr=8 pr=0 pw=0 time=0 us)
1 NESTED LOOPS (cr=7 pr=0 pw=0 time=0 us cost=8 size=80 card=1)
1 SORT UNIQUE (cr=4 pr=0 pw=0 time=0 us cost=5 size=16 card=1)
1 TABLE ACCESS BY INDEX ROWID PERSON_SYSTEMS (cr=4 pr=0 pw=0 time=0 us cost=5 size=16 card=1)
1 INDEX RANGE SCAN IDX_PERSON_SYSTEMS_SOURCE_KEY (cr=3 pr=0 pw=0 time=0 us cost=3 size=0 card=1)(object id 68561)
1 INDEX UNIQUE SCAN PK_PERSONS (cr=3 pr=0 pw=0 time=0 us cost=1 size=0 card=1)(object id 68506)
1 TABLE ACCESS BY INDEX ROWID PERSONS (cr=1 pr=0 pw=0 time=0 us cost=2 size=64 card=1)
Rows Execution Plan
0 SELECT STATEMENT MODE: ALL_ROWS
1 SORT (ORDER BY)
1 FILTER
1 NESTED LOOPS
1 NESTED LOOPS
1 SORT (UNIQUE)
1 TABLE ACCESS MODE: ANALYZED (BY INDEX ROWID) OF
'PERSON_SYSTEMS' (TABLE)
1 INDEX MODE: ANALYZED (RANGE SCAN) OF
'IDX_PERSON_SYSTEMS_SOURCE_KEY' (INDEX)
1 INDEX MODE: ANALYZED (UNIQUE SCAN) OF 'PK_PERSONS'
(INDEX (UNIQUE))
1 TABLE ACCESS MODE: ANALYZED (BY INDEX ROWID) OF
'PERSONS' (TABLE)Patrick, interesting insight. Thank you.
The optimizer must be peeking at my bind variables with it's eyes closed. I'm the only one testing and I've never passed %anything as a bind value. :)
Here's what I've learned since my last post:
I don't think that sqldeveloper is actually using the explain plan it says it is. When I run explain plan in sqldeveloper (with a bind variable) it shows me the exact same plan as Apex with a bind variable. However, when I run autotrace in sqldeveloper, it takes a path that matches the hard coded values, and returns results in half a second. That autotrace run is consistent with actually running the query outside of autotrace. So, I think either sqldeveloper isn't really using bind variables, OR it is using them in some other way that Apex does not, or maybe optimizer peeking works in sqldeveloper?
Using optimizer hints to tweak the plan helps. I've tried both /*+ FIRST_ROWS */ and /*+ index(ps pk_persons) */ and both drop the query to about a second. However, I'm loath to use hints because of the very dynamic nature of the query (and Tom Kyte doesn't like them either). The hints may end up hurting other variations on the query.
I also tested the query by wrapping it in a select count(1) from ([long query]) and testing the performance in sqldeveloper and in Apex. The performance in that case is identical with both bind variables and hard coded variables for both Apex and SqlDeveloper. That to me was very interesting and I went so far as to set up two bind variable report regions on the same page. One region wrapped the long query with select count(1) from (...) and the other didn't. The wrapped query ran in 0.01 seconds, the unwrapped took 15ish seconds with no other optimizations. Very strange.
To get performance up to acceptable levels I have changed my function returning query to:
1) Set the equality operator to "=" for values without wildcards and "like" for user input with wildcards. This makes a HUGE difference IF no wildcard is used.
2) Insert a /*+ FIRST_ROWS */ hint when users chose the column that requires the sub-query. This obviously changes the optimizer's plan and improves query speed from 15 seconds to 1.5 seconds even with wildcards.
I will NOT be hard coding any user supplied values in the query string. As you can probably tell by the query, this is an application where sql injection would be very bad.
Jeff, regarding your question about "like '%' || :P71_SEARCH_SOURCE1 || '%'". I've found that putting wildcards around values, particularly at the beginning will negate any indexing on the column in question and slows performance even more.
I'm still left wondering if there isn't something in Apex that is breaking the optimizer "peeking" that Patrick describes. Perhaps something in the way it switches contexts from apex_public_user to the workspace schema? -
Can I put a SQL query into a bind variable and then use it to output report
Hi,
Can I put a SQL query into a bind variable and then use it to output report?
I want to create a report and an item "text area" (say P1_TEXT) which can let user to input a SQL query(they are all technical users and knows SQL very well). Then, I use a bind variable (that text area) to store the SQL statement. Then, I add a submit button and I want to use the following to output the report:
select * from (:P1_TEXT);
Do you think it is possible to do that? Any known limitations for APEX in this area?
Thanks a lot,
AngelaYou can, but make sure it's what you really want to do. Make sure you are VERY familiar with SQL Injection. Most people who know what it is, go out of their way to prevent SQL Injection. You're going out of your way to allow it.
You can try using &P1_TEXT. instead of bind variable syntax. Bind variables are one of the best ways to prevent SQL Injection, which is why it's not working for you.
Once again, I strongly urge you to consider the implications of your app, but this suggestion should get it working.
Tyler -
Is the bind variable syntax supported in procedure? The following produces error:
VARIABLE salary number
CREATE OR REPLACE PROCEDURE bindvar
is
eid employees.employee_id%type;
BEGIN
SELECT employee_id INTO eid FROM EMPLOYEES
WHERE employee_id > :salary and rownum=1;
DBMS_OUTPUT.PUT_LINE(:salary);
END;
LINE/COL ERROR
6/26 PLS-00049: bad bind variable 'SALARY'
7/24 PLS-00049: bad bind variable 'SALARY'
But if I change the procedure to an anonymous block, everything works fine!your variable salary declaration exists only in the current SQL*Plus session. It is not going to be existing in all the environments from where this stored procedure can be called and certainly not on the server where the code is stored in the database.
The reference can be used in an anonymous block run from the same SQL*Plus session, since it is one time execution. Not in a stored procedure like the way you intend.
You could have the stored procedure take a number as input and use that parameter in your sql. then at SQL*Plus prompt call the procedure passing the value in :salary variable to get the results. -
I want to use a bind variable in order to insert a binary data in a raw field.
I do this in a C# app., using parameters, in Oracle Server it works successfully
but when I change the conection to a Oracle Lite Data Base the bd returns
the error "37000[POL-5228]: Syntaxis Error".
The sql is like this: "insert into GENERIC_TABLE (id, data) values ("+id.ToString()+", :Data)"
And after I insert the parameter.
Does someone know if in Lite the bind variables syntaxis is diferent?
Could you help me? What's happend in lite version?
Thanks in advanceHi,
As far I know, SQL Statements, metadata, user names, etc... in fact every string that is not binded or defined can only be ANSI or UTF16. -
I want to use a bind variable in order to insert a binary data in a raw field.
I do this in a C# app., using parameters, in Oracle Server it works successfully
but when I change the conection to a Oracle Lite Data Base the bd returns
the error "37000[POL-5228]: Syntaxis Error".
The sql is like this: "insert into GENERIC_TABLE (id, data) values ("+id.ToString()+", :Data)"
And after I insert the parameter.
Does someone know if in Lite the bind variables syntaxis is diferent?
Could you help me? What's happend in lite version?
Thanks in advanceHi,
You can write simple select statement in VO query without any where clause like this:
SELECT po_header_id PoHeaderId,LISTAGG(po_line_id,',') WITHIN GROUP (ORDER BY po_header_id) PoLineIds FROM xxpo_dropship_documents_v
and then set where clause using vo.setWhereClause("<condition>");
after this, use vo.setWhereClauseParam() to set the parameters values.
--Sushant -
Slow performance when using cursor with bind variable
i'm facing the problem mentioned in the subject.
whenever i use the bind variable it would take more than 5mins to fetch 157 records, but if i hardcode the value ( not using variable ) it would take only 10sec to fetch 157 records.
can anyone give me some guide to solve this problem? thank you..
Code :
DECLARE
cursor cur1(l_startdate IN varchar2,l_enddate IN varchar2) IS
select * from shipment ship where ship.insertion_date >= to_date(l_startdate,'DD-MM-YYYY HH24:MI:SS') and ship.insertion_date < to_date(l_enddate ,'DD-MM-YYYY HH24:MI:SS')
TYPE shipment_aat IS TABLE OF cur1%ROWTYPE INDEX BY PLS_INTEGER;
l_shpt shipment_aat;
limit_in INTEGER := 100;
BEGIN
v_startdate := '10-06-2008 14:00:00';
v_enddate := '10-06-2008 17:00:00';
OPEN C_shpt(v_startdate,v_enddate);
LOOP --start shipment loop
FETCH C_shpt BULK COLLECT INTO l_shpt LIMIT limit_in;
FOR indx IN 1 .. l_shpt.COUNT
LOOP
DBMS_OUTPUT.PUT_LINE('l_shpt value ' || l_shpt(indx).ship_number || '/' || l_shpt(indx).insertion_date);
END LOOP;
EXIT WHEN l_shpt.COUNT < limit_in;
END LOOP; -- end of shipment loop
CLOSE cur1;
END;When your query takes too long ...
-
Syntax to print to bind variable to screen
I need to know the correct syntax to print out the bind variable contents to the xterm screen.
Hi Veeranagi,
To print Dashed line, either you can use
WRITE: '----
If you dont want to use such statement, simply create a text element with
TEXT-001 '----
' and then use
WRITE: TEXT-001
Reward if useful.
Best Regards,
Ram. -
Using BIND VARIABLES in REF CURSOR(s)
Hello I am having trouble making my pl/sql program work using bind variables.
here is a little snipit from my code:
declare
type ref_type is REF CURSOR;
ref_cursor ref_type;
summation_table varchar2(4000);
begin
summation_table := 'table_sum tsum';
open ref_cursor for
select * from :summation_table
where tsum.revenue = 1000
USING summation_table;
end;
The Error that I get is
"bad bind variable 'summation_table'"
could someone please help? I think the way 'tsum' is used could be a problem, but I don't know.SQL> CREATE TABLE TABLE_SUM(REVENUE NUMBER(10),
2 OTHER NUMBER(10));
Table created.
SQL> INSERT INTO TABLE_SUM VALUES(1000,1);
1 row created.
SQL> INSERT INTO TABLE_SUM VALUES(1000,2);
1 row created.
SQL> variable alpha refcursor
SQL> INSERT INTO TABLE_SUM VALUES(2000,3);
1 row created.
SQL> DECLARE
2 summation_table varchar2(30) := 'table_sum tsum';
3 PROCEDURE MYTEST(p_out out sys_refcursor)
4 IS
5 BEGIN
6 OPEN p_out for 'select * from '||summation_table||
7 ' where tsum.revenue = :val' using 1000;
8 END;
9 BEGIN
10 MYTEST(:alpha);
11 END;
12 /
PL/SQL procedure successfully completed.
SQL> print alpha
REVENUE OTHER
1000 1
1000 2
SQL> -
Version details
BANNER
Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 - 64bi
PL/SQL Release 10.2.0.4.0 - Production
CORE 10.2.0.4.0 Production
TNS for Solaris: Version 10.2.0.4.0 - Production
NLSRTL Version 10.2.0.4.0 - ProductionBelow is the procedure where I'm using ref cursor
CREATE OR REPLACE PROCEDURE ref_sample
p_account_nbr in varchar2,
p_ref_out out sys_refcursor
IS
BEGIN
OPEN p_ref_out FOR
SELECT account_nbr,status,(
CASE
WHEN status = 'Pending' THEN
req_mail_date
WHEN status IN ('Rejected','Approved') THEN
NVL(verified_mail_date,req_mail_date)
END
)req_mail_date ,
CASE
WHEN status = 'Pending' THEN
NULL
WHEN status IN ('Rejected','Approved') THEN
NVL(verified_user_id,req_user_id)
END
)req_user_id
FROM X_tbl
WHERE account_nbr IN p_account_nbr
AND TRUNC(upload_date) = TRUNC(SYSDATE)
ORDER BY upload_date DESC ;
END;
/My input parameter p_account_nbr looks like ('a1','a2','a3')
Now,after knowing the importance of bind variables I'd like to make use of them in the above ref cursor.
But,here my input parameter is a string of varying length..either I've to go for the approach suggested here
http://asktom.oracle.com/pls/asktom/f?p=100:11:3667281145899708::::P11_QUESTION_ID:110612348061
or
http://www.dba-oracle.com/t_cursor_sharing.htm
I'm not much clear with the first approach,so I'm thinking of to modify my procedure as below
CREATE OR REPLACE PROCEDURE ref_sample
p_account_nbr in varchar2,
p_ref_out out sys_refcursor
IS
BEGIN
alter session set cursor_sharing=force;
OPEN p_ref_out FOR
SELECT account_nbr,status,(
CASE
WHEN status = 'Pending' THEN
req_mail_date
WHEN status IN ('Rejected','Approved') THEN
NVL(verified_mail_date,req_mail_date)
END
)req_mail_date ,
CASE
WHEN status = 'Pending' THEN
NULL
WHEN status IN ('Rejected','Approved') THEN
NVL(verified_user_id,req_user_id)
END
)req_user_id
FROM X_tbl
WHERE account_nbr IN p_account_nbr
AND TRUNC(upload_date) = TRUNC(SYSDATE)
ORDER BY upload_date DESC ;
alter session set cursor_sharing=exact;
END;
/Please let me know if the above modified code is fine or should I use bind variables??Also let me know better approach of both.The correct way to do this is use an array type for the input values as in this example.
SQL> create or replace procedure p
2 (
3 p_values sys.odcivarchar2list,
4 c out sys_refcursor
5 ) as
6 begin
7 open c for
8 select object_name, owner, object_type
9 from all_objects
10 where object_name in (select column_value from table(p_values));
11 end;
12 /
Procedure created.
SQL> var c refcursor
SQL> exec p (sys.odcivarchar2list('DUAL','USER_VIEWS'), :c)
PL/SQL procedure successfully completed.
SQL> print c
OBJECT_NAME OWNER OBJECT_TYPE
DUAL SYS TABLE
DUAL PUBLIC SYNONYM
USER_VIEWS SYS VIEW
USER_VIEWS PUBLIC SYNONYM
SQL> exec p (sys.odcivarchar2list('DUAL','USER_VIEWS','ALL_OBJECTS','ALL_SOURCE'), :c)
PL/SQL procedure successfully completed.
SQL> print c
OBJECT_NAME OWNER OBJECT_TYPE
DUAL SYS TABLE
DUAL PUBLIC SYNONYM
ALL_OBJECTS SYS VIEW
ALL_OBJECTS PUBLIC SYNONYM
USER_VIEWS SYS VIEW
USER_VIEWS PUBLIC SYNONYM
ALL_SOURCE SYS VIEW
ALL_SOURCE PUBLIC SYNONYM
8 rows selected.
SQL>That and other methods are described here.
http://tkyte.blogspot.com/2006/06/varying-in-lists.html
You would not use dynamic SQL. -
Open cursor for and bind variables
Hello all,
how can I assign values to a bind variable before opening a cursor?
example code:
DECLARE
TYPE ref_cur_t IS REF CURSOR;
l_ref_cur ref_cur_t;
l_query VARCHAR2 (100)
:= 'select * from table t1 where ndx= :var_index' ;
BEGIN
-- assign a value to :var_index
OPEN l_ref_cur FOR l_query;
END;Thanks!Something like this ->
scott@ORCL>
scott@ORCL>DECLARE
2 l_ref_cur sys_refcursor;
3 l_query VARCHAR2 (100) := 'select * from emp where empno = :var_index';
4 l_empno number(4);
5 BEGIN
6 l_empno := &emno;
7 -- assign a value to :var_index
8 OPEN l_ref_cur FOR l_query using l_empno;
9 END;
10 /
Enter value for emno: 7698
old 6: l_empno := &emno;
new 6: l_empno := 7698;
PL/SQL procedure successfully completed.
Elapsed: 00:00:19.78
scott@ORCL>Regards.
Satyaki De. -
Can bind variable be used for the table in an explicit cursor
I have an application that accesses a table on several different servers. I created a ref cursor variable for the cursor and a varchar2 variable to define my query. variable i_server is an parameter of my procedure. Is it possible to rewrite the v_query using bind variables for the table/server? I have include v_query below.
v_query := 'SELECT rp.usr_id, rp.sun_sft_cat, rp.sun_start, rp.sun_hrs,' ||
' rp.mon_sft_cat, rp.mon_start, rp.mon_hrs,' ||
' rp.tue_sft_cat, rp.tue_start, rp.tue_hrs,' ||
' rp.wed_sft_cat, rp.wed_start, rp.wed_hrs,' ||
' rp.thu_sft_cat, rp.thu_start, rp.thu_hrs,' ||
' rp.fri_sft_cat, rp.fri_start, rp.fri_hrs,' ||
' rp.sat_sft_cat, rp.sat_start, rp.sat_hrs,' ||
' rp.sun_sft, rp.mon_sft, rp.tue_sft, rp.wed_sft,' ||
' rp.thu_sft, rp.fri_sft, rp.sat_sft, nvl(ei.wip_permanent_sched_seq, 0)' ||
' FROM ' || i_server || ' rp, wip_emp_information ei,' ||
' wip_emp_status wes, wip_emp_status_type west ' ||
' WHERE rp.usr_id = ei.employee_id' ||
' AND wes.employee_id = ei.employee_id' ||
' AND wes.status_type = west.status_type' ||
' AND west.description = ''WAREHOUSE EMPLOYEE''' ||
' AND wes.effective_date = (SELECT MAX(wes2.effective_date)' ||
' FROM wip_emp_status wes2' ||
' WHERE wes2.status_type = wes.status_type' ||
' AND wes2.employee_id = wes.employee_id' ||
' AND wes2.effective_date <= trunc(SYSDATE))' ||
' AND wes.status = ''Y'' AND rp.wk = 1'; -- wk = 1 is next week's schedule
OPEN rp_sched_cursor FOR v_query;If your intention is to do this:
v_query := 'SELECT rp.usr_id, rp.sun_sft_cat, rp.sun_start, rp.sun_hrs,' ||
' rp.mon_sft_cat, rp.mon_start, rp.mon_hrs,' ||
' rp.tue_sft_cat, rp.tue_start, rp.tue_hrs,' ||
' rp.wed_sft_cat, rp.wed_start, rp.wed_hrs,' ||
' rp.thu_sft_cat, rp.thu_start, rp.thu_hrs,' ||
' rp.fri_sft_cat, rp.fri_start, rp.fri_hrs,' ||
' rp.sat_sft_cat, rp.sat_start, rp.sat_hrs,' ||
' rp.sun_sft, rp.mon_sft, rp.tue_sft, rp.wed_sft,' ||
' rp.thu_sft, rp.fri_sft, rp.sat_sft, nvl(ei.wip_permanent_sched_seq, 0)' ||
' FROM ' || :b0 || ' rp, wip_emp_information ei,' || --- Note the bindvariable...
' wip_emp_status wes, wip_emp_status_type west ' ||
' WHERE rp.usr_id = ei.employee_id' ||
' AND wes.employee_id = ei.employee_id' ||
' AND wes.status_type = west.status_type' ||
' AND west.description = ''WAREHOUSE EMPLOYEE''' ||
' AND wes.effective_date = (SELECT MAX(wes2.effective_date)' ||
' FROM wip_emp_status wes2' ||
' WHERE wes2.status_type = wes.status_type' ||
' AND wes2.employee_id = wes.employee_id' ||
' AND wes2.effective_date <= trunc(SYSDATE))' ||
' AND wes.status = ''Y'' AND rp.wk = 1'; -- wk = 1 is next week's schedule
OPEN rp_sched_cursor FOR v_query USING i_server;Then the answer is: no, you cannot do that.
But my question then would be: why would you want to do that?
I assume you don't have that many "different servers". One cursor per server won't hurt you. -
Cursor for loop vs bind variable efficiency
PL/SQL
I am going to need to execute many sqls within a cursor for loop.
Note: This is pseudo pl/sql code
for csr_rec in cursor
loop
insert into tablea
select [whateever] from tableb
where column_name = csr_rec.field
versus
execute immediate
'insert into table a select ... where column_name = :1' using csr_rec.field
So the question is whether the first insert statement will be treated as a separate sql statement and need to be parsed each iteration? If so, then I'd likely be much better of using the bind variable approach. (2nd) insert statement.
Thanks!The first statement (static) will be re-used - PL/SQL variables (csr_rec.field in this case) will be used as a bind variable.
-
hii,
what is the advantage of cursor sharing parameter?
Is there ayy performance differences between using cursor sharing parameter only ( coding sql queries with literals) and using bind variables only ( no setting of cursor sharing parameter)user4030266 wrote:
I am trying to optimize reports.
I think I have three option.
First is using literals and trust to the cursor sharing parameter.
Second one is using plsql functions which returns cursors.
Third one is using plsql functions which returns tables by using pipleined functions like http://mennan.kagitkalem.com/PerformanceAnalyzesOfPIPELINEDFunctionsInOracle.aspx.
How would any of these optimise reports?
Using literals and not bind variables is only a performance issue when the application fires off 100s of SQLs per second - and each need to be hard parsed. It is not a performance issue when the client is a reporting tool and happens not to use bind variables. Sure, it is desirable (most of the time) to have a client use bind variables. But what optimisation do you expect from a report query? It will definitely not be any faster - as the very same SQL will be executed.
A PL/SQL function returning a ref cursor.. again, what optimisation do you expect? Does not matter how you pass a SQL to the Oracle SQL engine, ALL SQLs are parsed and stored as cursors. Every one. Now instead of the client (reporting tool) getting a cursor handle directly from its call to the SQL engine, you want it to call PL/SQL, and then give it a ref cursor handle.
The only difference is basically who hands out the cursor handle. The SQL engine directly. Or your PL/SQL code indirectly? The SQL still remains the same. It will be as slow or as fast as before. Only now you're making things a tad more complex by introducing another layer (your PL/SQL code) in-between the client and the SQL engine.
Yes, it can serve a good purpose at times by abstracting the actual SQL layer from the client. But do not expect any performance improvements. This does not make the SQL go any faster.
Lastly, pipe line table functions. This is a great idea to make the SQL go slower. How does a PL/SQL pipeline works? It is called via the SQL engine. It is PL/SQL code. This code in turns calls the SQL engine again. It copies data from the SQL engine into PL/SQL. Then it copies (or pipes) that same data back to the SQL engine.
How can this be faster than the client simply getting the data directly from the SQL engine? Pipeline table functions is a tool to address a specific type of problem dealing with ETL (extraction, transformation and loading). With emphasis on the transformation part - as there is where you want to use PL/SQL to transform the SQL data into something different before passing (piping) it back to the SQL engine.
It is not a performance tool that make SQL go faster. In fact, it is slower than simply staying within the SQL engine and not move SQL data to and from the SQL engine to PL/SQL engine and back.
You want to improve or optimise actual reporting? Then what you need to look at is the stuff that is actually relevant. Not cursors. Not pipeline tables.
And the stuff that is relevant are:
- the design of the data model
- the physical implementation of the data model
- the design and logic of the SQL report
And that's it. Get that right, and you have addressed a significant portion of the performance problem of SQL reporting.
And be very wary when so-called "+experts+" mention using ref cursors and pipeline tables and the like to optimise performance... as these are not the tools one use to address performance tools. (these are tools dealing with usability and not speed) -
NESTED TABLE BIND VARIABLE IN A REF CURSOR
Hi,
this works:
open c_ref for v_sql using cp_asset_type
where cp_asset_type is a nested tables passed into the proc as an 'in' parameter, but since the number of passed tables varies I loaded the nemes into an a nested table and tried the following:
-- ELSIF BIND_COUNT.COUNT = 8 THEN
-- OPEN C_REF FOR V_SQL
-- USING BIND_COUNT(1),BIND_COUNT(2),BIND_COUNT(3),BIND_COUNT(4),BIND_COUNT(5),BIND_COUNT(6),BIND_COUNT(7),BIND_COUNT(8);
-- END IF;
which produced :
ORA-22905 CANNOT ACCESS ROWS FROM A NON-NESTED TABLE ITEM
my guess is that I'm passing the varchar2 names of the nested tables and the 'using' statement needs the actual table ????
if this is true is there any way to pass a pointer for the bind variable nested tables?
Thanks,
Victor<br>i removed the AND...but m still getting the same error.
<br>Is this a versioning problem...since urs is 9i and m using
<br>Oracle8i Enterprise Edition Release 8.1.7.4.0
<br> PROCEDURE sp_SearchByDriverName(i_C in varchar2,
i_F in varchar2,
i_LN in varchar2,
i_FN in varchar2,
o_Result out ABC_CURTYPE) is
<br> tm_corp varchar2(2);
<br> tm_fleet varchar2(6);
<br> dc ABC_curtype;
<br> begin
<br> tm_c := getformattedc(i_C);
<br> tm_f := getformattedf(i_f);
<br> if i_FN is not null then
<br> open dc for
<br> SELECT distinct b.bus_ref_access_value,
<br> i.individual_id,
<br> br.mf_driver_last_name LN,
<br> br.mf_driver_first_name FN,
<br> substr(b.bus_ref_access_value, 4, 6) FLEET1,
<br> (select '4444' from dual) --error is still coming here
<br> FROM bus_ref_access_values b,
<br> bus_ref_list brl,
<br> individual i,
<br> unit_contact_list f,
<br> unit u,
<br> bus_ref_current_prop br
<br> WHERE b.bus_ref_id = br.bus_ref_id AND
<br> b.bus_ref_id = brl.bus_ref_id AND
<br> brl.reference_id = u.reference_id AND
<br> u.unit_id = f.unit_id(+) AND
<br> i.individual_id = f.individual_id AND
<br> f.contact_type_ref = 'DR' AND
<br> br.mf_driver_last_name like i_LN || '%' AND
<br> br.mf_driver_first_name like i_FN || '%' AND
<br> substr(b.bus_ref_access_value, 1, 2) = tm_c AND
<br> substr(b.bus_ref_access_value, 4, 6) = tm_f AND
<br> b.bus_ref_access_label = 'UNIT NUMBER'
<br> ORDER BY 4, 3, 2;
<br> close dc;
<br>end if;
Maybe you are looking for
-
Looking for a good download manager !
Im looking for a good download manager which completely integrates into browsers like safari,firefox and opera specialy be able to catch rapidshare files when you try to download as premium user, preferably free i really miss IDM in windows and thats
-
Why is my mac not opening pages
-
Hi, I am using OSX 10.8.3, Adobe Bridge CS5 and Photoshop CS5. I ran repair permissions from disk utility, and now the results are inconsistent. in that if I use bridge to drag & drop a file from the desktop to a folder on the desktop it work ok. but
-
HI all, I have one problem.. that is .. String str = ",check,the,values"; ( String length may change) String may be like this also str = "check,the,values"; str = "check,the,values,"; I want the string like: ".check.the.values" means just replacing t
-
I tried to download iTunes for my new iPod (since they no longer come with the disc) but when I try to run the application I get a notification that pops up and it says "/iTunesSetup.exe is not a valid Win32 application." If anyone can help me I'd ap