Passing where cluase as parameter for cursor
I want to pass where clause of cursor as parameter.... how can I do that?
say I want cursor as,
cursor c1 is select fname, mname from person where :param;
where :param is a value I want to pass in declare section
I want to pass where clause of cursor as parameter.... how can I do that?Yes.
cursor c1 is select fname, mname from person where :param;
where :param is a value I want to pass in declare sectionYou can also shoot yourself in the foot using a 357 Magnum.
Neither is recommended - unless you are a professional idiot. Which I doubt as these are typically your Darwin Award Winners.
Why is it bad to to have "+WHERE :param+"?
Bind variables. If the WHERE clause is passed as a dynamic string. this will usually be implemented in the following fashion:
SQL> create or replace procedure smellyFoo( filterClause varchar2, refCur in out sys_refcursor ) is
2 begin
3 open refCur for
4 'select owner, object_id, object_name from all_objects where owner != ''SYS'' and '||filterClause||' order by 1,2';
5 end;
6 /
Procedure created.
SQL>
SQL> var c refcursor
SQL> exec smellyFoo( 'object_type=''TABLE'' and rownum <11', :c );
PL/SQL procedure successfully completed.
SQL>
SQL> print c
OWNER OBJECT_ID OBJECT_NAME
OUTLN 452 OL$
OUTLN 453 OL$HINTS
OUTLN 456 OL$NODES
SYSTEM 3621 MVIEW$_ADV_WORKLOAD
SYSTEM 3624 MVIEW$_ADV_BASETABLE
SYSTEM 3626 MVIEW$_ADV_SQLDEPEND
SYSTEM 3628 MVIEW$_ADV_PRETTY
SYSTEM 3630 MVIEW$_ADV_TEMP
SYSTEM 3632 MVIEW$_ADV_FILTER
SYSTEM 3634 MVIEW$_ADV_LOG
10 rows selected.
SQL>What's wrong with this? The filter clause contains literals. Not bind variables. Which means that non-sharable SQL will be created. This means more cursors (for same SQLs with different literal values) in the shared pool. Different sizes SQLs that leads to fragmentation of the shared pool memory. More hard parsing. Bigger delay in parsing as there are more cursors to scan in the shared pool (useless exercise) as there are no existing cursors that are sharable and can be re-used.
So what would the correct way be? The client passing a filter clause as a proper bind variable string, and also passing (separately) the values for those bind variables. But this is not easy to code, especially when dealing with filter clauses that may contain no bind variables. or a 100 bind variables.
Also, the call interface the client needs to use will become a lot more complex as the client now not only needs to build a proper string containing bind variables, it also need to make sure it pass the values for those variables in the correct order.
So why? Why do any of this? What is the requirement that lead you to this "solution" where the client can dynamically decide on what the filter criteria is?
Surely, there must be a reason to this madness of the client wanting to throw any filter clause at a SQL cursor... and surely, that is what needs to be identified and analysed and resolved - instead of wanting to create hacks like the above. Causing performance issues. Not to mention opening a security hole that is ideal for SQL injection.
Similar Messages
-
How to pass where condition to report for condition
hello people ,
i want to pass where condition for the report statement .
for example ,
select ename from emp
i want to pass parameter carry <where deptno=40>
thanksGood Morning oracleuser,
If we understood correctly, Bind references (or bind variables) should use this issue.
a>select ename from emp where deptno= :Dept_Number
If you have any more questions, please post it.
Otherwise:
Mark Helpful or Answer accordingly. -
Passing null as input parameter for relational physical DS
I'm creating a adapter(physical and logical) to talk to a Sybase Stored procedure. A few input integer arguments to the stored procedure are always null
From Stored procedures - default NULL , I use xs:int(()) to pass in nulls. But for the 2nd argument($id),which has args with valid input following it, the stored procedure does not return any results. Executing the same stored proc with same inputs via Java JDBC or Sybase central gives the right results.
But if i give a value for the 2nd argument ($id), the stored proc returns valid multi-row results indicating that the plumbing(my rowset schema..) works.
In the below code, I have included the 2nd argument(id_inp) as an input to Logical just to be able to test using "setNull" check box. I also tried just passing "xs:int(())" without getting it as input into the logical.
Physical:
declare function f1:test_get($cid as xs:string, *$id as xs:int?*, $dt as xs:string, $tm as xs:string, $in1 as xs:int?, $in2 as xs:int?, $in3 as xs:int?, $in4 as xs:int?) as schema-element(t1:test_get) external;
Logical:
declare function tns:test_get($cid_inp as xs:string, $dt_inp as xs:string, $tm_inp as xs:string, *$id as xs:int?*) as element(ns1:OutputSchema)*{
for $test_ret_get in f1:test_get($cid_inp, *$id*, $dt_inp, $tm_inp, xs:int(()), xs:int(()), xs:int(()), xs:int(()))
return
The sybase stored proc is declared as below: [ id, in1.in2,in3,in4 do not need to be passed in]
create proc test_get
@cid varchar(32)=null,
@id int=null,
@dt varchar(8)=null,
@tm varchar(8)=null,
@in1 int=null,
@in2 int=null,
@in3 int=null,
@in4 int=0
as
Can i pass in null to an input argument followed by valid inputs to arguments following it?
Is there any other way to send null?
Thank you.mikereiche wrote:
First - it is impossible to optimize stored procedures, as sorting, joining and filtering cannot be "pushed" inside the stored procedure. For this reason, I encourage you to avoid using stored procedures in your solution.Unfortunately, this is an external Sybase DB stored proc that we need to call to get data.
>
The issue is that SQL syntax for querying for a null value ( ... where COL_A is null ) is not consistent with querying for a non-null value (... where COL_A = ? ), and for ODSI to support querying for null values, it would need to delay generating the sql until the value of the arguments was known, and also there would be the possibility of having 2^number_of_args different sql statements. So it does not execute queries where any of the arguments are null. (look at the audit for your query, there won't be any executions of the sql).
The stored procedure seems to correctly handle the null input parameters since I get the correct results with Java JDBC.
See the thread, Re: Search Functionality , the post by Jeff Hoffman at "Mar 8, 2010 12:24 PM"
Jeff shows how to solve this problem when it occurs in a sql query (SELECT) - and this is useful for doing query-by-form - which, by the looks of it, is what you are after. To implement it for a stored query, you would need an extra "IsNull" arg for each arg that could be null,
myProcedure( @lastName varchar(8), @lastNameIsNull int, @firstName varchar(8) @firstNameIsNull int)
select from CUSTOMER where (LASTNAME = @lastName or @lastNameIsNull=1) and (FIRSTNAME = @firstName or @firstNameisNull=1)
And you would call that from ODSI as below (using Jeff's ensureNotNull function).
myProcedure( tns:ensureNotNull($lastName), fn:empty($lastName) , tns:ensureNotNull($firsttName), fn:empty($firstName) )
You may note that when lastName is null, a bogus value of "" (empty-string) will be passed for the value of @lastName. This does not matter since LASTNAME = @lastName will have no effect in the query since @lastNameIsNull=1 is true.I'm probably missing something but it is different in my case that i want to pass in null and the stored proc already has the necessary check for null. It looks up a different table when this arg is null and gets the values needed for execution.
I turned on the Audit for query parameters and it goes out as null for the 2nd argument. Its probably what i'm not getting from your explanation but I don't understand why it would behave differently compared to Java JDBC when it looks like the input parameters are the same. This also uses the JDBC DataSource created in Weblogic console.
Audit log:
rows: 0
parameters:
10000
null
12/06/11
15:48:00
null
null
null
0 -
I have a table with a field "f1" which type is nvarchar(1000). Now I want to update a record through binding variable method. Before I bind the parameter, I call SQLDescribeCol to get the length of f1 - 1000.
The data for updating f1 is prepared and is coverted to UTF16, so the buffer length is 2*(character length). When I call SQLBindParameter() to bind the variable for f1, what length value should be passed to ColumnSize parameter? Some said the Columnsize
should be in byte. In MSDN, I can't find any posts or examples for my cases. MSDN also mentioned that the limit for this argument is 4000.
I try 1000 and 2000, both works. Which one is the exactly correct one? I use SQL Server 2008 and native client 10.0.
Thanks in advance.
Liu PengHello,
Thank you for your question. I am trying to involve someone more familiar with this topic for a further look at this issue. Sometime delay might be expected from the job transferring. Your patience is greatly appreciated.
Thank you for your understanding and support.
Elvis Long
TechNet Community Support -
About passing multiple values in parameter for oracle report
https://docs.google.com/file/d/0B0dx7wf68mD0QzdpbWU4UGNURTQ/edit
Hi all,
i want to pass multiple value using , to separate them 1,2,3....
here is my query
SELECT DISTINCT
oh.header_id
,oh.org_id
,to_char(oh.ordered_date,'DD-MON-YYYY') d_date
,to_char(oh.ordered_date+31,'DD-MON-YYYY') d_validity
,oh.ship_to_org_id
,oh.invoice_to_org_id
,oh.cust_po_number d_po_num
,rcust.customer_id AS customer_id
,oh.order_number d_salesorder_no
,oh.cust_po_number d_project
,oh.attribute1 second_addr
,oh.attribute2 remark1
,oh.attribute3 remark2
,substr(oh.transactional_curr_code,1,3) as currency
,tyl.name ordertype
,oh.salesrep_id
,rat.name as d_payment_term
,rat.description d_payment_desc
,rsa.name
,rsa.email_address as sales_phone
,rcust.customer_name||' - #'||rcust.customer_number d_to_custname
,rcust.customer_name d_cust_sign
,rcust.attribute1
,rcust.customer_number
-- ,raddr.ship_to_flag
,oh.sold_to_contact_id AS attn_id
,rcust.party_id
,tyl.name AS SO_type
-- ,net_org.ORG_LOGO
FROM
oe_order_headers_all oh
,ra_customers rcust
,ra_addresses_all raddr
,ra_site_uses_all rsite --double_line
,ra_terms rat
,hz_party_sites hps
,hz_contact_points hcp
,ra_salesreps_all rsa
,oe_transaction_types_tl tyl
-- ,apps.ar_contacts_v acv
-- ,net_org
WHERE oh.sold_to_org_id = rcust.customer_id
AND oh.payment_term_id = rat.term_id(+)
--AND rcust.customer_id = acv.customer_id(+)
AND oh.salesrep_id = rsa.salesrep_id
AND oh.order_type_id = tyl.transaction_type_id
AND rcust.party_id = raddr.party_id
AND raddr.address_id = rsite.address_id
AND rcust.party_id = hps.party_id
AND hps.party_site_id = hcp.owner_table_id(+)
AND hcp.owner_table_name(+) = 'HZ_PARTY'
--AND hcp.contact_point_type (+)='PHONE'
AND tyl.LANGUAGE = userenv('LANG')
--AND raddr.ship_to_flag IS NULL
AND upper(tyl.name) in ('SW SALES CONTRACT','SW-NSC SALES CONTRACT','TILES SALES CONTRACT','VBP SAMPLE ORDER', 'VBP INTERNAL ORDER')
AND oh.order_number =:P_CONTRACT_NO
and oh.org_id = :P_ORG_ID
--and net_org.org_id = :P_ORG_ID
&CP_Param
and after para form
function AfterPForm return boolean is
begin
:CP_Param := 'where oh.order_number in ('||:P_CONTRACT_NO||')';
return (TRUE);
end;
it said ora-00933 but my query can run i dont need the multiple values para, can anyone help me how to modify the report so it can pass multipel values thanksHI I tried changing the parameter width to a larger value, it can output , and the field where I show the order_number i used source P_CONTRACT_NO,
it will display as 102005000,102005001 and I also tried using the column from the query directly, it will be separated , it has some other problem
I have the header part and main part,
and also there are page numbering, with the order number field set as order_number it will output single number , but the page order is wrong
102005000,102005001 will be like header page: 102005000 1/4 102005001 2/4, main page 102005000 3/4, 102005001 3/4
DO you have any idea how I can set the page numbering setting so it will output as header page:102005000 1/2 102005000 2/2
header page:102005001 1/2 102005001 2/2
?? thanks -
Pass ViewObject like parameter for JasperReport.
Hello everybody,
I'm using JasperReport for to generate reports in my application, then i would like to know like to pass a ViewObjet like parameter for JasperReport.
JDeveloper Studio 11.1.1.4.0
ADF Swing.You need to scan each picked Excel file to obtain its sheet name.
This technique is described in this blog post: http://www.codeproject.com/Articles/368530/Dynamic-Excel-file-loading-with-SSIS
Arthur My Blog -
Use of FOR Cursor and BULK COLLECT INTO
Dear all,
in which case we prefer to use FOR cursor and cursor with BULK COLLECT INTO? The following contains two block that query identically where one is using FOR cursor, the other is using BULK COLLECT INTO . Which one that performs better given in the existing task? How do we measure performance between these two?
I'm using sample HR schema:
declare
l_start number;
BEGIN
l_start:= DBMS_UTILITY.get_time;
dbms_lock.sleep(1);
FOR employee IN (SELECT e.last_name, j.job_title FROM employees e,jobs j
where e.job_id=j.job_id and e.job_id LIKE '%CLERK%' AND e.manager_id > 120 ORDER BY e.last_name)
LOOP
DBMS_OUTPUT.PUT_LINE ('Name = ' || employee.last_name || ', Job = ' || employee.job_title);
END LOOP;
DBMS_OUTPUT.put_line('total time: ' || to_char(DBMS_UTILITY.get_time - l_start) || ' hsecs');
END;
declare
l_start number;
type rec_type is table of varchar2(20);
name_rec rec_type;
job_rec rec_type;
begin
l_start:= DBMS_UTILITY.get_time;
dbms_lock.sleep(1);
SELECT e.last_name, j.job_title bulk collect into name_rec,job_rec FROM employees e,jobs j
where e.job_id=j.job_id and e.job_id LIKE '%CLERK%' AND e.manager_id > 120 ORDER BY e.last_name;
for j in name_rec.first..name_rec.last loop
DBMS_OUTPUT.PUT_LINE ('Name = ' || name_rec(j) || ', Job = ' || job_rec(j));
END LOOP;
DBMS_OUTPUT.put_line('total time: ' || to_char(DBMS_UTILITY.get_time - l_start) || ' hsecs');
end;
/In this code, I put timestamp in each block, but they are useless since they both run virtually instantaneous...
Best regards,
ValIf you want to get 100% benifit of bulk collect then it must be implemented as below
declare
Cursor cur_emp
is
SELECT e.last_name, j.job_title
FROM employees e,jobs j
where e.job_id=j.job_id
and e.job_id LIKE '%CLERK%'
AND e.manager_id > 120
ORDER BY e.last_name;
l_start number;
type rec_type is table of varchar2(20);
name_rec rec_type;
job_rec rec_type;
begin
l_start:= DBMS_UTILITY.get_time;
dbms_lock.sleep(1);
/*SELECT e.last_name, j.job_title bulk collect into name_rec,job_rec FROM employees e,jobs j
where e.job_id=j.job_id and e.job_id LIKE '%CLERK%' AND e.manager_id > 120 ORDER BY e.last_name;
OPEN cur_emp;
LOOP
FETCH cur_emp BULK COLLECT INTO name_rec LIMIT 100;
EXIT WHEN name_rec.COUNT=0;
FOR j in 1..name_rec.COUNT
LOOP
DBMS_OUTPUT.PUT_LINE ('Name = ' || name_rec(j) || ', Job = ' || job_rec(j));
END LOOP;
EXIT WHEN cur_emp%NOTFOUND;
END LOOP;
CLOSE cur_emp;
DBMS_OUTPUT.put_line('total time: ' || to_char(DBMS_UTILITY.get_time - l_start) || ' hsecs');
end;
/ -
Date Format on OWB 11.1.0.7 to use for input parameter for a mapping
All,
What is the Date Format on OWB 11.1.0.7 to use for passing in an input parameter for a mapping to execute?
I have tried '01-01-2010','01-JAN-2010','01.01.2010', 01/01/2010 and I get the following error:
Error RPE-01003: An infrastructure condition prevented the request from completing.
Error RPE-01038: Failed to evaluate expression declare l_expression DATE := 01/01/2010;begin :result := wb_rt_conversions.from_date(l_expression);end;. Please modify the expression, redeploy and retry again.
RA-06550: line 1, column 32:
PLS-00382: expression is of wrong type
ORA-06550: line 1, column 24:
PL/SQL: Item ignored
ORA-06550: line 1, column 90:
PLS-00320: the declaration of the type of this expression is incomplete or malformed
ORA-06550: line 1, column 51:
PL/SQL: Statement ignored
I am using a Mapping Input parameter object and have a START_DATE_IN as a DATE and an END_DATE_IN as a DATE
Any information you could provide would be greatly appreciated.
Thanks,
ShaunHello Shaun,
The function wb_rt_conversions.from_date is (at least in OWB10.2) overloaded and can with input-types as
date, timestamp_unconstrained, timestamp_tz_unconstrained, timestamp_ltz_unconstrained or varchar2.
If it doesn't work with varchar2 I would try Date:
For example: to_date('2010-01-01','YYYY-MM-DD')
I also found this thread:
http://kr.forums.oracle.com/forums/thread.jspa?threadID=608257
Hoping this helps...
Guenther -
Parameter for user locked when no connection
Where is the parameter for the number of days before automaticaly lock of the users ?
In our system, the users are locked automatically by SAP after 1 month of inactivity !!
Where is the parameter who control yhis ?Jean,
Where is the parameter who control yhis ?
In RZ10, login/password_max_idle_productive users who are idle for 30days will be automatically locked.
2. Use TU02 -you will get to know parameters active in the SAP system.
http://sap.ittoolbox.com/groups/technical-functional/sap-security/rsparam-settings-password-1185954
Thanks,
Sri
Edited by: sri on Jul 27, 2010 8:41 PM -
How to pass parameter into cursor for loop ?
Hi Experts,
I want to pass parameter l_bom_header_tbl(i).assembly_item_name into the for statement below How to achieve this?
for j in 1 .. l_bom_components_tbl.COUNT LOOP
ThanksMaybe i failed to describe in detail,so here i go:
I have two for loops:
for i in 1 .. l_bom_header_tbl.COUNT LOOP --1st For Loop
V_bom_header_tbl.organization_code :='DSC';
V_bom_header_tbl.assembly_item_name:= l_bom_header_tbl(i).assembly_item_name ;
k:=1;
I want to pass parameter l_bom_header_tbl(i).assembly_item_name into the for statement below: How to achieve this?
for j in 1 .. l_bom_components_tbl.COUNT LOOP *2nd For Loop*
v_bom_components_tbl(k).Assembly_Item_name := l_bom_header_tbl(i).assembly_item_name ;
k := k + 1;
end LOOP;
end loop;
end;
I want to pass a paramter into second for loop in such a way that it accepts from the first for loop
for j in 1 .. l_bom_components_tbl.COUNT LOOP -2nd loop
Edited by: ILovePlSql on Mar 22, 2010 12:25 PM -
Can I use Bulk Collect results as input parameter for another cursor
MUSIC ==> remote MUSIC_DB database, MUSIC table has 60 million rows
PRICE_DATA ==> remote PRICING_DB database, PRICE_DATE table has 1 billion rows
These two table once existed in same database, but size of database exceeded available hardware size and hardware budget, so the PRICE_DATA table was moved to another Oracle database. I need to create a single report that combines data from both of these tables, and a distributed join with DRIVING_SITE hint will not work because the size of both table is too large to push to one DRIVING_SITE location, so I wrote this PLSQL block to process in small blocks.
QUESTION: how can use bulk collect from one cursor and pass that bulk collected information as input to second cursor without specifically listing each cell of the PLSQL bulk collection? See sample pseudo-code below, I am trying to determine more efficient way to code than hard-coding 100 parameter names into 2nd cursor.
NOTE: below is truly pseudo-code, I had to change the names of everything to adhere to NDA, but below works and is fast enough for my purposes, but if I want to change from 100 input parameters to 200, I have to add more hard-coded values. There has got to be a better way.
DECLARE
-- define cursor that retrieves distinct SONG_IDs from MUSIC table in remote music database
CURSOR C_CURRENT_MUSIC
IS
select distinct SONG_ID
from MUSIC@MUSIC_DB
where PRODUCTION_RELEASE=1
/* define a parameterized cursor that accepts 100 SONG_IDs and retrieves
required pricing information
CURSOR C_get_music_price_data
P_SONG_ID_001 NUMBER, P_SONG_ID_002 NUMBER, P_SONG_ID_003 NUMBER, P_SONG_ID_004 NUMBER, P_SONG_ID_005 NUMBER, P_SONG_ID_006 NUMBER, P_SONG_ID_007 NUMBER, P_SONG_ID_008 NUMBER, P_SONG_ID_009 NUMBER, P_SONG_ID_010 NUMBER,
P_SONG_ID_011 NUMBER, P_SONG_ID_012 NUMBER, P_SONG_ID_013 NUMBER, P_SONG_ID_014 NUMBER, P_SONG_ID_015 NUMBER, P_SONG_ID_016 NUMBER, P_SONG_ID_017 NUMBER, P_SONG_ID_018 NUMBER, P_SONG_ID_019 NUMBER, P_SONG_ID_020 NUMBER,
P_SONG_ID_021 NUMBER, P_SONG_ID_022 NUMBER, P_SONG_ID_023 NUMBER, P_SONG_ID_024 NUMBER, P_SONG_ID_025 NUMBER, P_SONG_ID_026 NUMBER, P_SONG_ID_027 NUMBER, P_SONG_ID_028 NUMBER, P_SONG_ID_029 NUMBER, P_SONG_ID_030 NUMBER,
P_SONG_ID_031 NUMBER, P_SONG_ID_032 NUMBER, P_SONG_ID_033 NUMBER, P_SONG_ID_034 NUMBER, P_SONG_ID_035 NUMBER, P_SONG_ID_036 NUMBER, P_SONG_ID_037 NUMBER, P_SONG_ID_038 NUMBER, P_SONG_ID_039 NUMBER, P_SONG_ID_040 NUMBER,
P_SONG_ID_041 NUMBER, P_SONG_ID_042 NUMBER, P_SONG_ID_043 NUMBER, P_SONG_ID_044 NUMBER, P_SONG_ID_045 NUMBER, P_SONG_ID_046 NUMBER, P_SONG_ID_047 NUMBER, P_SONG_ID_048 NUMBER, P_SONG_ID_049 NUMBER, P_SONG_ID_050 NUMBER,
P_SONG_ID_051 NUMBER, P_SONG_ID_052 NUMBER, P_SONG_ID_053 NUMBER, P_SONG_ID_054 NUMBER, P_SONG_ID_055 NUMBER, P_SONG_ID_056 NUMBER, P_SONG_ID_057 NUMBER, P_SONG_ID_058 NUMBER, P_SONG_ID_059 NUMBER, P_SONG_ID_060 NUMBER,
P_SONG_ID_061 NUMBER, P_SONG_ID_062 NUMBER, P_SONG_ID_063 NUMBER, P_SONG_ID_064 NUMBER, P_SONG_ID_065 NUMBER, P_SONG_ID_066 NUMBER, P_SONG_ID_067 NUMBER, P_SONG_ID_068 NUMBER, P_SONG_ID_069 NUMBER, P_SONG_ID_070 NUMBER,
P_SONG_ID_071 NUMBER, P_SONG_ID_072 NUMBER, P_SONG_ID_073 NUMBER, P_SONG_ID_074 NUMBER, P_SONG_ID_075 NUMBER, P_SONG_ID_076 NUMBER, P_SONG_ID_077 NUMBER, P_SONG_ID_078 NUMBER, P_SONG_ID_079 NUMBER, P_SONG_ID_080 NUMBER,
P_SONG_ID_081 NUMBER, P_SONG_ID_082 NUMBER, P_SONG_ID_083 NUMBER, P_SONG_ID_084 NUMBER, P_SONG_ID_085 NUMBER, P_SONG_ID_086 NUMBER, P_SONG_ID_087 NUMBER, P_SONG_ID_088 NUMBER, P_SONG_ID_089 NUMBER, P_SONG_ID_090 NUMBER,
P_SONG_ID_091 NUMBER, P_SONG_ID_092 NUMBER, P_SONG_ID_093 NUMBER, P_SONG_ID_094 NUMBER, P_SONG_ID_095 NUMBER, P_SONG_ID_096 NUMBER, P_SONG_ID_097 NUMBER, P_SONG_ID_098 NUMBER, P_SONG_ID_099 NUMBER, P_SONG_ID_100 NUMBER
IS
select
from PRICE_DATA@PRICING_DB
where COUNTRY = 'USA'
and START_DATE <= sysdate
and END_DATE > sysdate
and vpc.SONG_ID IN
P_SONG_ID_001 ,P_SONG_ID_002 ,P_SONG_ID_003 ,P_SONG_ID_004 ,P_SONG_ID_005 ,P_SONG_ID_006 ,P_SONG_ID_007 ,P_SONG_ID_008 ,P_SONG_ID_009 ,P_SONG_ID_010,
P_SONG_ID_011 ,P_SONG_ID_012 ,P_SONG_ID_013 ,P_SONG_ID_014 ,P_SONG_ID_015 ,P_SONG_ID_016 ,P_SONG_ID_017 ,P_SONG_ID_018 ,P_SONG_ID_019 ,P_SONG_ID_020,
P_SONG_ID_021 ,P_SONG_ID_022 ,P_SONG_ID_023 ,P_SONG_ID_024 ,P_SONG_ID_025 ,P_SONG_ID_026 ,P_SONG_ID_027 ,P_SONG_ID_028 ,P_SONG_ID_029 ,P_SONG_ID_030,
P_SONG_ID_031 ,P_SONG_ID_032 ,P_SONG_ID_033 ,P_SONG_ID_034 ,P_SONG_ID_035 ,P_SONG_ID_036 ,P_SONG_ID_037 ,P_SONG_ID_038 ,P_SONG_ID_039 ,P_SONG_ID_040,
P_SONG_ID_041 ,P_SONG_ID_042 ,P_SONG_ID_043 ,P_SONG_ID_044 ,P_SONG_ID_045 ,P_SONG_ID_046 ,P_SONG_ID_047 ,P_SONG_ID_048 ,P_SONG_ID_049 ,P_SONG_ID_050,
P_SONG_ID_051 ,P_SONG_ID_052 ,P_SONG_ID_053 ,P_SONG_ID_054 ,P_SONG_ID_055 ,P_SONG_ID_056 ,P_SONG_ID_057 ,P_SONG_ID_058 ,P_SONG_ID_059 ,P_SONG_ID_060,
P_SONG_ID_061 ,P_SONG_ID_062 ,P_SONG_ID_063 ,P_SONG_ID_064 ,P_SONG_ID_065 ,P_SONG_ID_066 ,P_SONG_ID_067 ,P_SONG_ID_068 ,P_SONG_ID_069 ,P_SONG_ID_070,
P_SONG_ID_071 ,P_SONG_ID_072 ,P_SONG_ID_073 ,P_SONG_ID_074 ,P_SONG_ID_075 ,P_SONG_ID_076 ,P_SONG_ID_077 ,P_SONG_ID_078 ,P_SONG_ID_079 ,P_SONG_ID_080,
P_SONG_ID_081 ,P_SONG_ID_082 ,P_SONG_ID_083 ,P_SONG_ID_084 ,P_SONG_ID_085 ,P_SONG_ID_086 ,P_SONG_ID_087 ,P_SONG_ID_088 ,P_SONG_ID_089 ,P_SONG_ID_090,
P_SONG_ID_091 ,P_SONG_ID_092 ,P_SONG_ID_093 ,P_SONG_ID_094 ,P_SONG_ID_095 ,P_SONG_ID_096 ,P_SONG_ID_097 ,P_SONG_ID_098 ,P_SONG_ID_099 ,P_SONG_ID_100
group by
vpc.SONG_ID
,vpc.STOREFRONT_ID
TYPE SONG_ID_TYPE IS TABLE OF MUSIC@MUSIC_DB%TYPE INDEX BY BINARY_INTEGER;
V_SONG_ID_ARRAY SONG_ID_TYPE ;
v_commit_counter NUMBER := 0;
BEGIN
/* open cursor you intent to bulk collect from */
OPEN C_CURRENT_MUSIC;
LOOP
/* in batches of 100, bulk collect ADAM_ID mapped TMS_IDENTIFIER into PLSQL table or records */
FETCH C_CURRENT_MUSIC BULK COLLECT INTO V_SONG_ID_ARRAY LIMIT 100;
EXIT WHEN V_SONG_ID_ARRAY.COUNT = 0;
/* to avoid NO DATA FOUND error when pass 100 parameters to OPEN cursor, if the arrary
is not fully populated to 100, pad the array with nulls to fill up to 100 cells. */
IF (V_SONG_ID_ARRAY.COUNT >=1 and V_SONG_ID_ARRAY.COUNT <> 100) THEN
FOR j IN V_SONG_ID_ARRAY.COUNT+1..100 LOOP
V_SONG_ID_ARRAY(j) := null;
END LOOP;
END IF;
/* pass a batch of 100 to cursor that get price information per SONG_ID and STOREFRONT_ID */
FOR j IN C_get_music_price_data
V_SONG_ID_ARRAY(1) ,V_SONG_ID_ARRAY(2) ,V_SONG_ID_ARRAY(3) ,V_SONG_ID_ARRAY(4) ,V_SONG_ID_ARRAY(5) ,V_SONG_ID_ARRAY(6) ,V_SONG_ID_ARRAY(7) ,V_SONG_ID_ARRAY(8) ,V_SONG_ID_ARRAY(9) ,V_SONG_ID_ARRAY(10) ,
V_SONG_ID_ARRAY(11) ,V_SONG_ID_ARRAY(12) ,V_SONG_ID_ARRAY(13) ,V_SONG_ID_ARRAY(14) ,V_SONG_ID_ARRAY(15) ,V_SONG_ID_ARRAY(16) ,V_SONG_ID_ARRAY(17) ,V_SONG_ID_ARRAY(18) ,V_SONG_ID_ARRAY(19) ,V_SONG_ID_ARRAY(20) ,
V_SONG_ID_ARRAY(21) ,V_SONG_ID_ARRAY(22) ,V_SONG_ID_ARRAY(23) ,V_SONG_ID_ARRAY(24) ,V_SONG_ID_ARRAY(25) ,V_SONG_ID_ARRAY(26) ,V_SONG_ID_ARRAY(27) ,V_SONG_ID_ARRAY(28) ,V_SONG_ID_ARRAY(29) ,V_SONG_ID_ARRAY(30) ,
V_SONG_ID_ARRAY(31) ,V_SONG_ID_ARRAY(32) ,V_SONG_ID_ARRAY(33) ,V_SONG_ID_ARRAY(34) ,V_SONG_ID_ARRAY(35) ,V_SONG_ID_ARRAY(36) ,V_SONG_ID_ARRAY(37) ,V_SONG_ID_ARRAY(38) ,V_SONG_ID_ARRAY(39) ,V_SONG_ID_ARRAY(40) ,
V_SONG_ID_ARRAY(41) ,V_SONG_ID_ARRAY(42) ,V_SONG_ID_ARRAY(43) ,V_SONG_ID_ARRAY(44) ,V_SONG_ID_ARRAY(45) ,V_SONG_ID_ARRAY(46) ,V_SONG_ID_ARRAY(47) ,V_SONG_ID_ARRAY(48) ,V_SONG_ID_ARRAY(49) ,V_SONG_ID_ARRAY(50) ,
V_SONG_ID_ARRAY(51) ,V_SONG_ID_ARRAY(52) ,V_SONG_ID_ARRAY(53) ,V_SONG_ID_ARRAY(54) ,V_SONG_ID_ARRAY(55) ,V_SONG_ID_ARRAY(56) ,V_SONG_ID_ARRAY(57) ,V_SONG_ID_ARRAY(58) ,V_SONG_ID_ARRAY(59) ,V_SONG_ID_ARRAY(60) ,
V_SONG_ID_ARRAY(61) ,V_SONG_ID_ARRAY(62) ,V_SONG_ID_ARRAY(63) ,V_SONG_ID_ARRAY(64) ,V_SONG_ID_ARRAY(65) ,V_SONG_ID_ARRAY(66) ,V_SONG_ID_ARRAY(67) ,V_SONG_ID_ARRAY(68) ,V_SONG_ID_ARRAY(69) ,V_SONG_ID_ARRAY(70) ,
V_SONG_ID_ARRAY(71) ,V_SONG_ID_ARRAY(72) ,V_SONG_ID_ARRAY(73) ,V_SONG_ID_ARRAY(74) ,V_SONG_ID_ARRAY(75) ,V_SONG_ID_ARRAY(76) ,V_SONG_ID_ARRAY(77) ,V_SONG_ID_ARRAY(78) ,V_SONG_ID_ARRAY(79) ,V_SONG_ID_ARRAY(80) ,
V_SONG_ID_ARRAY(81) ,V_SONG_ID_ARRAY(82) ,V_SONG_ID_ARRAY(83) ,V_SONG_ID_ARRAY(84) ,V_SONG_ID_ARRAY(85) ,V_SONG_ID_ARRAY(86) ,V_SONG_ID_ARRAY(87) ,V_SONG_ID_ARRAY(88) ,V_SONG_ID_ARRAY(89) ,V_SONG_ID_ARRAY(90) ,
V_SONG_ID_ARRAY(91) ,V_SONG_ID_ARRAY(92) ,V_SONG_ID_ARRAY(93) ,V_SONG_ID_ARRAY(94) ,V_SONG_ID_ARRAY(95) ,V_SONG_ID_ARRAY(96) ,V_SONG_ID_ARRAY(97) ,V_SONG_ID_ARRAY(98) ,V_SONG_ID_ARRAY(99) ,V_SONG_ID_ARRAY(100)
LOOP
/* do stuff with data from Song and Pricing Database coming from the two
separate cursors, then continue processing more rows...
END LOOP;
/* commit after each batch of 100 SONG_IDs is processed */
COMMIT;
EXIT WHEN C_CURRENT_MUSIC%NOTFOUND; -- exit when there are no more rows to fetch from cursor
END LOOP; -- bulk fetching loop
CLOSE C_CURRENT_MUSIC; -- close cursor that was used in bulk collection
/* commit rows */
COMMIT; -- commit any remaining uncommitted data.
END;I've got a problem when using passing VARRAY of numbers as parameter to remote cursor: it takes a super long time to run, sometimes doesn't finish even after an hour as passed.
Continuing with my example in original entry, I replaced the bulk collect into PLSQL table collection with a VARRAY and i bulk collect into the VARRAY, this is fast and I know it works because I can DBMS_OUTPUT.PUT_LINE cells of VARRAY so I know it is getting populated correctly. However, when I pass the VARRAY containing 100 cells populated with SONG_IDs as parameter to cursor, execution time is over an hour and when I am expecting a few seconds.
Below code example strips the problem down to it's raw details, I skip the bulk collect and just manually populate a VARRAY with 100 SONG_ID values, then try to pass to as parameter to a cursor, but the execution time of cursor is unexpectedly long, over 30 minutes, sometime longer, when I am expecting seconds.
IMPORTANT: If I take the same 100 SONG_IDs and place them directly in the cursor query's where IN clause, the SQL runs in under 5 seconds and returns result. Also, if I pass the 100 SONG_IDs as individual cells of a PLSQL table collection, then it also runs fast.
I thought that since the VARRAY is used via select subquery that is it queried locally, but the cursor is remote, and that I had a distribute problem on my hands, so I put in the DRIVING_SITE hint to attempt to force the result of query against VARRAY to go to remote server and rest of query will run there before returning result, but that didn't work either, still got slow response.
Is something wrong with my code, or I am running into a Oracle problem that may require support to resolve?
DECLARE
/* define a parameterized cursor that accepts XXX number of in SONG_IDs and
retrieves required pricing information
CURSOR C_get_music_price_data
p_array_song_ids SYS.ODCInumberList
IS
select /*+DRIVING_SITE(pd) */
count(distinct s.EVE_ID)
from PRICE_DATA@PRICING_DB pd
where pd.COUNTRY = 'USA'
and pd.START_DATE <= sysdate
and pd.END_DATE > sysdate
and pd.SONG_ID IN
select column_value from table(p_array_song_ids)
group by
pd.SONG_ID
,pd.STOREFRONT_ID
V_ARRAY_SONG_IDS SYS.ODCInumberList := SYS.ODCInumberList();
BEGIN
V_ARRAY_SONG_IDS.EXTEND(100);
V_ARRAY_SONG_IDS( 1 ) := 31135 ;
V_ARRAY_SONG_IDS( 2 ) := 31140 ;
V_ARRAY_SONG_IDS( 3 ) := 31142 ;
V_ARRAY_SONG_IDS( 4 ) := 31144 ;
V_ARRAY_SONG_IDS( 5 ) := 31146 ;
V_ARRAY_SONG_IDS( 6 ) := 31148 ;
V_ARRAY_SONG_IDS( 7 ) := 31150 ;
V_ARRAY_SONG_IDS( 8 ) := 31152 ;
V_ARRAY_SONG_IDS( 9 ) := 31154 ;
V_ARRAY_SONG_IDS( 10 ) := 31156 ;
V_ARRAY_SONG_IDS( 11 ) := 31158 ;
V_ARRAY_SONG_IDS( 12 ) := 31160 ;
V_ARRAY_SONG_IDS( 13 ) := 33598 ;
V_ARRAY_SONG_IDS( 14 ) := 33603 ;
V_ARRAY_SONG_IDS( 15 ) := 33605 ;
V_ARRAY_SONG_IDS( 16 ) := 33607 ;
V_ARRAY_SONG_IDS( 17 ) := 33609 ;
V_ARRAY_SONG_IDS( 18 ) := 33611 ;
V_ARRAY_SONG_IDS( 19 ) := 33613 ;
V_ARRAY_SONG_IDS( 20 ) := 33615 ;
V_ARRAY_SONG_IDS( 21 ) := 33617 ;
V_ARRAY_SONG_IDS( 22 ) := 33630 ;
V_ARRAY_SONG_IDS( 23 ) := 33632 ;
V_ARRAY_SONG_IDS( 24 ) := 33636 ;
V_ARRAY_SONG_IDS( 25 ) := 33638 ;
V_ARRAY_SONG_IDS( 26 ) := 33640 ;
V_ARRAY_SONG_IDS( 27 ) := 33642 ;
V_ARRAY_SONG_IDS( 28 ) := 33644 ;
V_ARRAY_SONG_IDS( 29 ) := 33646 ;
V_ARRAY_SONG_IDS( 30 ) := 33648 ;
V_ARRAY_SONG_IDS( 31 ) := 33662 ;
V_ARRAY_SONG_IDS( 32 ) := 33667 ;
V_ARRAY_SONG_IDS( 33 ) := 33669 ;
V_ARRAY_SONG_IDS( 34 ) := 33671 ;
V_ARRAY_SONG_IDS( 35 ) := 33673 ;
V_ARRAY_SONG_IDS( 36 ) := 33675 ;
V_ARRAY_SONG_IDS( 37 ) := 33677 ;
V_ARRAY_SONG_IDS( 38 ) := 33679 ;
V_ARRAY_SONG_IDS( 39 ) := 33681 ;
V_ARRAY_SONG_IDS( 40 ) := 33683 ;
V_ARRAY_SONG_IDS( 41 ) := 33685 ;
V_ARRAY_SONG_IDS( 42 ) := 33700 ;
V_ARRAY_SONG_IDS( 43 ) := 33702 ;
V_ARRAY_SONG_IDS( 44 ) := 33704 ;
V_ARRAY_SONG_IDS( 45 ) := 33706 ;
V_ARRAY_SONG_IDS( 46 ) := 33708 ;
V_ARRAY_SONG_IDS( 47 ) := 33710 ;
V_ARRAY_SONG_IDS( 48 ) := 33712 ;
V_ARRAY_SONG_IDS( 49 ) := 33723 ;
V_ARRAY_SONG_IDS( 50 ) := 33725 ;
V_ARRAY_SONG_IDS( 51 ) := 33727 ;
V_ARRAY_SONG_IDS( 52 ) := 33729 ;
V_ARRAY_SONG_IDS( 53 ) := 33731 ;
V_ARRAY_SONG_IDS( 54 ) := 33733 ;
V_ARRAY_SONG_IDS( 55 ) := 33735 ;
V_ARRAY_SONG_IDS( 56 ) := 33737 ;
V_ARRAY_SONG_IDS( 57 ) := 33749 ;
V_ARRAY_SONG_IDS( 58 ) := 33751 ;
V_ARRAY_SONG_IDS( 59 ) := 33753 ;
V_ARRAY_SONG_IDS( 60 ) := 33755 ;
V_ARRAY_SONG_IDS( 61 ) := 33757 ;
V_ARRAY_SONG_IDS( 62 ) := 33759 ;
V_ARRAY_SONG_IDS( 63 ) := 33761 ;
V_ARRAY_SONG_IDS( 64 ) := 33763 ;
V_ARRAY_SONG_IDS( 65 ) := 33775 ;
V_ARRAY_SONG_IDS( 66 ) := 33777 ;
V_ARRAY_SONG_IDS( 67 ) := 33779 ;
V_ARRAY_SONG_IDS( 68 ) := 33781 ;
V_ARRAY_SONG_IDS( 69 ) := 33783 ;
V_ARRAY_SONG_IDS( 70 ) := 33785 ;
V_ARRAY_SONG_IDS( 71 ) := 33787 ;
V_ARRAY_SONG_IDS( 72 ) := 33789 ;
V_ARRAY_SONG_IDS( 73 ) := 33791 ;
V_ARRAY_SONG_IDS( 74 ) := 33793 ;
V_ARRAY_SONG_IDS( 75 ) := 33807 ;
V_ARRAY_SONG_IDS( 76 ) := 33809 ;
V_ARRAY_SONG_IDS( 77 ) := 33811 ;
V_ARRAY_SONG_IDS( 78 ) := 33813 ;
V_ARRAY_SONG_IDS( 79 ) := 33815 ;
V_ARRAY_SONG_IDS( 80 ) := 33817 ;
V_ARRAY_SONG_IDS( 81 ) := 33819 ;
V_ARRAY_SONG_IDS( 82 ) := 33821 ;
V_ARRAY_SONG_IDS( 83 ) := 33823 ;
V_ARRAY_SONG_IDS( 84 ) := 33825 ;
V_ARRAY_SONG_IDS( 85 ) := 33839 ;
V_ARRAY_SONG_IDS( 86 ) := 33844 ;
V_ARRAY_SONG_IDS( 87 ) := 33846 ;
V_ARRAY_SONG_IDS( 88 ) := 33848 ;
V_ARRAY_SONG_IDS( 89 ) := 33850 ;
V_ARRAY_SONG_IDS( 90 ) := 33852 ;
V_ARRAY_SONG_IDS( 91 ) := 33854 ;
V_ARRAY_SONG_IDS( 92 ) := 33856 ;
V_ARRAY_SONG_IDS( 93 ) := 33858 ;
V_ARRAY_SONG_IDS( 94 ) := 33860 ;
V_ARRAY_SONG_IDS( 95 ) := 33874 ;
V_ARRAY_SONG_IDS( 96 ) := 33879 ;
V_ARRAY_SONG_IDS( 97 ) := 33881 ;
V_ARRAY_SONG_IDS( 98 ) := 33883 ;
V_ARRAY_SONG_IDS( 99 ) := 33885 ;
V_ARRAY_SONG_IDS(100 ) := 33889 ;
/* do stuff with data from Song and Pricing Database coming from the two
separate cursors, then continue processing more rows...
FOR i IN C_get_music_price_data( v_array_song_ids ) LOOP
. (this is the loop where I pass in v_array_song_ids
. populated with only 100 cells and it runs forever)
END LOOP;
END; -
Dynamic where clause for cursor
Hi Friends,
I have a stored procedure with a single input parameter where in the input comes as
a string of values (ex: EMPLOYEE NAMES) separated by commas. I use this parameter in my cursor query
and my requirement is like when the parameter is NULL the query has to run for ALL the employees but if
its not, it has to run for the EMPLOYEE NAMES passed as the input parameter.
What are the possible and apt solutions for this requirement ?
Should I go for dynamic sql or do I have any other optimal solutions?
Please advice me.
Thanks
ZaraDear,
I have a stored procedure with a single input parameter where in the input comes as
a string of values (ex: *EMPLOYEE NAMES*) separated by commas. I use this parameter in my cursor query
and my requirement is like when the parameter is NULL the query has to run for ALL the employees but if
its not, it has to run for the EMPLOYEE NAMES passed as the input parameter.
What are the possible and apt solutions for this requirement ?
Should I go for dynamic sql or do I have any other optimal solutions?
Please advice me.I would suggest you to let down this dynamic SQL and those concatenations that are going to introduce a threat of SQL injection and non shared code into your application.
And, as far as you've opted for a stored procedure I want to suggest you to use
(a) stored procedure in wich only static SQL is used
(b) if point (a) is respected then you don't have to care about using litteral inside your stored procedure. All what you will do in this procedure will be 'auto-binded'; that is PL/SQL (static).
(c) However, make sure to call your stored procedure using bind variables; otherwise your shared pool (v$sql) will be full of hundred and thousands of calls to your stored procedure.
Best Regards
Mohamed Houri -
Huge query with parameter for to use Dynamic Cursor with Parameters
Hi
Is possible put the query below like dynmic cursor passing Parameters ?
How can I do it ?
OPEN P_CURSOR FOR
WITH NOTIFICACAO AS(
SELECT
t1.cd_consultora,
t1.dc_nome_consultora,
t2.nm_notificacao_cn,
t2.dt_notificacao_cn dt_notificacao,
t2.dt_atendimento_notificado,
t1.cd_tipo_estrutura_comercial,
t1.cd_estrutura_comercial
FROM t_consultora t1, nc.t_nc_notificacao_cn t2
WHERE t2.dt_notificacao_cn BETWEEN w_DTA_INI AND w_DTA_FIM
AND t2.cd_consultora = t1.cd_consultora
AND t1.cd_setor = w_cd_setor
AND t1.cd_tipo_estrutura_comercial = p_tp_estrutura_comercial
AND t1.cd_estrutura_comercial = p_cd_estrutura_comercial),
T_NOTIFICADA AS ( select Count(t1.nm_notificacao_cn) over (partition by t1.cd_consultora,t1.nm_notificacao_cn ) QTD_NOTAS,
Count(t2.nm_item_notificacao_cn) over (partition by t1.cd_consultora,t1.nm_notificacao_cn ) QTD_ITENS,
T3.*
from nc.t_nc_notificacao_cn t1,
nc.t_nc_item_notificacao_cn T2,
NOTIFICACAO T3
where t1.dt_notificacao_cn >= to_date('01/09/2006','dd/mm/yyyy')
and t3.nm_notificacao_cn = t1.nm_notificacao_cn
and t1.nm_notificacao_cn = t2.nm_notificacao_cn
and ((t2.cd_tipo_item_nc = 4 and t2.cd_subtipo_item_nc = 6)
or t2.cd_tipo_item_nc = 2 or t2.cd_tipo_item_nc = 3)
and t3.cd_consultora = t1.cd_consultora (+) ) ,
T_BLOQUEADA AS ( SELECT T4.* FROM
(SELECT T3.*,
CASE WHEN T3.BLOQUEADA = -1 THEN 'Bloqueada'
WHEN T3.BLOQUEADA = 0 THEN
(CASE WHEN T3.QTD_NOTAS > 2 THEN
CASE WHEN T3.QTD_ITENS > 8 THEN 'Atencao / Analise'
ELSE
'Normal'
END
ELSE
'Atencao / Analise'
END)
END OBSERVACAO
FROM (SELECT CASE WHEN NVL(T2.ID_CN_BLOQUEADA,1) = 1 then -1
WHEN NVL(T2.ID_CN_BLOQUEADA,1) = 0 THEN 0
END BLOQUEADA, T1.*
FROM T_NOTIFICADA T1,
T_PS_CONSULTORA T2
WHERE T1.CD_CONSULTORA = T2.CD_PESSOA)T3) T4 )
select *
from (SELECT t1.*, ROWNUM r_linha
FROM (SELECT cd_consultora,
dc_nome_consultora,
fnc_busca_telefone(CD_CONSULTORA, 1) TELEFONE1,
fnc_busca_telefone(CD_CONSULTORA, 2) TELEFONE2,
EMAIL,
observacao,
nm_notificacao_cn,
nvl(vl_total_final,0) vl_total_final,
dt_notificacao,
qt_produto_item_nc,
sg_notificacao,
ID_SITUACAO,
qtd_registros
FROM (SELECT /*+ INDEX(W5 I0_NC_TIPO_ITEM_NC) */
W1.cd_consultora,
W1.dc_nome_consultora,
fnc_busca_telefone(w1.CD_CONSULTORA, 1) TELEFONE1,
fnc_busca_telefone(w1.CD_CONSULTORA, 2) TELEFONE2,
fnc_busca_email(w1.CD_CONSULTORA) EMAIL,
W1.OBSERVACAO observacao,
W1.nm_notificacao_cn,
sum(W4.qt_produto_nf *
W4.vl_unitario_final_produto_nf) OVER(PARTITION BY W1.cd_consultora, W1.nm_notificacao_cn) vl_total_final,
W1.dt_notificacao,
sum(W4.qt_produto_nf) OVER(PARTITION BY W1.cd_consultora, W1.nm_notificacao_cn) qt_produto_item_nc,
'PENDENTE' sg_notificacao,
W5.dc_tipo_item_nc ID_SITUACAO,
W_qtd_registros qtd_registros
FROM T_BLOQUEADA W1,
nc.t_nc_item_notificacao_cn W2,
nc.t_nc_produto_item_nc W3,
nc.t_nc_produto_item_nf W4,
nc.t_nc_tipo_item_nc W5
WHERE W1.dt_atendimento_notificado is null
and W1.nm_notificacao_cn =
W2.nm_notificacao_cn
and W2.cd_tipo_item_nc = W5.cd_tipo_item_nc
and W2.nm_notificacao_cn =
W3.nm_notificacao_cn(+)
and W2.nm_item_notificacao_cn =
W3.nm_item_notificacao_cn(+)
and W3.nm_notificacao_cn =
W4.nm_notificacao_cn(+)
and W3.nm_item_notificacao_cn =
W4.nm_item_notificacao_cn(+)
and W3.nm_sequencia_produto_item_nc =
W4.nm_sequencia_produto_item_nc(+)
and W2.cd_tipo_item_nc not in (6, 7)
and ((W2.id_situacao_item_nc = 1) OR
(W2.id_situacao_item_nc = 3 OR
W2.id_solucao_definida is not null))
UNION
SELECT /*+ INDEX(W5 I0_NC_TIPO_ITEM_NC) */
W1.cd_consultora,
W1.dc_nome_consultora,
fnc_busca_telefone(w1.CD_CONSULTORA, 1) TELEFONE1,
fnc_busca_telefone(w1.CD_CONSULTORA, 2) TELEFONE2,
fnc_busca_email(w1.CD_CONSULTORA) EMAIL,
W1.OBSERVACAO observacao,
W1.nm_notificacao_cn,
sum(W4.qt_produto_nf *
W4.vl_unitario_final_produto_nf) OVER(PARTITION BY W1.cd_consultora, W1.nm_notificacao_cn) vl_total_final,
W1.dt_notificacao,
sum(W4.qt_produto_nf) OVER(PARTITION BY W1.cd_consultora, W1.nm_notificacao_cn) qt_produto_item_nc,
'ATENDIDO' sg_notificacao,
W5.dc_tipo_item_nc ID_SITUACAO,
W_qtd_registros qtd_registros
FROM T_BLOQUEADA W1,
nc.t_nc_item_notificacao_cn W2,
nc.t_nc_produto_item_nc W3,
nc.t_nc_produto_item_nf W4,
nc.t_nc_tipo_item_nc W5
WHERE W1.dt_atendimento_notificado is not null
and W1.nm_notificacao_cn =
W2.nm_notificacao_cn
and W2.cd_tipo_item_nc = W5.cd_tipo_item_nc
and W2.nm_notificacao_cn =
W3.nm_notificacao_cn(+)
and W2.nm_item_notificacao_cn =
W3.nm_item_notificacao_cn(+)
and W3.nm_notificacao_cn =
W4.nm_notificacao_cn(+)
and W3.nm_item_notificacao_cn =
W4.nm_item_notificacao_cn(+)
and W3.nm_sequencia_produto_item_nc =
W4.nm_sequencia_produto_item_nc(+)
)T2
---- here with NDS I changed order by
ORDER BY DECODE(p_nm_asc_desc,0,DECODE(p_nm_col_ordem ,1, cd_consultora,2,dc_nome_consultora)) ASC, --,8,vl_total_final)) ASC,
DECODE(p_nm_asc_desc,1,DECODE(p_nm_col_ordem ,1, cd_consultora,2,dc_nome_consultora)) desc --,8,vl_total_final)) DESC
) T1
where rownum <= W_TO_REC)
where r_linha >= W_FROM_REC;Is It Query very much great and how can I to pass parameters w_DTA_INI ,w_DTA_FIM, W_TO_REC,W_FROM_REc ....etc
TIAI did (some time ago and it was a packaged procedure) something like
Procedure p(p_one in datatype,p_two in datatype,p_dataset out sys_refcursor) is
the_sql varchar2(32000);
the_cursor sys_refcursor;
begin
the_sql = 'WITH NOTIFICACAO AS( ' ||
' SELECT ' ||
' t1.cd_consultora, ' ||
' where t1.dt_notificacao_cn >= to_date(''01/09/2006'',''dd/mm/yyyy'') ' || -- note the ''
' where rownum <= :W_TO_REC) ' || -- parameter 1
' where r_linha >= :W_FROM_REC '; -- parameter 2
open the_cursor for the_sql using p_one,p_two; -- just by the book
end p;if I remember correctly
Regards
Etbin -
How to pass parameter for table name in form6i.
Hi ,
I am facing the problem to pass parameter for table name in form6i.
If any solution please infirm me earliest to my mail id.
([email protected])
example:
begin
select ename into :ename
from :tab_name
where empno =7788;
end;
It gives error as bad bind variable 'tab_name'
*** where :ename and :tab_name are form fields
Thanking you,
Balasahebobject name not taken as table --> what do u mean by
this?
Please be more clear..
Regards
PriyaI have two block. First block I am displaying all the table using user_objects table. Another block I want display, user which table selected, corresponding table all the records. -
Passing where and group by clause to cursor
I am working on a procedure that builds a where clause and needs a group by clause to return the correct results. I am trying to pass both the where and group by variables into the cursor.
The variables are getting populated correctly, but when the cursor gets created, the variables are not in the cursor.
Here is the code I'm working with. It is a part of a package, but makes no calls to other parts of the package.
PROCEDURE createFollowUpTask_Exposure( psUppgkedjetyp IN tis.tial.uppgkedjetyp%TYPE default NULL,
psAlarmtyp IN tis.tial.alarmtyp%TYPE default NULL,
psSubtyp IN tis.tial.subtyp%TYPE default NULL,
pnDays IN NUMBER default NULL,
psKampkod IN tis.tiin.kampkod%TYPE default NULL,
psKatnr IN tis.tiin.katnr%TYPE default NULL,
psUtgava IN tis.tiin.utgava%TYPE default NULL,
psKatslag IN tis.tikg.katslag%TYPE default NULL,
psProdsyst IN tis.tikg.prodsyst%TYPE default NULL,
psUppgtyp IN tis.tiin.uppgtyp%TYPE default NULL,
psProdkod IN tis.tiin.prodkod%TYPE default NULL,
psStatus IN tis.tiin.status%TYPE default NULL
) AS
cTIAL tis.tial%ROWTYPE;
vLopnr tis.tial.lopnr%TYPE;
vSqlWhere VARCHAR2(4000);
vGroupBy VARCHAR2(1000) := ' tiin.kampkod, tiin.abnr, tiko.fordsalj';
cSelectCursor SYS_REFCURSOR;
vSqlSelect VARCHAR2(4000);
psDays VARCHAR2(50);
cRec T_TIAL_REC;
nCount number := 0;
CURSOR cSqlSelect( SqlWhere IN VARCHAR2, GroupBy IN VARCHAR2) IS
SELECT tiin.kampkod, tiin.abnr, tiko.fordsalj, MAX(tici.regdat) ALARMDATE
FROM tis.tiin
JOIN tis.tiko ON tiin.kampkod = tiko.kampkod AND tiin.abnr = tiko.abnr
JOIN core.tici ON tiin.kampkod = tici.kampkod AND tiin.abnr = tici.abnr AND tici.inplnr = tiin.inplnr
WHERE 1=1 || SqlWhere
GROUP BY GroupBy;
BEGIN
-- If these parameters are null, raise error
IF psUppgkedjetyp IS NULL and psSubtyp IS NULL THEN
raise_application_error(-20001,
'Either Event Chain or Starting Event must be assigned');
END IF;
-- Populate TIAL values
IF psUppgkedjetyp IS NOT NULL THEN
cTIAL.Uppgkedjetyp := psUppgkedjetyp;
END IF;
IF psAlarmtyp IS NOT NULL THEN
cTIAL.Alarmtyp := psAlarmtyp;
END IF;
cTIAL.Handklass := 'T';
cTIAL.Blobid := 0;
IF pnDays IS NOT NULL THEN
psDays := '+ '||pnDays;
END IF;
IF psSubtyp IS NOT NULL THEN
cTIAL.Subtyp := psSubtyp;
END IF;
-- Create Where clause for cursor
vSqlWhere := '';
IF psKampkod IS NOT NULL THEN
vSqlWhere := vSqlWhere||' AND tiin.kampkod = '''|| psKampkod||'''';
END IF;
IF psKatnr IS NOT NULL THEN
vSqlWhere := vSqlWhere||' AND tiin.katnr = '''||psKatnr||'''';
END IF;
IF psUtgava IS NOT NULL THEN
vSqlWhere := vSqlWhere||' AND tiin.utgava = '''||psUtgava||'''' ;
END IF;
IF psKatslag IS NOT NULL THEN
vSqlWhere := vSqlWhere||' AND tikg.katslag = '''||psKatslag||'''';
END IF;
IF psProdsyst IS NOT NULL THEN
vSqlWhere := vSqlWhere||' AND tikg.prodsyst = '''||psProdsyst||'''';
END IF;
IF psUppgtyp IS NOT NULL THEN
vSqlWhere := vSqlWhere||' AND tiin.uppgtyp = '''||psUppgtyp||'''';
END IF;
IF psProdkod IS NOT NULL THEN
vSqlWhere := vSqlWhere||' AND tiin.prodkod = '''||psProdkod||'''';
END IF;
IF psStatus IS NOT NULL THEN
vSqlWhere := vSqlWhere||' AND tiin.status = '''||psStatus||'''';
END IF;
-- Loop through all records meeting input parameters and set required TIAL values.
FOR i IN cSqlSelect(vSqlWhere, vGroupBy)
LOOP
--FETCH cSelectCursor INTO cRec;
cTIAL.Kampkod := '';
cTIAL.Abnr := '';
cTIAL.Sign := '';
cTIAL.Alarmdate := '';
cTIAL.Kampkod := i.Kampkod;
cTIAL.Abnr := i.Abnr;
cTIAL.Sign := i.fordsalj;
cTIAL.Alarmdate := i.alarmdate;
nCount := nCount + 1;
IF vLopnr = -1 THEN
raise_application_error(-20002,
'Error Creating task for: '||cTIAL.Kampkod||' '||cTIAL.Abnr||' Sales Rep: '||cTIAL.Alarmdate);
END IF;
END LOOP;
DBMS_OUTPUT.PUT_LINE('I created '||nCount||' records.');
END createFollowUpTask_Exposure;
Thanks in advance for any help.Hi,
Welcome to the forum!
Try this (not tested) as an example:
PROCEDURE createFollowUpTask_Exposure(psUppgkedjetyp IN tis.tial.uppgkedjetyp%TYPE DEFAULT NULL,
psAlarmtyp IN tis.tial.alarmtyp%TYPE DEFAULT NULL,
psSubtyp IN tis.tial.subtyp%TYPE DEFAULT NULL,
pnDays IN NUMBER DEFAULT NULL,
psKampkod IN tis.tiin.kampkod%TYPE DEFAULT NULL,
psKatnr IN tis.tiin.katnr%TYPE DEFAULT NULL,
psUtgava IN tis.tiin.utgava%TYPE DEFAULT NULL,
psKatslag IN tis.tikg.katslag%TYPE DEFAULT NULL,
psProdsyst IN tis.tikg.prodsyst%TYPE DEFAULT NULL,
psUppgtyp IN tis.tiin.uppgtyp%TYPE DEFAULT NULL,
psProdkod IN tis.tiin.prodkod%TYPE DEFAULT NULL,
psStatus IN tis.tiin.status%TYPE DEFAULT NULL) AS
cTIAL tis.tial%ROWTYPE;
vLopnr tis.tial.lopnr%TYPE;
vSqlWhere VARCHAR2(4000);
vGroupBy VARCHAR2(1000) := ' tiin.kampkod, tiin.abnr, tiko.fordsalj';
cSelectCursor SYS_REFCURSOR;
vSqlSelect VARCHAR2(4000);
psDays VARCHAR2(50);
cRec T_TIAL_REC;
nCount NUMBER := 0;
FUNCTION fnc_cSqlSelect(SqlWhere IN VARCHAR2,
GroupBy IN VARCHAR2) RETURN VARCHAR2 IS
BEGIN
RETURN 'SELECT tiin.kampkod,
tiin.abnr,
tiko.fordsalj,
MAX(tici.regdat) ALARMDATE
FROM tis.tiin
JOIN tis.tiko ON tiin.kampkod = tiko.kampkod
AND tiin.abnr = tiko.abnr
JOIN core.tici ON tiin.kampkod = tici.kampkod
AND tiin.abnr = tici.abnr
AND tici.inplnr = tiin.inplnr
WHERE 1 = 1 ' || SqlWhere || ' GROUP BY ' || GroupBy;
END fnc_cSqlSelect;
BEGIN
-- If these parameters are null, raise error
IF psUppgkedjetyp IS NULL AND psSubtyp IS NULL THEN
raise_application_error(-20001,
'Either Event Chain or Starting Event must be assigned');
END IF;
-- Populate TIAL values
IF psUppgkedjetyp IS NOT NULL THEN
cTIAL.Uppgkedjetyp := psUppgkedjetyp;
END IF;
IF psAlarmtyp IS NOT NULL THEN
cTIAL.Alarmtyp := psAlarmtyp;
END IF;
cTIAL.Handklass := 'T';
cTIAL.Blobid := 0;
IF pnDays IS NOT NULL THEN
psDays := '+ ' || pnDays;
END IF;
IF psSubtyp IS NOT NULL THEN
cTIAL.Subtyp := psSubtyp;
END IF;
-- Create Where clause for cursor
vSqlWhere := '';
IF psKampkod IS NOT NULL THEN
vSqlWhere := vSqlWhere || ' AND tiin.kampkod = ''' || psKampkod || '''';
END IF;
IF psKatnr IS NOT NULL THEN
vSqlWhere := vSqlWhere || ' AND tiin.katnr = ''' || psKatnr || '''';
END IF;
IF psUtgava IS NOT NULL THEN
vSqlWhere := vSqlWhere || ' AND tiin.utgava = ''' || psUtgava || '''';
END IF;
IF psKatslag IS NOT NULL THEN
vSqlWhere := vSqlWhere || ' AND tikg.katslag = ''' || psKatslag || '''';
END IF;
IF psProdsyst IS NOT NULL THEN
vSqlWhere := vSqlWhere || ' AND tikg.prodsyst = ''' || psProdsyst || '''';
END IF;
IF psUppgtyp IS NOT NULL THEN
vSqlWhere := vSqlWhere || ' AND tiin.uppgtyp = ''' || psUppgtyp || '''';
END IF;
IF psProdkod IS NOT NULL THEN
vSqlWhere := vSqlWhere || ' AND tiin.prodkod = ''' || psProdkod || '''';
END IF;
IF psStatus IS NOT NULL THEN
vSqlWhere := vSqlWhere || ' AND tiin.status = ''' || psStatus || '''';
END IF;ç
-- Loop through all records meeting input parameters and set required TIAL values.
OPEN cSelectCursor FOR fnc_cSqlSelect(vSqlWhere,
vGroupBy);
LOOP
FETCH cSelectCursor
INTO v; -- You must define a variable 'v' to hold the data of cursor
EXIT WHEN cSelectCursor%NOTFOUND;
--FETCH cSelectCursor INTO cRec;
cTIAL.Kampkod := '';
cTIAL.Abnr := '';
cTIAL.Sign := '';
cTIAL.Alarmdate := '';
cTIAL.Kampkod := i.Kampkod;
cTIAL.Abnr := i.Abnr;
cTIAL.Sign := i.fordsalj;
cTIAL.Alarmdate := i.alarmdate;
nCount := nCount + 1;
IF vLopnr = -1 THEN
raise_application_error(-20002,
'Error Creating task for: ' || cTIAL.Kampkod || ' ' ||
cTIAL.Abnr || ' Sales Rep: ' || cTIAL.Alarmdate);
END IF;
END LOOP;
CLOSE cSelectCursor;
DBMS_OUTPUT.PUT_LINE('I created ' || nCount || ' records.');
END createFollowUpTask_Exposure;
/Regards,
Maybe you are looking for
-
How can you get your money back for an app that doesn't work???
-
Hi, I hope someone can help me with this. I've got an ASP.Net application that initiates an HTTPS request to another server as needed. The Application Pool is automatically recycled every night, and the end users have no trouble until about 12:30 to
-
Photos distorted when opened in preview, yet ok in cover flow
Hi I previously posted this question which got moved to the iPhoto section, but its NOT an iPhoto issue: http://discussions.apple.com/thread.jspa?threadID=2619921&tstart=0 Having purchased a new camera (Sony DSC2000) the first time I used it the phot
-
HT5219 can i connect thunderbolt display to macpro
can i connect thunderbolt display to macpro i tried alot but its not supporting
-
It will not turn off & it will not go into recovery mode. I had to completely delete & reinstall itunes just so it woulkd even show up there. Now it says "Can not connect enter correct passcode on ipod" Which of course I don't have that option. He di