Executing a PL/SQL block (using Toplink)
I have a scenario where I need to execute some fairly complex PL/SQL blocks. As a tester, I am attempting to execute the following simple block:
declare val NUMBER := 1; begin val := 2; end;
Both wrapping this in an SQLCall, or a DataReadQuery give the following exception. What is the best way to execute a PL/SQL block using Toplink?
Local Exception Stack:
Exception [TOPLINK-4002] (Oracle TopLink - 10g Release 3 (10.1.3.0.0) (Build 060118)): oracle.toplink.exceptions.DatabaseException
Internal Exception: java.sql.SQLException: ORA-00900: invalid SQL statement
Error Code: 900
Call: declare val NUMBER := 1; begin val := 2; end;
Query:DataReadQuery()
at oracle.toplink.exceptions.DatabaseException.sqlException(DatabaseException.java:290)
at oracle.toplink.internal.databaseaccess.DatabaseAccessor.basicExecuteCall(DatabaseAccessor.java:570)
at oracle.toplink.internal.databaseaccess.DatabaseAccessor.executeCall(DatabaseAccessor.java:442)
at oracle.toplink.threetier.ServerSession.executeCall(ServerSession.java:453)
at oracle.toplink.internal.queryframework.DatasourceCallQueryMechanism.executeCall(DatasourceCallQueryMechanism.java:117)
at oracle.toplink.internal.queryframework.DatasourceCallQueryMechanism.executeCall(DatasourceCallQueryMechanism.java:103)
at oracle.toplink.internal.queryframework.DatasourceCallQueryMechanism.executeSelectCall(DatasourceCallQueryMechanism.java:174)
at oracle.toplink.internal.queryframework.DatasourceCallQueryMechanism.executeSelect(DatasourceCallQueryMechanism.java:156)
at oracle.toplink.queryframework.DataReadQuery.executeNonCursor(DataReadQuery.java:118)
at oracle.toplink.queryframework.DataReadQuery.executeDatabaseQuery(DataReadQuery.java:110)
at oracle.toplink.queryframework.DatabaseQuery.execute(DatabaseQuery.java:603)
at oracle.toplink.queryframework.DataReadQuery.execute(DataReadQuery.java:96)
at oracle.toplink.publicinterface.Session.internalExecuteQuery(Session.java:2062)
at oracle.toplink.publicinterface.Session.executeQuery(Session.java:981)
at oracle.toplink.publicinterface.Session.executeQuery(Session.java:938)
Could you try the following:
Session s = ...
DataModifyQuery dmq = new DataModifyQuery();
SQLCall sqlCall = new SQLCall();
sqlCall.setQueryString(
"declare\n" +
" val NUMBER := 1;\n" +
"begin\n" +
" val := 2;\n" +
"end;");
sqlCall.setQuery(dmq);
dmq.setCall(sqlCall);
s.executeQuery(dmq);
Similar Messages
-
Accepting user input and executing a PL/SQL block using it
Hi All,
I am working on a requirement wherein I have to accept values from the user for the various arguments to be supplied to a PL/SQL block and then execute it using these values. For now, I am using the following logic:
PROMPT Enter value for the Category
ACCEPT cCategory CHAR PROMPT 'Category:'
DECLARE
cCategry CHAR(1) := '&cCategory';
BEGIN
DBMS_OUTPUT.PUT_LINE('The value of the Category as entered by you is' || cCategory);
END;
PROMPT Press y if you want to proceed with the current values, or press n if you want to re-enter the values
ACCEPT cChoice CHAR Prompt 'Enter y or n:'
DECLARE
cCategry CHAR(1) := '&cCategory';
sErrorCd VARCHAR2(256);
sErrorDsc VARCHAR2(256);
BEGIN
IF '&cChoice' = 'y'
THEN
DBMS_OUTPUT.PUT_LINE('Starting with the process to execute the stored proc');
--- schema1.package1.sp1(cCategry, sErrorCd, sErrorDsc);
--- DBMS_OUTPUT.PUT_LINE('Error Code :' || sErrorCd);
--- DBMS_OUTPUT.PUT_LINE(' Error Description :' || sErrorDsc);
ELSIF '&cChoice' = 'n'
THEN
Now I want that the proc again start executing in the loop from the 1st line i.e. PROMPT Enter value for the Category. However i see that this is not possible to do that PROMPT statements and accepting user inputs execute only on the SQL prompt and not inside a PL/SQL block.
Is there an alternate method to establish this?
Thanks in advance.Hi,
You can write a genric procedure to achive the desired output. Pass 'Y' or 'N' in the procedure.
Call that procedure in simple pl/sql block during runtime using substituton operator.
For ex
create or replace procedure p1(category_in in varchar2)
IS
BEGIN
if (category_in='Y')
then
prcdr1()
/** Write your logic here ***/
elsif(category_in='N') then
prcdr2()
/** write your logic here***/
end if;
exception
/***write the exception logic ***/
end p1;
Begin
p1('&cat');
end;Regards,
Achyut K
Edited by: Achyut K on Aug 6, 2010 5:20 AM -
Construct a Sql block using With Clause to improve the performance
I have got four diff parametrized cursor in my Pl/Sql Procedure. As the performance of the Procedure is very pathetic,so i have been asked to tune the Select statements used in those cursors.
So I am trying to use the With Clause in order to club all those four Select Statements.
I would appreciate if anybody can help me to construct the Sql Block using With Clause.
My DB version is..
Oracle Database 11g Enterprise Edition Release 11.1.0.7.0 - 64bit Production
PL/SQL Release 11.1.0.7.0 - Production
Four Diff cursors are defined below.
CURSOR all_iss (
b_batch_end_date IN TIMESTAMP,
IS
SELECT isb.*
FROM IMPLMN_STEP_BREKPN isb
, ISSUE iss
WHERE isb.issue_id = iss.issue_id
AND iss.issue_status_id = 50738
AND ewo_no IN
(SELECT TO_CHAR(wo_no)
FROM MGO_PLANT_AUDIT
WHERE dml_status = 'U' OR dml_status = 'I')
UNION ALL
SELECT isb.*
FROM IMPLMN_STEP_BREKPN isb
, ISSUE iss
WHERE isb.issue_id = iss.issue_id
AND iss.issue_status_id = 50738
AND CAST (isb.last_updt_timstm AS TIMESTAMP) >=
b_batch_end_date;
CURSOR ewo_plant ( p_ewo_no IN IMPLMN_STEP_BREKPN.ewo_no%TYPE)
IS
SELECT DISTINCT wo_no ,
plant_code
FROM MGO_PLANT
WHERE TO_CHAR(wo_no) = p_ewo_no;
CURSOR iss_ewo_plnt (
p_issue_id IN IMPLMN_STEP_BREKPN.issue_id%TYPE ,
p_ewo_no IN IMPLMN_STEP_BREKPN.EWO_NO%TYPE,
p_plnt_code IN IMPLMN_STEP_BREKPN.PLT_FACLTY_ID%TYPE)
IS
SELECT *
FROM IMPLMN_STEP_BREKPN
WHERE issue_id = p_issue_id
AND ewo_no = p_ewo_no
AND
(plt_faclty_id = p_plnt_code
OR
plt_faclty_id IS NULL);
CURSOR iss_ewo_plnt_count (
p_issue_id IN IMPLMN_STEP_BREKPN.issue_id%TYPE ,
p_ewo_no IN IMPLMN_STEP_BREKPN.EWO_NO%TYPE,
p_plnt_code IN IMPLMN_STEP_BREKPN.PLT_FACLTY_ID%TYPE)
IS
SELECT COUNT(*)
FROM IMPLMN_STEP_BREKPN
WHERE issue_id = p_issue_id
AND ewo_no = p_ewo_no
AND
(plt_faclty_id = p_plnt_code
OR
plt_faclty_id IS NULL);Not tested. Some thing like below. i just made the queries as tables and given name as a,b,c and substituted columns for the parameters used in the 2nd cursor and third cursor. Try like this.
CURSOR all_iss (
b_batch_end_date IN TIMESTAMP,
IS
select a.*,b.*,c.* from
( SELECT isb.*
FROM IMPLMN_STEP_BREKPN isb
, ISSUE iss
WHERE isb.issue_id = iss.issue_id
AND iss.issue_status_id = 50738
AND ewo_no IN
(SELECT TO_CHAR(wo_no)
FROM MGO_PLANT_AUDIT
WHERE dml_status = 'U' OR dml_status = 'I')
UNION ALL
SELECT isb.*
FROM IMPLMN_STEP_BREKPN isb
, ISSUE iss
WHERE isb.issue_id = iss.issue_id
AND iss.issue_status_id = 50738
AND CAST (isb.last_updt_timstm AS TIMESTAMP) >=
b_batch_end_date) a,
( SELECT DISTINCT wo_no ,
plant_code
FROM MGO_PLANT
WHERE TO_CHAR(wo_no) = p_ewo_no) b,
( SELECT *
FROM IMPLMN_STEP_BREKPN
WHERE issue_id = p_issue_id
AND ewo_no = p_ewo_no
plt_faclty_id IS NULL) c
where b.wo_no = c.ewo_no and
c.issue_id = a.issue_id ;
vinodh
Edited by: Vinodh2 on Jul 11, 2010 12:03 PM -
How to re-execute anonymous PL/SQL block in package definition ?
Hi all,
I implemented a package which contains procedures and an anonymous PL/SQL block.
This anonymous PL/SQL block is executed only once when the package is called.
and charge in-memory the content of table to avoid multiple SQL access each
time one procedure is called.
As my application open many sessions to the Oracle database, I would like to try
a solution to signal all sessions to reload the content of table when the content
of table is modified. The solution to stop and to restart the connection is not
acceptable.
Best regards
Sylvain> .. to avoid multiple SQL access each time one procedure is called.
As I understand your posting, this is the actual technical requirement. You want to force serialisation of PL/SQL code. Correct? (only one session at a time can run the procedure)
This feature typically used to accomplish this in o/s code is called a semaphore. PL/SQL does not specifically support semaphores. However, it supports a range of IPC (Inter Process Communication) methods - from message queues to pipes.
One of these IPC interfaces is DBMS_LOCK - which allows a unique lock to be defined and processes to manage their resource usage/execution/etc via this lock using the DBMS_LOCK API.
I've found this a pretty clean and manageable solution to enforce serialisation. Of course, it is even better not to enforce serialisation. Rather design the code to be thread safe and capable of multi-processing/parallel processing.
Personally, I would not use a table as an IPC mechanism as Oracle already provides better IPC mechanisms for PL/SQL code. As for "signalling sessions to re-load the table" - not possible as Oracle sessions cannot register callbacks to handle events. Oracle sessions are not event driven processes from a PL/SQL (application development) perspective. -
Obtaining a collection as a return from an execute immediate pl/sql block
version 10.2
I need to obtain the collection back from the execute immediate of a pl/sql block:
procedure block(owner varchar2) is
stmt long;
objecttab_coll dbms_stats.objecttab;
begin
stmt := '
begin
dbms_stats.gather_schema_stats(''' || owner || '''
,options => ''LIST AUTO''
,objlist => :objecttab_coll
end;';
execute immediate stmt returning into objecttab_coll;
-- do more stuff here
end block;I have tried this + a few variations but with no luck. In looking through the docs I do not see an example. can this be done?
Thanks
OxI dont find any need for an execute immediate here. This must be just enough.
procedure block(owner varchar2)
is
objecttab_coll dbms_stats.objecttab;
begin
dbms_stats.gather_schema_stats(ownname => owner, options => 'LIST AUTO', objlist => objecttab_coll);
-- do more stuff here
end block;Thanks,
Karthick. -
Execute anonymous PL/SQL block via JDBC - OUT parameter not available
I have a simple proc on the database:
CREATE PROCEDURE TEST(X OUT BINARY_INTEGER, Y IN VARCHAR) AS
BEGIN
X := 33;
END; I am trying to invoke it via JDBC using an anonymous PL/SQL block:
try {
Connection connection =
DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:ORCL",
"scott", "tiger");
CallableStatement stproc_stmt = connection.prepareCall(
"DECLARE\n" +
" X_TARGET BINARY_INTEGER;\n" +
" Y_TARGET VARCHAR(20) := :2;\n" +
"BEGIN\n" +
" TEST(X=>X_TARGET, Y=>Y_TARGET);\n" +
" :1 := X_TARGET;\n" +
"END;"
stproc_stmt.registerOutParameter(1, Types.NUMERIC);
stproc_stmt.setString(2, "test");
stproc_stmt.executeUpdate();
Object o = stproc_stmt.getObject(1);
catch (Exception e) {
e.printStackTrace();
} No exceptions are thrown, but the Object o does not get the value '33' - it is NULL.
Any ideas?
thanks in advance,
Mike NormanI think the issue may be in how JDBC parameter binding is being managed throughout the block's lifecycle.
The slightly-different TEST2 works:
CREATE PROCEDURE TEST2(Y IN VARCHAR, X OUT BINARY_INTEGER) AS
BEGIN
X := 33;
END;
try {
Connection connection =
DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:ORCL",
"scott", "tiger");
CallableStatement stproc_stmt = connection.prepareCall(
"DECLARE\n" +
" Y_TARGET VARCHAR(20) := :1;\n" +
" X_TARGET BINARY_INTEGER;\n" +
"BEGIN\n" +
" TEST2(Y=>Y_TARGET, X=>X_TARGET);\n" +
" :2 := X_TARGET;\n" +
"END;"
stproc_stmt.setString(1, "test");
stproc_stmt.registerOutParameter(2, Types.NUMERIC);
stproc_stmt.executeUpdate();
Object o = stproc_stmt.getObject(1);
catch (Exception e) {
e.printStackTrace();
}The order of the bind indices ':1' and ':2' are reversed in the above anonymous block - we are returning via ':2'.
I am wondering if 'under the covers' there isn't perhaps a cursor issue. When the original block is parsed and the first bind index is found to be position 2, somehow we can't go back to position 1 - a forwards-only cursor? -
Error in the pl/sql block using associative arrays
Hi
I tried the following block of code using associative arrays.
DECLARE
TYPE NumTab IS TABLE OF NUMBER INDEX BY BINARY_INTEGER;
CURSOR c1 IS SELECT empno FROM emp;
empnos NumTab;
rows NATURAL := 10;
BEGIN
OPEN c1;
FOR i in empnos.first..empnos.last LOOP
/* The following statement fetches 10 rows (or less). */
FETCH c1 BULK COLLECT INTO empnos LIMIT rows;
EXIT WHEN c1%NOTFOUND;
DBMS_OUTPUT.PUT_LINE ( empnos.next(i));
END LOOP;
CLOSE c1;
END;and the error is
DECLARE
ERROR at line 1:
ORA-06502: PL/SQL: numeric or value error
ORA-06512: at line 8could you please let me know where i'm wrong
and please guide me where we use these associative arrays.
ThanksSomething like this. Do minor modification in your code.
DECLARE
TYPE NumTab IS TABLE OF NUMBER INDEX BY BINARY_INTEGER;
CURSOR c1 IS SELECT empno FROM emp;
empnos NumTab;
rows NATURAL := 5;
BEGIN
OPEN c1;
LOOP
/* The following statement fetches 5 rows (or less). */
FETCH c1 BULK COLLECT INTO empnos LIMIT rows;
EXIT WHEN c1%NOTFOUND;
DBMS_OUTPUT.PUT_LINE ( empnos.count);
END LOOP;
CLOSE c1;
END;
/ -
Executing parameterised PL sql block
hi,
I have a procedure which takes in parameter of a table name.
In the procedure i have a variable (say rowcount).
I want the variable rowcount to have the number of records present in that
particular table (passed as a parameter).
One way of doing this is getting the count in a dummy table and then
querying it.
Is there a better way out ?
Truptiyes, use dynamic sql e.g.
execute immediate 'select count (0) from ' || table_name_parameter into tabcnt_variable; -
How to SQL intersect using Toplink expressions
I try to do this SQL intersect
SELECT part_k FROM ATTR_VALUE
where commodity_n ='dab badge' and attribute_n='Badge Width' and attribute_value_x='10'
INTERSECT
SELECT part_k FROM ATTR_VALUE
where commodity_n='dab badge' and attribute_n='Brand Logo' and attribute_value_x='Jaguar'
using the following Toplink expressions:
Expression e1 = builder.get("commodity").equal("dab badge")
.and(builder.get("attribute").equal("Badge Width"))
.and(builder.get("value").equal("10"));
Expression e2 = builder.get("commodity").equal("dab badge")
.and(builder.get("attribute").equal("Brand Logo"))
.and(builder.get("value").equal("Jagua"));
Expression myExpression = e1.and(e2);
However, this would not give me the correct result.
Any suggestions would be greatly appreicated.Right, TopLink doesn't have an Intersect operator. If it did, you might still get the same problem unless you are using a report query to return only the "part_k" value instead of an object since attribute_n cannot have a value of both 'Badge Width' and 'Brand Logo' at the same time.
You can get the part_k values or the objects from the ATTR_VALUE
table by using a report query for the second expression as a subquery to the IN clause. Something like
ReportQuery subquery = new ReportQuery(yourclass.class);
ExpressionBuilder subBuilder = subquery.getBuilder();
Expression e2 = subBuilder.get("commodity").equal("dab badge").and(subBuilder.get("attribute").equal("Brand Logo")).and(subBuilder.get("value").equal("Jagua"));
subquery.setSelectionCriteria(e2);
subquery.addAttribute("partk");
Expression myExpression = e1.and( builder.get("partk").in(subquery) );Regards,
Chris -
Execute immediate a sql block of istructions
Hello,
i need to to do something like this:
execute immediate par;
where par is a big file stored in a table that is simply a pl/sql script like this
comment on table SOMETABLE.COLUMN is 'this' ;
comment on table SOMETABLE.COLUMN2 is 'this' ;
and so on for 45 columns. when i try it say that ; is not a valid character. It works only if i put only a row in the table.
How i can put more istructions in a string to be "execute immediate"
Thanks
Edited by: user12195888 on 10-nov-2009 7.59In the example already provided be aware that if you have commands that aren't supported in PL/SQL like COMMENT this approach may not work. Here is an example that breaks the string up on the semi-colon terminator:
SQL> DROP TABLE A;
Table dropped.
SQL> DROP TABLE B;
Table dropped.
SQL> DROP TABLE C;
Table dropped.
SQL> DROP TABLE INSTRUCTION_TEST;
Table dropped.
SQL>
SQL> CREATE TABLE A (ID NUMBER);
Table created.
SQL> CREATE TABLE B (ID NUMBER);
Table created.
SQL> CREATE TABLE C (ID NUMBER);
Table created.
SQL> CREATE TABLE INSTRUCTION_TEST
2 (
3 INSTRUC VARCHAR2(4000)
4 );
Table created.
SQL>
SQL> INSERT INTO INSTRUCTION_TEST
2 VALUES
3 (
4 'COMMENT ON TABLE A IS ''Table A''; COMMENT ON TABLE B IS ''Table B''; COMMENT ON TABLE C IS ''Table C'';'
5 );
1 row created.
SQL>
SQL> DECLARE
2 BEGIN
3 FOR r IN
4 (
5 WITH instructions AS
6 (
7 SELECT ';' || INSTRUC AS INST
8 FROM INSTRUCTION_TEST
9 )
10 SELECT SUBSTR
11 (
12 INST
13 , INSTR(INST,';',1,LEVEL) + 1
14 , INSTR(INST,';',1,LEVEL+1) - INSTR(INST,';',1,LEVEL) - 1
15 ) AS INDIVIDUAL_STATEMENT
16 FROM instructions
17 CONNECT BY LEVEL <= LENGTH(REGEXP_REPLACE(INST,'[^;]','')) - 1
18 )
19 LOOP
20 --DBMS_OUTPUT.PUT_LINE(r.INDIVIDUAL_STATEMENT);
21 EXECUTE IMMEDIATE r.INDIVIDUAL_STATEMENT;
22 END LOOP;
23 END;
24 /
PL/SQL procedure successfully completed.
SQL> SELECT * FROM ALL_TAB_COMMENTS WHERE TABLE_NAME IN ('A','B','C');
OWNER TABLE_NAME TABLE_TYPE COMMENTS
TEST_USER C TABLE Table C
TEST_USER B TABLE Table B
TEST_USER A TABLE Table AHTH! -
hi,
i created a pl/sql block using ed <filename.sql> and tried to execut it useing @<filena.sql> or run <filename.sql>.for the 2nd command the message i got is "nothing
in buffer to run" and for the 1st comm i got nothing. i dint event get prompt.
i am totally new to oracle. please solve my probs.
thanqTo execute the PL/SQL block make sure that you have a "/" at the end of your PL/SQL block and then an <Return character>. Once you have that then you can type C:\..\..\@filename.sql. If you don't put the "/" and "return character" it in your script then after typing C:\..\..\@filename.sql press enter and then type in "/" and then press enter again.
Soji. -
Execute Dynamic SQL statement using procedure builder
i want to execute a dynamic SQL statment using procedure builder not using forms
because my statement depending on a variable table name
i know that i can do that from forms using
FORMS_DDL('SQL_STAT');
but i wanna to use the procedure builder
which function i should use and how?
please explain in example if you don't mind.
thanksHi,
You can very well use DBMS_SQL Package supplied by Oracle for doing this.
Search for DBMS_SQL in OTN. You will get all info regarding this.
Regards.
<BLOCKQUOTE><font size="1" face="Verdana, Arial, Helvetica">quote:</font><HR>Originally posted by itslul:
i want to execute a dynamic SQL statment using procedure builder not using forms
because my statement depending on a variable table name
i know that i can do that from forms using
FORMS_DDL('SQL_STAT');
but i wanna to use the procedure builder
which function i should use and how?
please explain in example if you don't mind.
thanks<HR></BLOCKQUOTE>
null -
Error while invoking webservice using UTL_HTTP from PL/SQL Block
Hi All,
I am invoking a webservice (SOAP Request) from a PL/SQL block using UTL_HTTP package.
I am able to send the complete request and am getting the required instance on the BPEL Console, but the process is erroring out while getting response back.
and the PL/SQL Block is ending in error mentioned below:
ERROR at line 1:
ORA-29266: end-of-body reached
ORA-06512: at "SYS.UTL_HTTP", line 1321
ORA-06512: at "APPS.CSM_BPEL_TEST_PKG", line 34
ORA-06512: at line 1
Package is completing successfully if i test in local DB and local BPEL.
But giving above error in client's.
Can anyone let me know what is the cause of this.
Thanks in advanceI got it working by making process Synchronous.
But with asynchronous process it is still same error.
Thanks... -
How to execute pl/sql block from a file
hi all,
can anybody tell me how to execute a pl/sql block from a file.it wont contain any procedures.it is of the form
--begin
--declare
--end;
ThanxHere is the file
File is stored in C Drive (Windows Environment)
declare
x number;
begin
select 1 into x from dual;
dbms_output.put_line(x);
end;
SQL> @c:\t.sql;
1
PL/SQL procedure successfully completed.Are you facing any issues?
Regards,
Bhushan -
DDL in pl/sql block???
Hi,
begin
create table sample_test ( x number);
end;
gives an error, but
begin
execute immediate 'create table sample_test(x number)';
end
very much works, is there any specific reason to why the first way of doing a DDL statement is restricted or avoided???
cheereHi,
begin
create table sample_test ( x number);
end;
you can not issue DDL like above in a PL/SQL Block, hence error
gives an error, but
begin
execute immediate 'create table sample_test(x
(x number)';
end
You Issued DDL in PL/SQL Block using Native Dynamic SQL, hence worked !!
Message was edited by:
biswabijay
Maybe you are looking for
-
hi all, I am working o adobe forms, i have to print a paragraph text which has both dymanic and static elemets in it. By putting all the text in a static text it works fine, but allignment does not happen properly. do we have something like &.....&
-
Application has a problem error message.
Application has a problem. Diagnostic file C:\Program Files\SAP\SAP Business One\Log\SAP Business One_20080924115328.dmp was created. Please contact support and attach diagnostic file. I get this error when I try to u201Cview user defined fieldsu201D
-
Billing type is not populating table TVARVC
Hi Expert My billing type is not populating the TVARVC table can any body explain whats needs to be done. Regards Sanjay
-
Hi i like to know how can i understand the output of the autotrace .. my current sql explain plan is Execution Plan Plan hash value: 2038802176 | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | | 0 | SELECT STATEMENT | | 9 | 1026 | 332 (3)
-
Trying to update 10.4.11
I am trying to update 10.4.11. I need to get to 10.4.3. Installer will not let me install on to my hardrive. What can I do? I have tried 10.4.2 as well, same error? It says volume doesn't meet requirements for this update.