[ORACLE 9] OPEN FOR statement USING bind variable
Hi,
I have a loop that only fetches 1 record instead of 7:
DECLARE
lv_into varchar2(40);
lv_qry varchar2(400);
type curtest_ref is ref cursor;
curtest curtest_ref;
lv_compteur number(4) := 1;
lv_client_loc varchar2(100);
BEGIN
dbms_output.put_line( 'Début' );
lv_qry := 'select client_loc from tmp_jbm where client_id = :A ';
open curtest for lv_qry using lv_compteur;
loop
fetch curtest into lv_client_loc ;
exit when curtest%notfound;
dbms_output.put_line( 'ligne: ' || to_char( lv_compteur )
|| ' Client Loc: ' || lv_client_loc );
lv_compteur := lv_compteur + 1;
exit when lv_compteur > 6;
end loop;
EXCEPTION
when others then
dbms_output.put_line( 'Erreur exception: ' || sqlerrm );
END;
[/END CODE]
It looks like the cursor only fetches 1 record and then stops.
Many thanks
The code is doing what you have asked it to do.
Incrementing lv_compteur := lv_compteur + 1; inside the FOR LOOP will not refresh your CURSOR as the CURSOR OPEN statement is outside the loop.
You could change your lv_qry variable to something like this:
lv_compteur_min number(4) := 1;
lv_compteur_max number(4) := 6;
lv_qry := 'select client_loc from tmp_jbm where client_id BETWEEN :A AND :B';and OPEN the cursor by passing two variables
open curtest for lv_qry using lv_compteur_min, lv_compteur_max ;
Similar Messages
-
Possible for Oracle to consider constraints when using bind variable?
Consider the following table with a check constraint listing the possible values of the column
create table TEST_TABLE(
my_column varchar2(10));
insert into TEST_TABLE select 'VALUE1' from dba_objects;
alter table TEST_TABLE
add constraint TEST_TABLE_CHK1
check (my_column in ('VALUE1', 'VALUE2'));
begin dbms_stats.gather_table_stats(ownname=>user,tabname=>'TEST_TABLE');END;Let's see the number of logical I/O's needed for the following SQL statements.
(The value was obtained by the delta ofselect m.value from v$mystat m, v$statname n
where name='session logical reads' and m.statistic#=n.statistic#)
If string lateral is used:
declare
n number;
begin
select count(*) into n from test_table where my_column='VALUE1';
end;
Consistent Gets: 21
declare
n number;
begin
select count(*) into n from test_table where my_column='VALUE2';
end;
Consistent Gets: 21
declare
n number;
begin
select count(*) into n from test_table where my_column='VALUE3';
end;
Consistent Gets: 0Oracle can eliminate the table if it knows the queried value can't satisfy the constraint. Good.
(Actually, the execution plan for the last query included the 'FILTER' operation.)
However, if bind variable is used:
declare
n number;
x varchar2(10);
begin
x := 'VALUE1';
select count(*) into n from test_table where my_column=x;
end;
Consistent Gets: 21
declare
n number;
x varchar2(10);
begin
x := 'VALUE3';
select count(*) into n from test_table where my_column=x;
end;
Consistent Gets: 21Oracle can't eliminate the table using the constraint. I can understand that because bind variables are used, Oracle can't directly eliminate the table when generating the execution plan. However, is it possible to eliminate the table, or at least employ some shortcut in runtime? If not, will this be a performance loss compared with using values laterals when check constraint exists?
(And is it possible to use autotrace on PL/SQL block in sqlplus?)
Oracle:
10.2.0.4 SE
11.2.0.2 SE
OS:
RHEL5However, is it possible to eliminate the table, or at least employ some shortcut in runtime? I can't see how to do this. Oracle has a sqltext that has an embedded bind variable in it. And for this sqltext it has an execution plan in the shared pool that will be used irrespective of the actual bound values at runtime.
Maybe in 11G, with adaptive cursor sharing / plan bind awareness, Oracle might be smart enough to introduce a second execution plan for the VALUE3 case.
If not, will this be a performance loss compared with using values laterals when check constraint exists?Only if you submit the dumb query and search for records with VALUE3... Normally your application code would not hold/generate these queries.
Will it?
For columns whose values are bound by a CHECK constraint, one might even consider to never use bind variables, since very likely you will have few versions of queries that use these columns.
Not?
Edited by: Toon Koppelaars on Jun 22, 2011 1:20 PM -
Does Oracle E-business suite R12 use bind variables?
Hello,
We have Oracle E-business suite R12 and database 10.2.0.3.
I was just wondering does E-business suite R12 use bind variables?
We have recently purchased Toad and Spotlight, in Spotlight we keep getting an alarm raised for Parse SQL requests (Library cache latches alert) When I've researched into this the recommendation is to try to improve the use of bind variables within your application.
Please could someone help me answer this?
Thank you
SarahHi,
I was just wondering does E-business suite R12 use bind variables? Yes it uses bind variables. You can trace a concurrent program and get the tkprof to check it.
We have recently purchased Toad and Spotlight, in Spotlight we keep getting an alarm raised for Parse SQL requests (Library cache latches alert) When I've researched into this the recommendation is to try to improve the use of bind variables within your application.You can not make every conc. program or sql use bind variables. Some times it is not possible so.
Thanks -
Using bind variables with sql statements
We connect from a VB 6.0 program via OO4O to an Oracle 8.1.7 database, using bind variables in connection with select statements. Running ok, but performance again by using bind vars not as good as expected!
When looking into the table v$sqlarea, we were able to detect the reason. We expected that our program submits the sql statement with bind vars, Oracle parses this once, and with each select statement again, we do not have a reparse. But: It seems that with each new session Oracle reparses the sql statement, that is, Oracle is not able to memorize or cache bind vars and statements. Even more worrying, this kind of behaviour was visible with each new dynaset, but the same database/session.
Is there anybody our there with an idea of what is happening here?
Code snippet:
Dim OraSession As OracleInProcServer.OraSessionClass
Dim OraDatabase As OracleInProcServer.OraDatabase
Set OraSession = CreateObject("OracleInProcServer.XOraSession")
Set OraDatabase = OraSession.OpenDatabase(my database", "my connect", 0&)
OraDatabase.Parameters.Add "my_bind", 0, ORAPARM_INPUT
OraDatabase.Parameters("my_bind").DynasetOption = ORADYN_NOCACHE
OraDatabase.Parameters("my_bind").serverType = ORATYPE_NUMBER ' Bind Var Type
Dim RS As OracleInProcServer.OraDynaset
strSQLstatement= "Select * from my_table where igz= [my_bind] "
Set RS = OraDatabase.CreateDynaset(strSQLstatement, &H4)
OraDatabase.Parameters("my_bind").Value = myValue
RS.Refresh
Cheers and thanks a lot :)
Michael SonntagWe connect from a VB 6.0 program via OO4O to an Oracle 8.1.7 database, using bind variables in connection with select statements. Running ok, but performance again by using bind vars not as good as expected!
When looking into the table v$sqlarea, we were able to detect the reason. We expected that our program submits the sql statement with bind vars, Oracle parses this once, and with each select statement again, we do not have a reparse. But: It seems that with each new session Oracle reparses the sql statement, that is, Oracle is not able to memorize or cache bind vars and statements. Even more worrying, this kind of behaviour was visible with each new dynaset, but the same database/session.
Is there anybody our there with an idea of what is happening here?
Code snippet:
Dim OraSession As OracleInProcServer.OraSessionClass
Dim OraDatabase As OracleInProcServer.OraDatabase
Set OraSession = CreateObject("OracleInProcServer.XOraSession")
Set OraDatabase = OraSession.OpenDatabase(my database", "my connect", 0&)
OraDatabase.Parameters.Add "my_bind", 0, ORAPARM_INPUT
OraDatabase.Parameters("my_bind").DynasetOption = ORADYN_NOCACHE
OraDatabase.Parameters("my_bind").serverType = ORATYPE_NUMBER ' Bind Var Type
Dim RS As OracleInProcServer.OraDynaset
strSQLstatement= "Select * from my_table where igz= [my_bind] "
Set RS = OraDatabase.CreateDynaset(strSQLstatement, &H4)
OraDatabase.Parameters("my_bind").Value = myValue
RS.Refresh
Cheers and thanks a lot :)
Michael Sonntag -
How to use bind variable in this select statement
Hi,
I have created this procedure where table name and fieldname is variable as they vary, therefore i passed them as parameter. This procedure will trim leading (.) if first five char is '.THE''. The procedure performs the required task. I want to make select statement with bind variable is there any possibility to use a bind variable in this select statement.
the procedure is given below:
create or replace procedure test(tablename in varchar2, fieldname IN varchar2)
authid current_user
is
type poicurtype is ref cursor;
poi_cur poicurtype;
sqlst varchar2(250);
THEVALUE NUMBER;
begin
sqlst:='SELECT EMPNO FROM '||TABLENAME||' WHERE SUBSTR('||FIELDNAME||',1,5)=''.THE ''';
DBMS_OUTPUT.PUT_LINE(SQLST);
OPEN POI_CUR FOR SQLST ;
LOOP
FETCH POI_CUR INTO THEVALUE;
EXIT WHEN POI_CUR%NOTFOUND;
DBMS_OUTPUT.PUT_LINE(THEVALUE);
SQLST:='UPDATE '||TABLENAME|| ' SET '||FIELDNAME||'=LTRIM('||FIELDNAME||',''.'')';
SQLST:=SQLST|| ' WHERE EMPNO=:X';
DBMS_OUTPUT.PUT_LINE(SQLST);
EXECUTE IMMEDIATE SQLST USING THEVALUE;
END LOOP;
COMMIT;
END TEST;
Best Regards,So you want to amend each row individually? Is there some reason you're trying to make this procedure run as slow as possible?
create or replace procedure test (tablename in varchar2, fieldname in varchar2)
authid current_user
is
sqlst varchar2 (250);
thevalue number := 1234;
begin
sqlst := 'update ' || tablename || ' set ' || fieldname || '= ltrim(' || fieldname || ',''.'') where substr(' || fieldname
|| ',1,5) = ''.THE ''';
dbms_output.put_line (sqlst);
execute immediate sqlst;
end test;will update every row that satisfies the criteria in a single statement. If there are 10 rows that start with '.THE ' then it will update 10 rows. -
Do not use bind variable notations for p_session_id argument...
Hi there,
... in apex_custom_auth.login the Apex doc says. Does anyone know why not?
LOGIN Procedure
Also referred to as the "Login API," this procedure performs authentication and session registration.
p_session_id Current Oracle Application Express session ID.
Note: Do not use bind variable notations for p_session_id argument.Thanks
LuisI tend to avoid assigning values to bind variables like that - but it may be due to the nature of much of my code residing in PL/SQL packages.
And due to the strange encounters I have had with this, like your linked discussions, I've tended towards using apex_util instead.
You may also enjoy this discussion
http://www.danielmcghan.us/2012/08/implicit-commits-in-apex.html
Scott -
Performance when using bind variables
I'm trying to show myself that bind variables improve performance (I believe it, I just want to see it).
I've created a simple table of 100,000 records each row a single column of type integer. I populate it with a number between 1 and 100,000
Now, with a JAVA program I delete 2,000 of the records by performing a loop and using the loop counter in my where predicate.
My first JAVA program runs without using bind variables as follows:
loop
stmt.executeUpdate("delete from nobind_test where id = " + i);
end loop
My second JAVA program uses bind variables as follows:
pstmt = conn.prepareStatement("delete from bind_test where id = ?");
loop
pstmt.setString(1, String.valueof(i));
rs = pstmt.executeQuery();
end loop;
Monitoring of v$SQL shows that program one doesn't use bind variables, and program two does use bind variables.
The trouble is that the program that does not use bind variables runs faster than the bind variable program.
Can anyone tell me why this would be? Is my test too simple?
Thanks.[email protected] wrote:
I'm trying to show myself that bind variables improve performance (I believe it, I just want to see it).
I've created a simple table of 100,000 records each row a single column of type integer. I populate it with a number between 1 and 100,000
Now, with a JAVA program I delete 2,000 of the records by performing a loop and using the loop counter in my where predicate.
Monitoring of v$SQL shows that program one doesn't use bind variables, and program two does use bind variables.
The trouble is that the program that does not use bind variables runs faster than the bind variable program.
Can anyone tell me why this would be? Is my test too simple?
The point is that you have to find out where your test is spending most of the time.
If you've just populated a table with 100,000 records and then start to delete randomly 2,000 of them, the database has to perform a full table scan for each of the records to be deleted.
So probably most of the time is spent scanning the table over and over again, although most of blocks might already be in your database buffer cache.
The difference between the hard parse and the soft parse of such a simple statement might be negligible compared to effort it takes to fulfill each delete execution.
You might want to change the setup of your test: Add a primary key constraint to your test table and delete the rows using this primary key as predicate. Then the time it takes to locate the row to delete should be negligible compared to the hard parse / soft parse difference.
You probably need to increase your iteration count because deleting 2,000 records this way probably takes too short and introduces measuring issues. Try to delete more rows, then you should be able to spot a significant and constant difference between the two approaches.
In order to prevent any performance issues from a potentially degenerated index due to numerous DML activities, you could also just change your test case to query for a particular column of the row corresponding to your predicate rather than deleting it.
Regards,
Randolf
Oracle related stuff blog:
http://oracle-randolf.blogspot.com/
SQLTools++ for Oracle (Open source Oracle GUI for Windows):
http://www.sqltools-plusplus.org:7676/
http://sourceforge.net/projects/sqlt-pp/ -
Using Bind Variable in a SELECT
Hi,
I'm trying to build up my SQL query at run-time using bind variables and in the Oracle® Fusion Middleware Fusion Developer's Guide for Oracle Application Development Framework 11g Release 1 (11.1.1) it says that 'After defining the bind variables, the next step is to reference them in the SQL statement. While SQL syntax allows bind variables to appear both in the SELECT list and in the WHERE clause, you'll typically use them in the latter context, as part of your WHERE clause.'.
However, when I try to use the bind variables in my SELECT list because I've had to set a type for the variable to String the variable gets inserted with inverted commas either side e.g. SELECT 'Service' FROM TestTable. Is it possible to use bind variables to insert a value into my select list without these inverted commas around it?
Thanks in advance,
TomOK, thanks for your response. Do you know of a way then where I can control my SELECT parameters programmatically? I'm currently trying to do it using the information in the chapter '35.9 Using Programmatic View Objects for Alternative Data Sources' from the Oracle® Fusion Middleware Fusion Developer's Guide for Oracle Application Development Framework 11g Release 1 (11.1.1). I think I'm part way there, would this be the correct way of acheiving what I want?
Cheers, Tom -
Trying to pass array to stored procedure in a loop using bind variable
All,
I'm having trouble figuring out if I can do the following:
I have a stored procedure as follows:
create procedure enque_f826_utility_q (inpayload IN f826_utility_payload, msgid out RAW) is
enqopt dbms_aq.enqueue_options_t;
mprop dbms_aq.message_properties_t;
begin
dbms_aq.enqueue(queue_name=>'f826_utility_queue',
enqueue_options=>enqopt,
message_properties=>mprop,
payload=>inpayload,
msgid=>msgid);
end;
The above compiles cleanly.
The first parameter "inpayload" a database type something like the following:
create or replace type f826_utility_payload as object
2 (
3 YEAR NUMBER(4,0),
4 MONTH NUMBER(2,0),
83 MUSTHAVE CHAR(1)
84 );
I'd like to call the stored procedure enque_f826_utility_q in a loop passing to it
each time, new values in the inpayload parameter.
My questions are:
First, I'm not sure in php, how to construct the first parameter which is a database type.
Can I just make an associative array variable with the keys of the array the same as the columns of the database type shown above and then pass that array to the stored procedure?
Second, is it possible to parse a statement that calls the enque_f826_utility_q procedure using bind variables and then execute the call to the stored procedure in a loop passing new bind variables each time?
I've tried something like the following but it's not working:
$conn = oci_pconnect (....);
$stmt = "select * from f826_utility";
$stid = oci_parse($conn, $sqlstmt);
$r = oci_execute($stid, OCI_DEFAULT);
$row = array();
$msgid = "";
$enqstmt = "call enque_f826_utility_q(:RID,:MID)";
$enqstid = oci_parse($conn, $sqlstmt);
oci_bind_by_name($enqstid, ":RID", $row); /* line 57 */
oci_bind_by_name($enqstid, ":MID", $msgid);
while ($row = oci_fetch_array($stid, OCI_RETURN_NULLS+OCI_ASSOC))
++$rowcnt;
if (! oci_execute($enqstid)) /* line 65 */
echo "Error";
exit;
When I run this, I get the following:
PHP Notice: Array to string conversion in C:\Temp\enqueue_f826_utility.php on l
ine 57
Entering loop to process records from F826_UTIITY table
PHP Notice: Array to string conversion in C:\Temp\enqueue_f826_utility.php on l
ine 65
PHP Warning: oci_execute(): ORA-06553: PLS-306: wrong number or types of argume
nts in call to 'ENQUE_F826_UTILITY_Q' in C:\Temp\enqueue_f826_utility.php on lin
e 65
PHP Notice: Undefined variable: msgnum in C:\Temp\enqueue_f826_utility.php on l
ine 68
Error during oci_execute of statement select * from F826_UTILITY
Exiting!Thanks for the reply.
I took a look at this article. What it appears to describe is
a calling a stored procedure that takes a collection type which is an array.
Does anyone from Oracle know if I can pass other database type definitions to a stored procedure from PHP?
I have a type defined in my database similar to the following which is not
an array but a record of various fields. This type corresponds to a payload
of an advanced queue payload type. I have a stored procedure which will take as it's input, a payload type of this structure and then enqueue it to a queue.
So I want to be able to pass a database type similar to the following type definition from within PHP. Can anyone from Oracle verify whether or not this is possible?
create or replace type f826_utility_payload as object
YEAR NUMBER(4,0),
MONTH NUMBER(2,0),
UTILITY_ID NUMBER(10,0),
SUBMIT_FAIL_BY VARCHAR2(30),
MUSTHAVE CHAR(1)
); -
Combine select and update into single statement,without bind-variable
I have a problem, that I think is not possible to solve the way I want to, but I just wanted to check before leaving the idea...
I am looking for a way to combine the select and the update statement into one single statement. This is what I wan't to achive: select some data, and update the data selected before returning them.
On this site http://www.psoug.org/reference/update.html I see that the following are possible:
var bnd1 NUMBER
var bnd2 VARCHAR2(30)
var bnd3 NUMBER
UPDATE employees
SET job_id ='SA_MAN', salary = salary + 1000,
department_id = 140
WHERE last_name = 'Jones'
RETURNING salary*0.25, last_name, department_id
INTO :bnd1, :bnd2, :bnd3;
I need to have this as a single statement, and cannot use bind-variables. So I was hoping that something like this could be possible:
UPDATE customer c
SET c.HAS_CREDIT ='1'
WHERE c.HAS_CREDIT = '0'
RETURNING c.CUSTOMER_NO, c.FIRSTNAME, c.LASTNAME
where c.HAS_CREDIT = '1'
But this doesn't compile, complaining of missing into (ORA-00925: missing INTO keyword). And even though I would like this to be possible because this would solve my current problem, I think it would be very confusing. For instance; would the where clause of the returning part be operating after the update or before?
Any comments or suggestions on how to get it work in a single statement, or should I just leave this path straight away?Hi,
RETURNING only works with bind variables, see
http://download-uk.oracle.com/docs/cd/B19306_01/appdev.102/b14261/returninginto_clause.htm#sthref3006
The real problem is that the form of RETURNING clause with bind variables is only valid for single row update or insert statements.
To update (or insert) multiple rows and return the data, you will need to use
RETURNING BULK COLLECT INTO clause. See
http://download-uk.oracle.com/docs/cd/B19306_01/appdev.102/b14261/tuning.htm#sthref2236
Cheers,
Colin -
How to use bind variables with XMLTABLE?
I tried to use bind variables with xmltable statment. Here, my testcase:
create or replace function wsdltest return xmltype as
l_dummy xmltype;
l_stt clob;
l_name varchar2(500);
l_xml clob;
BEGIN
l_xml :=
'<definitions name="F1" targetNamespace="http://xmlns.oracle.com/orawsv/XFILES/F1" xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:tns="http://xmlns.oracle.com/orawsv/XFILES/F1" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/">
<types>
<xsd:schema targetNamespace="http://xmlns.oracle.com/orawsv/XFILES/F1" elementFormDefault="qualified">
<xsd:element name="SVARCHAR2-F1Input">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="A-VARCHAR2-IN" type="xsd:string"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element name="F1Output">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="RETURN" type="xsd:string"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:schema>
</types>
<message name="F1InputMessage">
<part name="parameters" element="tns:SVARCHAR2-F1Input"/>
</message>
<message name="F1OutputMessage">
<part name="parameters" element="tns:F1Output"/>
</message>
<portType name="F1PortType">
<operation name="F1">
<input message="tns:F1InputMessage"/>
<output message="tns:F1OutputMessage"/>
</operation>
</portType>
<binding name="F1Binding" type="tns:F1PortType">
<soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
<operation name="F1">
<soap:operation soapAction="F1"/>
<input>
<soap:body parts="parameters" use="literal"/>
</input>
<output>
<soap:body parts="parameters" use="literal"/>
</output>
</operation>
</binding>
<service name="F1Service">
<documentation>Oracle Web Service</documentation>
<port name="F1Port" binding="tns:F1Binding">
<soap:address location="http://localhost:8080/orawsv/XFILES/F1"/>
</port>
</service>
</definitions>';
-- OK
l_stt := 'select * from xmltable(XMLNAMESPACES(''http://www.w3.org/2001/XMLSchema'' AS "XSD", default ''http://schemas.xmlsoap.org/wsdl/''),
''//definitions/types/XSD:schema/XSD:element[@name="SVARCHAR2-F1Input"]''
passing xmltype(:1)
columns
ab xmltype path ''.'' ) t';
EXECUTE IMMEDIATE l_stt INTO l_dummy using l_xml;
-- ERROR ORA-01006
l_name := '"SVARCHAR2-F1Input"';
l_stt := 'select * from xmltable(XMLNAMESPACES(''http://www.w3.org/2001/XMLSchema'' AS "XSD", default ''http://schemas.xmlsoap.org/wsdl/''),
''//definitions/types/XSD:schema/XSD:element[@name=:2]''
passing xmltype(:1)
columns
ab xmltype path ''.'' ) t';
EXECUTE IMMEDIATE l_stt INTO l_dummy using l_xml, l_name;
return l_dummy;
END;
Any idea ?
Thanks in advance
CyrylWhy are you using dynamic SQL statements? Why not just use something like this instead in your PL/SQL. I also replaced the leading // in your Xpath with just / since you start from the root node.
select *
INTO l_dummy
from xmltable(XMLNAMESPACES('http://www.w3.org/2001/XMLSchema' AS "XSD", default 'http://schemas.xmlsoap.org/wsdl/'),
'/definitions/types/XSD:schema/XSD:element'
passing xmltype(l_xml)
columns
ab xmltype path '.' ) t;Also, the above returns two rows, which I suspect is not what you want. Here is the pure SQL version for you to debug.
select *
from xmltable(XMLNAMESPACES('http://www.w3.org/2001/XMLSchema' AS "XSD", default 'http://schemas.xmlsoap.org/wsdl/'),
'/definitions/types/XSD:schema/XSD:element'
passing xmltype('<definitions name="F1" targetNamespace="http://xmlns.oracle.com/orawsv/XFILES/F1" xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:tns="http://xmlns.oracle.com/orawsv/XFILES/F1" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/">
<types>
<xsd:schema targetNamespace="http://xmlns.oracle.com/orawsv/XFILES/F1" elementFormDefault="qualified">
<xsd:element name="SVARCHAR2-F1Input">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="A-VARCHAR2-IN" type="xsd:string"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element name="F1Output">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="RETURN" type="xsd:string"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:schema>
</types>
<message name="F1InputMessage">
<part name="parameters" element="tns:SVARCHAR2-F1Input"/>
</message>
<message name="F1OutputMessage">
<part name="parameters" element="tns:F1Output"/>
</message>
<portType name="F1PortType">
<operation name="F1">
<input message="tns:F1InputMessage"/>
<output message="tns:F1OutputMessage"/>
</operation>
</portType>
<binding name="F1Binding" type="tns:F1PortType">
<soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
<operation name="F1">
<soap:operation soapAction="F1"/>
<input>
<soap:body parts="parameters" use="literal"/>
</input>
<output>
<soap:body parts="parameters" use="literal"/>
</output>
</operation>
</binding>
<service name="F1Service">
<documentation>Oracle Web Service</documentation>
<port name="F1Port" binding="tns:F1Binding">
<soap:address location="http://localhost:8080/orawsv/XFILES/F1"/>
</port>
</service>
</definitions>'
columns
ab xmltype path '.' ) t -
ORA-01460: unimplemented or unreasonable error & OPEN-FOR statement ...
Hi,
I have a procedure that opens a cursor which returns a result set based on a dynamic SELECT statement. The IN clause
in most cases needs to handle more than 1000 expressions. So to avoid the ORA-01785 error, I use a function to
convert the comma separated list of ids (which are unknown) into a collection which can then be used in the sub query
to process each expression or id. I assumed that the maximum string length I could use for these list of ids was
32767, i.e. VARCHAR2. But f I attempt to open the cursor with a list of ids where the string length is greater than 4000 bytes , the cursor is invalid
and it seems to throw the following Oracle error:
ORA-01460: unimplemented or unreasonable conversion ...
Note that anything less than 4000 bytes is fine. I have attached some of the code below and would appreciate if anyone
could tell me what im doing wrong! For example, can a varchar2 variable greater than 4000 bytes not be used when
executing dynamic SQL in the context of the OPEN-FOR statement?
-- Create type to hold collection of identifiers.
CREATE OR REPLACE TYPE IDList IS TABLE OF NUMBER;
-- Function which converts a string of comma separated list of identifiers
-- into a collection.
CREATE OR REPLACE FUNCTION fnConvertIDListToCollection(
varList IN VARCHAR2,
varDelimiter IN VARCHAR2 DEFAULT ',')
RETURN IDList
IS
varString long := varList || varDelimiter;
varPos pls_integer;
varData IDList := IDList();
BEGIN
LOOP
varPos := instr(varString, varDelimiter);
EXIT WHEN (nvl(varPos, 0) = 0);
varData.extend;
varData(varData.count) := trim(substr(varString, 1, varPos - 1));
varString := substr(varString, varPos + 1);
END LOOP;
RETURN (varData);
END;
CREATE OR REPLACE PROCEDURE MyTestProc
myCursor OUT SYS_REFCURSOR
AS
varListOfIds VARCHAR2(32767);
BEGIN
-- Hard coding this for now but this will be an incoming parameter containing a list
-- of unknown ids, separated with commas.
varListOfIds := '1,2 .. , 5000';
OPEN myCursor FOR
'SELECT DISTINCT val1, val2, val3
FROM TABLEA
WHERE val1 IN (select * from table(cast(fnConvertIDListToCollection(:ListOfIds) as IDList)))' USING varListOfIds;
END;
/APC,
Many thanks for the suggestion and yes I could possibly implement an alternative solution, certainly for some cases but I need to investigate further for others. I'm migrating some SQL Server logic over to Oracle and that was simply the approach taken on that platform.
Could I trouble you with one further question as a newbie to all of this. I hinted in my last response that I was somewhat confused over the limits with the use of varchar2 variables in PL/SQL. If I were building up a piece of dynamic SQL (e.g. SELECT statement including a WHERE clause) using an incoming VARCHAR2 parameter for the WHERE clause, can this parameter contain more than 4000 bytes if necessary. I assumed it could be as big as 32767 bytes but an earlier response suggested a maximum of 4000 bytes. Really sorry for probably a fairly basic Oracle question but it would be very appreciated if you could explain this to me.
Again, many thanks. -
Hi,
I have the below cursor 1 which is working already.For my requirement i want to use bind variable like second cursor.But its telling Bind Variable "p_col_list" is NOT DECLARED.Please any onehelp me on this.
How to use bind variable Here.
Cursor1:
DECLARE
emp_cv sys_refcursor;
iid NUMBER := 1;
i_sql varchar2(100);
p_col_list varchar2(2000) := 'aaa,bbb,ccc,ddd';
BEGIN
i_sql := 'select '''||REPLACE(p_col_list, ',', ''',''')||''' from dual '||CHR(10) ;
dbms_output.put_line(i_sql);
OPEN emp_cv FOR i_sql ;
END;
Cursor2:
DECLARE
emp_cv sys_refcursor;
iid NUMBER := 1;
i_sql varchar2(100);
p_col_list varchar2(2000) := 'aaa,bbb,ccc,ddd';
BEGIN
i_sql := 'select '''||REPLACE(:p_col_list, ',', ''',''')||''' from dual '||CHR(10) ;
dbms_output.put_line(i_sql);
OPEN emp_cv FOR i_sql using p_col_list;
END;hello,
the reports parameterform capabilities are limited. if you want
to create sophisticated parameterforms, you should do that with
oracle forms or html forms.
regards,
the oracle reports team --pw -
Query taking too long when using bind variable
Hi All,
There is a query in our prod DB which runs very slow (approx 2 hours) when it uses Bind Variables (using JDBC thin client), and when i try passing the variable using TOAD/SQL developer it runs fine.
Explain Plan for running Query
SELECT STATEMENT ALL_ROWSCost: 146 Bytes: 379 Cardinality: 1
21 SORT ORDER BY Cost: 146 Bytes: 379 Cardinality: 1
20 NESTED LOOPS Cost: 145 Bytes: 379 Cardinality: 1
17 HASH JOIN Cost: 22 Bytes: 42,558 Cardinality: 123
15 MERGE JOIN CARTESIAN Cost: 15 Bytes: 8,910 Cardinality: 27
12 FILTER
11 NESTED LOOPS OUTER Cost: 9 Bytes: 316 Cardinality: 1
8 NESTED LOOPS OUTER Cost: 8 Bytes: 290 Cardinality: 1
5 NESTED LOOPS Cost: 6 Bytes: 256 Cardinality: 1
2 TABLE ACCESS BY GLOBAL INDEX ROWID TABLE GDP.GDP_FX_DEALS_INCREMENTOR Cost: 4 Bytes: 28 Cardinality: 1 Partition #: 9 Partition access computed by row location
1 INDEX RANGE SCAN INDEX GDP.GDP_FX_DEALS_INC_IDX_01 Cost: 3 Cardinality: 1
4 TABLE ACCESS BY INDEX ROWID TABLE GDP.GDP_FX_DEALS Cost: 2 Bytes: 228 Cardinality: 1
3 INDEX UNIQUE SCAN INDEX (UNIQUE) GDP.GDP_FX_DEALS_KEY Cost: 1 Cardinality: 1
7 TABLE ACCESS BY INDEX ROWID TABLE GDP.GDP_FX_DEALS Cost: 2 Bytes: 34 Cardinality: 1
6 INDEX UNIQUE SCAN INDEX (UNIQUE) GDP.GDP_FX_DEALS_KEY Cost: 1 Cardinality: 1
10 TABLE ACCESS BY INDEX ROWID TABLE GDP.GDP_COUNTERPARTIES Cost: 1 Bytes: 26 Cardinality: 1
9 INDEX UNIQUE SCAN INDEX (UNIQUE) GDP.PK_CPTY Cost: 0 Cardinality: 1
14 BUFFER SORT Cost: 14 Bytes: 448 Cardinality: 32
13 TABLE ACCESS FULL TABLE GDP.GDP_CITIES Cost: 6 Bytes: 448 Cardinality: 32
16 TABLE ACCESS FULL TABLE GDP.GDP_AREAS Cost: 6 Bytes: 2,304 Cardinality: 144
19 TABLE ACCESS BY INDEX ROWID TABLE GDP.GDP_PORTFOLIOS Cost: 1 Bytes: 33 Cardinality: 1
18 INDEX UNIQUE SCAN INDEX (UNIQUE) GDP.PORTFOLIOS_KEY Cost: 0 Cardinality: 1
Explain Plan for Slow Query
Plan
SELECT STATEMENT ALL_ROWSCost: 11,526,226 Bytes: 119,281,912 Cardinality: 314,728
21 SORT ORDER BY Cost: 11,526,226 Bytes: 119,281,912 Cardinality: 314,728
20 HASH JOIN Cost: 11,510,350 Bytes: 119,281,912 Cardinality: 314,728
2 TABLE ACCESS BY INDEX ROWID TABLE GDP.GDP_PORTFOLIOS Cost: 1,741 Bytes: 177,540 Cardinality: 5,380
1 INDEX FULL SCAN INDEX (UNIQUE) GDP.PORTFOLIOS_KEY Cost: 14 Cardinality: 5,380
19 HASH JOIN Cost: 11,507,479 Bytes: 87,932,495,360 Cardinality: 254,140,160
3 TABLE ACCESS FULL TABLE GDP.GDP_AREAS Cost: 6 Bytes: 2,304 Cardinality: 144
18 MERGE JOIN CARTESIAN Cost: 11,506,343 Bytes: 18,602,733,930 Cardinality: 56,371,921
15 FILTER
14 HASH JOIN RIGHT OUTER Cost: 3,930,405 Bytes: 556,672,868 Cardinality: 1,761,623
5 TABLE ACCESS BY INDEX ROWID TABLE GDP.GDP_COUNTERPARTIES Cost: 6,763 Bytes: 892,580 Cardinality: 34,330
4 INDEX FULL SCAN INDEX (UNIQUE) GDP.PK_CPTY Cost: 63 Cardinality: 34,330
13 HASH JOIN OUTER Cost: 3,923,634 Bytes: 510,870,670 Cardinality: 1,761,623
10 HASH JOIN Cost: 2,096,894 Bytes: 450,975,488 Cardinality: 1,761,623
7 TABLE ACCESS BY GLOBAL INDEX ROWID TABLE GDP.GDP_FX_DEALS_INCREMENTOR Cost: 2,763 Bytes: 52,083,248 Cardinality: 1,860,116 Partition #: 14 Partition access computed by row location
6 INDEX RANGE SCAN INDEX GDP.GDP_FX_DEALS_INC_IDX_01 Cost: 480 Cardinality: 334,821
9 TABLE ACCESS BY INDEX ROWID TABLE GDP.GDP_FX_DEALS Cost: 1,734,205 Bytes: 8,320,076,820 Cardinality: 36,491,565
8 INDEX FULL SCAN INDEX (UNIQUE) GDP.GDP_FX_DEALS_KEY Cost: 104,335 Cardinality: 39,200,838
12 TABLE ACCESS BY INDEX ROWID TABLE GDP.GDP_FX_DEALS Cost: 1,733,836 Bytes: 1,331,145,696 Cardinality: 39,151,344
11 INDEX FULL SCAN INDEX (UNIQUE) GDP.GDP_FX_DEALS_KEY Cost: 104,335 Cardinality: 39,200,838
17 BUFFER SORT Cost: 11,499,580 Bytes: 448 Cardinality: 32
16 TABLE ACCESS FULL TABLE GDP.GDP_CITIES Cost: 4 Bytes: 448 Cardinality: 32
How can I avoid that.
ThanksHello
Could you reformat your execution plans because they aren't particularly readable. The forums allow you to preserve the formatting of code or output by putting the symbol {noformat}{noformat} before and after the section of text you want to preserve formatting for.
If you write
{noformat}select * from v$version
{noformat}
it will be displayed asselect * from v$version
So can you run this above statement and post the output here so we know the full oracle version you are working with? And finally, it would be really helpful to see the query you are running. When you say it runs fine in Toad, is that when you replace the bind variables with the values or are you also using bind variables in Toad?
Cheers
David -
Good day to all,
I have a question related to VB.
Is there any way to use Bind variables in VB, or any other way, that my same query will not parse every time in Oracle just for a little difference in variable field..
Regards
AnsYou'd use OracleParameters. I dont do VB.NET, but here's a c# example you should be able to easily convert.
Hope it helps,
Greg
using (OracleConnection con = new OracleConnection("user id=scott;password=tiger;data source=orcl"))
con.Open();
using (OracleCommand cmd = new OracleCommand("", con))
cmd.CommandText = "insert into emp (empno, ename) values (:e1, :e2)";
cmd.Parameters.Add(new OracleParameter("e1",OracleDbType.Int32,0,1234,ParameterDirection.Input));
cmd.Parameters.Add(new OracleParameter("e2",OracleDbType.Varchar2,4,"KING",ParameterDirection.Input));
cmd.ExecuteNonQuery();
Console.WriteLine("done");
}
Maybe you are looking for
-
ADC Studio Display 17" USB not working
Hi, I hope someone can help. I have a 17" Apple Studio Display that connects via ADC left over from my old Powermac G4. I recently bought the new Mac Mini (Unibody) and an Apple DVI to ADC Display Adapter to use with the HDMI to DVI Adapter to connec
-
Hi Guru's, I am newbie in BW security, Please provide step by step documentation for creation of roles and profiles and assigning these roles to users.Basically giving BW access to new users is also urgent requirement for me. Any help will be highly
-
IPhoto 09 8.1.1 update: no longer able to sync photos with AppleTV
I have Itunes 9.0.2 (25) and just updated iPhoto 8.1.1 (419) and when I try to synch with my AppleTv 3.0.1 I get an error -50 trying to sync the photos. If I unselect photo sync it will work sync just fine. Also I am now unable to select individual e
-
Problems connecting RAZR via Bluetooth
Hey guys... I have an iBook G4 1.33MHz running 10.4.7 but, for some reason, my RAZR will not pair with my iBook. It just will flat out not discover it. I go to my phone, click on discoverable, and let that run. Meahwhile, I run the wizzard to connect
-
Help!! with my if statements
I am using the following code on a JSP page, it evaluates the nulls just fine, but for some reason it does not seem to evaluate my strings to see if they are the same which gives me several duplicate lines.... <UL> <% if(strTemp1=="") {%> <L