get dynamic SQL CLOB in PLSQL?
Hello
I need to call a function to get a clob in return, but the name of this function is dynamic. This means that I get a user input and depends on the name of the function to call.
Problem is that this feature is also DML, so I can't do
EXECUTE IMMEDIATE 'select function_name_'||version||' from dual'
And I don't like the idea of
if .. then return function_nam_1 elsif .. then return function_nam_2 elsif .. then return function_nam_3 elsif .. then ...
So I think to use the DBMS_SQL package.
But what this part would look like exactly?
create or replace function execute_fkn_test(version number, p_input varchar2) return CLOB is -- does the SQL string need a change? v_sql varchar2(1000) := ' declare v_return_clob clob; begin v_return_clob:= test_function_'||version||'(p_param => '||p_input ||' ); end;'; v_dummy INTEGER; v_result CLOB; BEGIN EXECUTE IMMEDIATE v_sql; -- what to write here to get v_return_clob from dynamic SQL into v_result? return v_result; END;
Good bye
DPT
I don't know the reason for this design, but to answer your question from the academic point of view: you must use bind variables, like this:
create or replace function execute_fkn_test (version number, p_input varchar2) return clob
is
v_sql varchar2 (1000): = ' START: 1: = test_function_' | TO_CHAR (version) | "(p_param =>: 2); END;';
CLOB v_result;
Start
execute immediate v_sql using the v_result, in p_input
Return v_result;
end;
Tags: Database
Similar Questions
-
GETTING AN ERROR - slider 'P_REFCUR' cannot be used in the OPEN dynamic SQL stat
DECLARE
create or replace procedure partial_single (p_fileid in NUMBER, p_filename IN VARCHAR2 (2000), p_temptablename IN VARCHAR2 (2000), p_temppartialtablename IN VARCHAR2 (2000), p_retval ON the NUMBER)
--)
p_fileid NUMBER;
p_filename VARCHAR2 (2000);
p_temptablename VARCHAR2 (2000);
p_temppartialtablename VARCHAR2 (2000);
p_retval NUMBER;
p_refcur types_pkg.return_cur;
v_strquery varchar2 (4000);
BEGIN
p_fileid: = 5080;
p_filename: = "TAGSUR1HM2011013111160838654.000019265";
-p_temptablename: = "TEMP_RECORDS_MED_0004";
p_temptablename: = 'TEMP_RECORDS_MED_DATE ';
p_temppartialtablename: = 'TEMP_MED_PARTIAL_RECORDS_0002 ';
p_retval: = 0;
v_strquery: = 'SELECT imsi, connectedcallingnumber, callstart MIN (calleventstarttimestamp), SUM (calleventduration), MAX (sequence_number) sequencenumber, msisdn, max (callreleasetime) callreleasetime period';
v_strquery: = v_strquery | ' A ' | p_temppartialtablename | ' GROUP BY connectedcallingnumber, imsi, msisdn';
OPEN p_refcur - GETTING AN ERROR - slider 'P_REFCUR' cannot be used in a dynamic OPEN SQL statement
FOR v_strquery;
FOR CC IN (SELECT imsi,
connectedcallingnumber,
Callstart MIN (calleventstarttimestamp),
Duration of the SUM (calleventduration),
SequenceNumber MAX (sequence_number),
MSISDN,
Max (callreleasetime) callreleasetime
OF TEMP_MED_PARTIAL_RECORDS_0002
GROUP BY connectedcallingnumber, imsi, msisdn)
LOOP
UPDATE TEMP_RECORDS_MED_DATE
SET calleventstarttimestamp = cc.callstart,
calleventduration = calleventduration + cc.duration
WHERE connectedcallingnumber = cc.connectedcallingnumber
AND imsi = cc.imsi
AND sequencenumber = cc.sequencenumber + 1
AND msisdn = cc.msisdn
AND calleventstarttimestamp = cc.callreleasetime;
IF SQL % ROWCOUNT > 0
THEN
UPDATE TEMP_MED_PARTIAL_RECORDS_0002
SET isprocessed = 1
WHERE connectedcallingnumber = cc.connectedcallingnumber
AND imsi = cc.imsi
AND msisdn = cc.msisdn;
- AND callreleasetime = cc.callreleasetime;
ON THE OTHER
UPDATE TEMP_MED_PARTIAL_RECORDS_0002
SET calleventduration = calleventduration + cc.duration
IMSI WHERE = cc.imsi
AND msisdn = cc.msisdn
AND callreleasetime = cc.callreleasetime
AND calleventduration! = cc.duration;
END IF;
END LOOP;
REMOVE FROM TEMP_MED_PARTIAL_RECORDS_0002
WHERE isprocessed = 1;
p_retval: = 0;
-VALIDATION;
/ * EXCEPTION
WHILE OTHERS
THEN
-RESTORATION;
p_retval: = 1;
p3_errorlog ("partial" p_fileid, SQLERRM, |) ':' || p_filename);
COMMIT;
*/
END;Is - what your refcursor has a return type? In this case you can not open it with dynamic SQL. Change the Refcursor as a weakly typed cursor and give it a try.
-
How to get sql % number of dynamic sql code lines
Hello
In this procedure I'm inserting and updating using dynamic sql. Now I want to go back two more PARAMETERS, the parameter should be back the number of lines inserted and how updated by stmtas of UPDATE as well as an INSERT. I'm not able to do can help you on that?
CREATE OR REPLACE PROCEDURE Sp_Array_Test( PV_TGT_NAME IN VARCHAR2, PV_SRC_NAME IN VARCHAR2, PV_PK_COLS IN VARCHAR2, PN_ERR_CD OUT NUMBER, PN_ERR_MSG OUT VARCHAR2) AS TYPE ARR_TAB IS TABLE OF VARCHAR2(4000) INDEX BY BINARY_INTEGER; --UTL_FP UTL_FILE.FILE_TYPE; LV_AN_ BLOCK VARCHAR2(32767); LN_CUR BINARY_INTEGER := DBMS_SQL.OPEN_CURSOR; LN_DESC DBMS_SQL.DESC_TAB; LN_COL_CNT PLS_INTEGER := 0; LV_SEL_UPD_STMT VARCHAR2(4000); LV_SEL_INS_STMT VARCHAR2(4000); ARR_INDX NUMBER := 1; LV_DATA_TYPE VARCHAR2(8); LN_FIND_FLAG NUMBER := 0; LN_TAB ARR_TAB; LV_COLS_ARR ARR_TAB; LV_ERR_MSG VARCHAR2(500); --PROCEDURE FILE_WRITE ( FH_IN IN UTL_FILE.FILE_TYPE, -- STRING_IN IN VARCHAR2 ) IS --BEGIN -- UTL_FILE.PUT_LINE(FH_IN,STRING_IN); -- LV_AN_BLOCK := LV_AN_BLOCK||STRING_IN; --EXCEPTION -- WHEN OTHERS THEN -- RAISE; --END FILE_WRITE; BEGIN -- UTL_FP := UTL_FILE.FOPEN('TEST_DIR', 'TEST.sql', 'W'); LV_SEL_UPD_STMT := 'SELECT A.'||REPLACE(PV_PK_COLS,',','||A.')||' PK_COLS , A.* , B.ROWID FROM '||PV_SRC_NAME||' A, '||PV_TGT_NAME||' B WHERE '; LV_SEL_INS_STMT := 'SELECT A.* FROM '||PV_SRC_NAME||' A WHERE NOT EXISTS (SELECT ''1'' FROM '||PV_TGT_NAME||' B WHERE '; LN_TAB(ARR_INDX) := 'DECLARE '; ARR_INDX := ARR_INDX + 1; LN_TAB(ARR_INDX) := 'CURSOR CUR_VIEW_UPD IS '||LV_SEL_UPD_STMT ; ARR_INDX := ARR_INDX + 1; SELECT SUBSTR(COLS,DECODE(RN,1,1,INSTR(COLS,',',1,RN-1)+1),DECODE(RN,1,INSTR(COLS,',',1,RN)-1,INSTR(COLS,',',1,RN)-INSTR(COLS,',',1,RN-1)-1)) BULK COLLECT INTO LV_COLS_ARR FROM ( SELECT RN, PV_PK_COLS||',' COLS FROM (SELECT ROWNUM RN FROM ALL_OBJECTS WHERE ROWNUM <= LENGTH(PV_PK_COLS)- LENGTH(REPLACE(PV_PK_COLS,','))+1)) ; FOR K IN 1 .. LV_COLS_ARR.COUNT LOOP LV_SEL_UPD_STMT := LV_SEL_UPD_STMT||' A.'||LV_COLS_ARR(K)||' = '; LN_TAB(ARR_INDX) := ' A.'||LV_COLS_ARR(K)||' = '; LV_SEL_UPD_STMT := LV_SEL_UPD_STMT||' B.'||LV_COLS_ARR(K) ||CASE WHEN K = LV_COLS_ARR.COUNT THEN NULL ELSE ' AND ' END; LN_TAB(ARR_INDX) := LN_TAB(ARR_INDX)||' B.'||LV_COLS_ARR(K) ||CASE WHEN K = LV_COLS_ARR.COUNT THEN ' ;' ELSE ' AND ' END; ARR_INDX := ARR_INDX + 1; END LOOP; LN_TAB(ARR_INDX) := 'CURSOR CUR_VIEW_INS IS '||LV_SEL_INS_STMT ; ARR_INDX := ARR_INDX + 1; FOR K IN 1 .. LV_COLS_ARR.COUNT LOOP LV_SEL_INS_STMT := LV_SEL_INS_STMT||' A.'||LV_COLS_ARR(K)||' = '; LN_TAB(ARR_INDX) := ' A.'||LV_COLS_ARR(K)||' = '; LV_SEL_INS_STMT := LV_SEL_INS_STMT||' B.'||LV_COLS_ARR(K) ||CASE WHEN K = LV_COLS_ARR.COUNT THEN NULL ELSE ' AND ' END; LN_TAB(ARR_INDX) := LN_TAB(ARR_INDX)||' B.'||LV_COLS_ARR(K) ||CASE WHEN K = LV_COLS_ARR.COUNT THEN ' );' ELSE ' AND ' END; ARR_INDX := ARR_INDX + 1; END LOOP; LV_ERR_MSG := 'WHILE PARSING SELECT STATEMENT -- '||LV_SEL_UPD_STMT; DBMS_SQL.PARSE(LN_CUR, LV_SEL_UPD_STMT, DBMS_SQL.NATIVE); LV_ERR_MSG := 'WHILE DESCRIBING SELECT STATEMENT -- '||LV_SEL_UPD_STMT; DBMS_SQL.DESCRIBE_COLUMNS(LN_CUR, LN_COL_CNT, LN_DESC); FOR i IN LN_DESC.FIRST .. LN_DESC.LAST LOOP IF LN_DESC(i).col_type = 2 THEN LV_DATA_TYPE := 'NUMBER'; ELSIF LN_DESC(i).col_type = 12 THEN LV_DATA_TYPE := 'DATE'; ELSE LV_DATA_TYPE := 'VARCHAR2'; END IF; LN_TAB(ARR_INDX) := ' T_'||LN_DESC(i).col_name||' DBMS_SQL.'||LV_DATA_TYPE||'_TABLE;'; ARR_INDX := ARR_INDX + 1; END LOOP; LN_TAB(ARR_INDX) := 'BEGIN '; ARR_INDX := ARR_INDX + 1; LN_TAB(ARR_INDX) := ' EXECUTE IMMEDIATE ''ALTER SESSION SET NLS_DATE_FORMAT = ''''DD-MON-YYYY HH24:MI:SS'''''';'; ARR_INDX := ARR_INDX + 1; LN_TAB(ARR_INDX) := ' OPEN CUR_VIEW_UPD;'; ARR_INDX := ARR_INDX + 1; LN_TAB(ARR_INDX) := ' LOOP'; ARR_INDX := ARR_INDX + 1; LN_TAB(ARR_INDX) := ' FETCH CUR_VIEW_UPD BULK COLLECT INTO T_'||LN_DESC(LN_DESC.FIRST).col_name||','; ARR_INDX := ARR_INDX + 1; FOR i IN LN_DESC.FIRST + 1 .. LN_DESC.LAST - 1 LOOP LN_TAB(ARR_INDX) := ' T_'||LN_DESC(i).col_name||','; ARR_INDX := ARR_INDX + 1; END LOOP; LN_TAB(ARR_INDX) := ' T_'||LN_DESC(LN_DESC.LAST).col_name||' LIMIT 500 ;'; ARR_INDX := ARR_INDX + 1; LN_TAB(ARR_INDX) := ' FORALL I IN 1 .. '||'T_'||LN_DESC(LN_DESC.LAST).col_name||'.COUNT '; ARR_INDX := ARR_INDX + 1; LN_TAB(ARR_INDX) := ' UPDATE '||PV_TGT_NAME||' SET '; ARR_INDX := ARR_INDX + 1; LN_FIND_FLAG := 0; FOR I IN LN_DESC.FIRST + 1 .. LN_DESC.LAST-1 LOOP FOR K IN 1 .. LV_COLS_ARR.COUNT LOOP LN_FIND_FLAG := 0; IF LN_DESC(I).COL_NAME = LV_COLS_ARR(K) THEN LN_FIND_FLAG := 1; EXIT; END IF; END LOOP; IF LN_FIND_FLAG = 0 THEN LN_TAB(ARR_INDX) := ' '||LN_DESC(i).col_name||' = '||'T_'||LN_DESC(i).col_name||'(I)'||CASE WHEN I = LN_DESC.LAST-1 THEN ' WHERE ' ELSE ',' END; ARR_INDX := ARR_INDX + 1; END IF ; END LOOP; LN_TAB(ARR_INDX) := ' ROWID = '||'T_'||LN_DESC(LN_DESC.LAST).col_name||'(I) ;'; ARR_INDX := ARR_INDX + 1; LN_TAB(ARR_INDX) := ' COMMIT;'; ARR_INDX := ARR_INDX + 1; LN_TAB(ARR_INDX) := ' EXIT WHEN CUR_VIEW_UPD%NOTFOUND;'; ARR_INDX := ARR_INDX + 1; LN_TAB(ARR_INDX) := ' END LOOP;'; ARR_INDX := ARR_INDX + 1; LN_TAB(ARR_INDX) := ' CLOSE CUR_VIEW_UPD;'; ARR_INDX := ARR_INDX + 1; LN_TAB(ARR_INDX) := ' COMMIT;'; ARR_INDX := ARR_INDX + 1; LN_TAB(ARR_INDX) := ' OPEN CUR_VIEW_INS;'; ARR_INDX := ARR_INDX + 1; LN_TAB(ARR_INDX) := ' LOOP'; ARR_INDX := ARR_INDX + 1; LN_TAB(ARR_INDX) := ' FETCH CUR_VIEW_INS BULK COLLECT INTO T_'||LN_DESC(LN_DESC.FIRST+1).col_name||','; ARR_INDX := ARR_INDX + 1; FOR i IN LN_DESC.FIRST + 2 .. LN_DESC.LAST - 2 LOOP LN_TAB(ARR_INDX) := ' T_'||LN_DESC(i).col_name||','; ARR_INDX := ARR_INDX + 1; END LOOP; LN_TAB(ARR_INDX) := ' T_'||LN_DESC(LN_DESC.LAST-1).col_name||' LIMIT 500 ;'; ARR_INDX := ARR_INDX + 1; LN_TAB(ARR_INDX) := ' FORALL J IN 1 .. '||'T_'||LN_DESC(LN_DESC.FIRST + 1).col_name||'.COUNT '; ARR_INDX := ARR_INDX + 1; LN_TAB(ARR_INDX) := ' INSERT INTO '||PV_TGT_NAME||' ('; ARR_INDX := ARR_INDX + 1; FOR i IN LN_DESC.FIRST + 1 .. LN_DESC.LAST - 1 LOOP LN_TAB(ARR_INDX) := ' '||LN_DESC(i).col_name||CASE WHEN I = LN_DESC.LAST - 1 THEN ' )' ELSE ',' END ; ARR_INDX := ARR_INDX + 1; END LOOP; FOR i IN LN_DESC.FIRST + 1 .. LN_DESC.LAST - 1 LOOP LN_TAB(ARR_INDX) := CASE WHEN I = LN_DESC.FIRST + 1 THEN 'VALUES (' ELSE NULL END ||' T_'||LN_DESC(i).col_name||'(J)'||CASE WHEN I = LN_DESC.LAST - 1 THEN ' ) ;' ELSE ',' END ; ARR_INDX := ARR_INDX + 1; END LOOP; LN_TAB(ARR_INDX) := ' COMMIT;'; ARR_INDX := ARR_INDX + 1; LN_TAB(ARR_INDX) := ' EXIT WHEN CUR_VIEW_INS%NOTFOUND;'; ARR_INDX := ARR_INDX + 1; LN_TAB(ARR_INDX) := ' END LOOP;'; ARR_INDX := ARR_INDX + 1; LN_TAB(ARR_INDX) := ' CLOSE CUR_VIEW_INS;'; ARR_INDX := ARR_INDX + 1; LN_TAB(ARR_INDX) := ' COMMIT;'; ARR_INDX := ARR_INDX + 1; LN_TAB(ARR_INDX) := 'END ;'; ARR_INDX := ARR_INDX + 1; FOR J IN 1 .. LN_TAB.COUNT LOOP -- DBMS_OUTPUT.PUT_LINE( LN_TAB(J)); -- FILE_WRITE(UTL_FP,LN_TAB(J)); LV_AN_BLOCK := LV_AN_BLOCK||LN_TAB(J); END LOOP; -- UTL_FILE.FCLOSE(UTL_FP); EXECUTE IMMEDIATE LV_AN_BLOCK; PN_ERR_CD := 0; PN_ERR_MSG := 'Successful Completion'; EXCEPTION WHEN OTHERS THEN PN_ERR_CD := SQLCODE; PN_ERR_MSG := LV_ERR_MSG||' -- '||SQLERRM ; END; /
Thank you all for your answers. I agree with you all. I have manged this time by adding variable bind, then run it immediately ON aid. I don't know how it's going to be training.
From now on my side no problem I don't thank you.
-
Difference between static &; dynamic sql
Hello
It is my first question in OTN.
I have a pl/sql procedure with no insert statements.
Insert into table values...
If I turn all these insert statements in dynamic sql, my procedure will give more effective? (execution)
Please help me.
Thanks in adv
Friend
Hello
8b00c42d-7716-467e-BCEF-c756fd9599e2 wrote:
Hello
It is my first question in OTN.
Welcome to the Forum!
To get the most out of this Forum, see the FAQ in the Forum: Re: 2. How can I ask a question on the forums?
For all performance issues, see also this Forum FAQ page: Re: 3. how to improve the performance of my query? / my query is slow.
I have a pl/sql procedure with no insert statements.
Insert into table values...
If I turn all these insert statements in dynamic sql, my procedure will give more effective? (execution)
Probably not. Dynamic SQL is generally less effective than static SQL, as well as being more difficult to code, debug and maintain.
Is there a reason why you think that the dynamic SQL would be preferable in this case? If so, what is it?
-
How to pass the Record of entry to the dynamic SQL Code
Hi all
I am trying to run under Oracle applications API on the remote database using DB Link. I try to run using dynamic SQL. Part of the code is given below.
DECLARE
l_batch_info_rec wsh_picking_batches_pub.batch_info_rec;
l_rule_id NUMBER;
l_rule_name VARCHAR2 (240);
l_batch_prefix VARCHAR2 (240);
BEGIN
l_batch_info_rec.document_set_id: = v_document_set_id;
l_batch_info_rec.order_type_id: = v_order_type_id;
l_batch_info_rec. Default_Stage_Subinventory: = v_default_stage_subinventory;
l_batch_info_rec.pick_grouping_rule_id: = v_pick_grouping_rule_id;
l_batch_info_rec.pick_sequence_rule_id: = v_pick_sequence_rule_id;
l_batch_info_rec.autopack_level: = v_autopack_level;
l_batch_info_rec.autopack_flag: = v_autopack_flag;
l_batch_info_rec.ac_delivery_criteria: = v_ac_delivery_criteria;
l_batch_info_rec.backorders_only_flag: = v_backorders_only_flag;
l_batch_info_rec.existing_rsvs_only_flag: = v_existing_rsvs_only_flag;
l_batch_info_rec.customer_id: = v_customer_id;
l_batch_info_rec.order_header_id: = v_header_id;
l_batch_info_rec.from_scheduled_ship_date: = NULL;
l_batch_info_rec.organization_id: = v_organization_id;
l_batch_info_rec.include_planned_lines: = v_include_planned_lines;
l_batch_info_rec.autocreate_delivery_flag: = v_autocreate_deliveries_flag;
l_batch_info_rec.autodetail_pr_flag: = v_autodetail_pr_flag;
l_batch_info_rec.allocation_method: = 'I ';
l_batch_info_rec.pick_from_locator_id: = NULL;
l_batch_info_rec.auto_pick_confirm_flag: = 'n'; -The value manually to run Transact order
l_batch_info_rec.autopack_flag: = 'n'; -Manually configure to perform the manual packaging
l_rule_id: = NULL;
l_rule_name: = NULL;
l_batch_prefix: = NULL;
v_sqlstmt1: = ' START
wsh_picking_batches_pub.create_batch' | g_db_link | "(1.0,
fnd_api.g_true,
fnd_api.g_true,
: l_return_status,.
: l_msg_count,.
: l_msg_data,.
: l_rule_id,.
: l_rule_name,.
: l_batch_info_rec,.
: l_batch_prefix,.
: p_new_batch_id
);
END;';
--
EXECUTE IMMEDIATE V_sqlstmt1
With the HELP OF THE l_return_status,.
ON l_msg_count,.
ON l_msg_data,.
BY l_rule_id,
BY l_rule_name,
BY l_batch_info_rec,
BY l_batch_prefix,
OUT p_new_batch_id;
--
END;
After you run this script, I get below error "PLS-00457: expressions must be SQL types ' for variable l_batch_info_rec which is of type record. can someone please guide me how can I pass variable type dynamic SQL record.
Thank you
Priyanka
Food for thought:
On remote db:
SQL > create or replace
package 2 pkg
3 is
4 type r_type is (record
Number 5,
6 name varchar2 (10)
7 );
(p) 8 procedure
9 p_rec in r_type,
10 p_out out varchar2
11 );
12 end;
13.Package created.
SQL > create or replace
package 2 body pkg
3 is
4 procedure p)
5 p_rec in r_type,
6 p_out out varchar2
7 )
8 is
9 start
10 p_out: = "ID = ' |" p_rec.ID | 'Name =' | p_rec. Name;
11 end;
12 end;
13.Package body created.
SQL >
On local db:
SQL > set serveroutput on
SQL > declare
v_rec 2 pkg.r_type@pdb1sol12;
3 v_out varchar2 (50);
4 start
v_rec.ID 5: = 1;
6 v_rec.name: = 'XXX ';
7 immediate execution"
8 begin
9 pkg.p@pdb1sol12 (: 1,: 2);
10 end;'
11 using v_rec,
12 v_out;
13 dbms_output.put_line (v_out);
14 end;
15.
using v_rec;
*
ERROR on line 11:
ORA-06550: line 11, column 20:
PLS-00457: expressions must be SQL types
ORA-06550: line 7, column 5:
PL/SQL: Statement ignoredSQL > declare
2 number of v_id: = 1;
3 v_name varchar2 (10): = 'XXX ';
4 v_out varchar2 (50);
5. start
6 immediate execution"
7 report
8 v_rec pkg.r_type@pdb1sol12.
9 begin
10 v_rec.id := :1;
11 v_rec.name: =: 2;
12 pkg.p@pdb1sol12 (v_rec,: 3);
13 end;'
14 using v_id,
15 in v_name,
16 v_out;
17 dbms_output.put_line (v_out);
18 end;
19.
ID = 1 name = XXXPL/SQL procedure successfully completed.
SQL >
SY.
-
How to extract the names of columns in dynamic SQL
Hi all
Is it possible to extract all the names of columns in a dynamic query?
In my case according to the user selections that my query will get changed (number of the column, column name and tables that everything can vary).
So now, is it possible to retrieve all the column names of the dynamic query generated?
I am using Oracle 11g (11.2.0.4)
Thank you
Shaz
-
Quoted string inside dynamic SQL
Hello
My version of db: database Oracle 11 g Enterprise Edition Release 11.2.0.1.0 - 64 bit Production
I run this code in a proc, and it goes to the exception block without running the code below:
I made a mistake with quoted strings and I have tried different combinations, but anyway his does not work.EXECUTE IMMEDIATE 'SELECT LISTAGG (entitlement, '''','''') WITHIN GROUP (ORDER BY entitlement) FROM XMLTABLE ( ''''/ROWSET/ROW/ENTITLEMENTS/ENTITLEMENT'''' PASSING XMLPARSE (DOCUMENT p_xmldoc) COLUMNS ENTITLEMENT VARCHAR2(30) PATH ''''.'''')' INTO v_str;
THA real piece of code is below, whick I'm trying to run immediately in a string
p_xmldoc sample is less thanSELECT LISTAGG (entitlement, ',') WITHIN GROUP (ORDER BY entitlement) FROM XMLTABLE ( '/ROWSET/ROW/ENTITLEMENTS/ENTITLEMENT' PASSING XMLPARSE (DOCUMENT p_xmldoc) COLUMNS ENTITLEMENT VARCHAR2(30) PATH '.')
My goal is to get'<?xml version="1.0"?> <ROWSET> <ROW> <ENTITLEMENTS> <ENTITLEMENT>AMEX</ENTITLEMENT> <ENTITLEMENT>JCB</ENTITLEMENT> </ENTITLEMENTS> </ROW> </ROWSET>'
v_str = AMEX, JCB
Please advice.Hello
Use the notation by Q.
Assuming that the dynamic control does not contain a right brace immediately before a single quote, you can say:sql_txt := Q'{SELECT LISTAGG (entitlement, ',') WITHIN GROUP (ORDER BY entitlement) ...}'; dbms_output.put_line (sql_txt || ' = sql_txt'); -- EXECUTE IMMEDIATE sql_txt;
With Q-rating, you can't excape double, or otherwise single quotes.
When you write code dynamic SQL, put the full command in a single VARCHAR2 variable (such as the sql_txt above). During the test, display it. If it looks right, then a comment the line where actually run you it.
-
error in dynamic sql code:
When I'm adding this code dynamically is error rechaussaient. Please can you find the error and tell me please
v_sql := v_sql||'tl.type = ''1'' and TL.TYPE IN (SELECT DECODE (LENGTH (tc.id),2,''AP''||tc.tagid,tc.tagid) tagid FROM traninfo tc, trancogroup tg WHERE tc.id = tg.id AND tc.req = tg.req AND tc.status = ''Y'' AND tg.smstype IN (SELECT SUBSTR (channel_desc,''1'',''2'') FROM deliverychannelinfo) AND tc.description ='||v_txntype||')';
980560 wrote:
When I'm adding this code dynamically is error rechaussaient. Please can you find the error and tell me pleasev_sql := v_sql||'tl.type = ''1'' and TL.TYPE IN (SELECT DECODE (LENGTH (tc.id),2,''AP''||tc.tagid,tc.tagid) tagid FROM traninfo tc, trancogroup tg WHERE tc.id = tg.id AND tc.req = tg.req AND tc.status = ''Y'' AND tg.smstype IN (SELECT SUBSTR (channel_desc,''1'',''2'') FROM deliverychannelinfo) AND tc.description ='||v_txntype||')';
The most important thing to consider when you use dynamic SQL statements, is to ensure that you are using Bind variables and not the value of filler directly as you did it tc.description ='| v_txntype |') ' ; + It is very bad.
Secondly, when you generate a string which uses apostrophes Q use notation that would be easier and more readable.
And on the error you get, that could be cause of there is no space before t1.type, then try this
v_sql := v_sql || q'[ tl.type = '1' and tl.type in (select decode (length (tc.id),2,'AP'||tc.tagid,tc.tagid) tagid from traninfo tc, trancogroup tg where tc.id = tg.id and tc.req = tg.req and tc.status = 'Y' and tg.smstype IN (SELECT SUBSTR (channel_desc,1,2) FROM deliverychannelinfo) and tc.description = :txn_type)]'
-
Hello gurus,
I have a doubt!
How to get the value of a dynamic sql inside the loop For?
Kind regardsDECLARE lv_v_sql VARCHAR2 (4000); BEGIN lv_v_sql := 'SELECT a FROM' || ' (SELECT 1 AS a FROM DUAL ' || 'UNION ALL ' || 'SELECT 2 AS a FROM DUAL' || ' UNION ALL ' || 'SELECT 3 AS a FROM DUAL ' || ' UNION ALL ' || ' SELECT 4 AS a FROM DUAL' || ' UNION ALL ' || ' SELECT 5 AS a FROM DUAL) ' || ' where a=' || 1; EXECUTE IMMEDIATE lv_v_sql; DBMS_OUTPUT.put_line (lv_v_sql); FOR i IN lv_v_sql LOOP DBMS_OUTPUT.put_line (i); END LOOP; END;
a friend :)Just add IN the clause EXECUTE IMMEDIATE. Example below shows you how to select EXECUTE IMMEDIATE data when it returns a single row and when she returns several lines:
SQL> DECLARE 2 lv_v_sql VARCHAR2 (4000); 3 v_a number; 4 v_a_tbl sys.OdciNumberList; 5 BEGIN 6 lv_v_sql := 7 'SELECT a FROM' 8 || ' (SELECT 1 AS a FROM DUAL ' 9 || 'UNION ALL ' 10 || 'SELECT 2 AS a FROM DUAL' 11 || ' UNION ALL ' 12 || 'SELECT 3 AS a FROM DUAL ' 13 || ' UNION ALL ' 14 || ' SELECT 4 AS a FROM DUAL' 15 || ' UNION ALL ' 16 || ' SELECT 5 AS a FROM DUAL) ' 17 || ' where a=' 18 || 1; 19 EXECUTE IMMEDIATE lv_v_sql 20 INTO v_a; 21 DBMS_OUTPUT.put_line (lv_v_sql); 22 DBMS_OUTPUT.put_line(v_a); 23 lv_v_sql := 24 'SELECT a FROM' 25 || ' (SELECT 1 AS a FROM DUAL ' 26 || 'UNION ALL ' 27 || 'SELECT 2 AS a FROM DUAL' 28 || ' UNION ALL ' 29 || 'SELECT 3 AS a FROM DUAL ' 30 || ' UNION ALL ' 31 || ' SELECT 4 AS a FROM DUAL' 32 || ' UNION ALL ' 33 || ' SELECT 5 AS a FROM DUAL) '; 34 EXECUTE IMMEDIATE lv_v_sql 35 BULK COLLECT 36 INTO v_a_tbl; 37 DBMS_OUTPUT.put_line (lv_v_sql); 38 FOR i IN 1..v_a_tbl.COUNT 39 LOOP 40 DBMS_OUTPUT.put_line(v_a_tbl(i)); 41 END LOOP; 42 END; 43 / SELECT a FROM (SELECT 1 AS a FROM DUAL UNION ALL SELECT 2 AS a FROM DUAL UNION ALL SELECT 3 AS a FROM DUAL UNION ALL SELECT 4 AS a FROM DUAL UNION ALL SELECT 5 AS a FROM DUAL) where a=1 1 SELECT a FROM (SELECT 1 AS a FROM DUAL UNION ALL SELECT 2 AS a FROM DUAL UNION ALL SELECT 3 AS a FROM DUAL UNION ALL SELECT 4 AS a FROM DUAL UNION ALL SELECT 5 AS a FROM DUAL) 1 2 3 4 5 PL/SQL procedure successfully completed.
SY.
-
Dynamic SQL with dynamic identifiers
Oracle 10gXE
I have a table that is used to track student attendance. If the student is present on a given day, a record is inserted with the student ID and the date they frequented.
presence of DESC
Name of Type Null
--------------- -------- ------
ID NOT NULL NUMBER
NUMBER OF STUDENT_ID
SITE_ID NUMBER
DATE OF ATTENDANCE_DATE
I want to view a report (in TOP) which shows all students for a given site, the days when school was in session for this month (not Saturday, Sunday) and a X for the student who participated in that day or a null value if they do not have.
ID # FNAME LNAME 3 4 5 6 7 10
38754636 POE JANE X X X
81248754 DOE KAYLA X X X X X
43127409 RAO JOHN X X X X X
In this example, days 3 and 7 of the month are from Monday to Friday and 8-9 have been excluded because they are on Saturday and Sunday.
I am trying to find a way to dynamically generate a query for any month/year and returning to a report. The obstacle is that given that I don't know in advance which days in a month will be excluded, the identifiers in my select statement are not fixed.
I found a query that returns a list of day numbers and dates for a given month. It looks like this:
SELECT LEVEL lv, TO_DATE (TO_CHAR (LEVEL, '09')
|| TO_CHAR (EXTRACT (TO_DATE('01-SEP-11') MONTHS), '09')
|| To_char (EXTRACT (TO_DATE('01-SEP-11') YEAR), ' 9999'), 'dd.mm.yyyy') mon_day
OF double WHERE ROWNUM < = EXTRACT (DAY OF LAST_DAY (TO_DATE('01-SEP-11')))
CONNECT BY LEVEL = ROWNUM
I combined this request with another brings my student attendance data and results that pivots in what I need. Then, I created a function that accepts the month and year as parameters and creates the combined request.
SELECT c.ID student_id, c.last_name, c.first_name,.
MAX (decode (mon_day, ' 01 - SEPT.-11', 'X', NULL)) '1', MAX (decode (mon_day, ' 02 - SEVEN.-11', 'X', NULL)) '2 ',.
MAX (decode (mon_day, ' 05 - SEPT.-11', 'X', NULL)) '5', MAX (decode (mon_day, ' 06 - SEPT.-11', 'X', NULL)) "6."
MAX (decode (mon_day, ' 07-SEP-11', 'X', NULL)) '7', MAX (decode (mon_day, ' 08 - SEPT.-11', 'X', NULL)) "8."
MAX (decode (mon_day, ' 09 - SEPT.-11', 'X', NULL)) '9', MAX (decode (mon_day, 12-SEP-11', 'X', NULL)) "12."
MAX (decode (mon_day, 13-SEP-11', 'X', NULL)) '13', MAX (decode (mon_day, 14-SEPT-11', 'X', NULL)) "14."
MAX (decode (mon_day, 15-SEP-11', 'X', NULL)) '15', MAX (decode (mon_day, 16-SEP-11', 'X', NULL)) "16."
MAX (decode (mon_day, 19-SEP-11', 'X', NULL)) '19', MAX (decode (mon_day, 20-7.-11', 'X', NULL)) "20."
MAX (decode (mon_day, 21-SEP-11', 'X', NULL)) "21", MAX (decode (mon_day, 22-SEP-11', 'X', NULL)) '22 ',.
MAX (decode (mon_day, 23-SEP-11', 'X', NULL)) '23', MAX (decode (mon_day, 26-SEP-11', 'X', NULL)) "26."
MAX (decode (mon_day, 27-SEP-11', 'X', NULL)) '27', MAX (decode (mon_day, 28-SEP-11', 'X', NULL)) "28."
MAX (decode (mon_day, 29-SEP-11', 'X', NULL)) '29', MAX (decode (mon_day, 30-SEP-11', 'X', NULL)) '30 '.
(SELECT level lv, TO_DATE (TO_CHAR (LEVEL, '09')
|| TO_CHAR (EXTRACT (TO_DATE('01-SEP-11') MONTHS), '09')
|| To_char (EXTRACT (TO_DATE('01-SEP-11') YEAR), ' 9999'), 'dd.mm.yyyy') mon_day
OF double WHERE ROWNUM < = EXTRACT (DAY OF LAST_DAY (TO_DATE('01-SEP-11')))
CONNECTION LEVEL = ROWNUM) a, b of attendance, student c
WHERE to_char(MON_DAY,'D') NOT IN (1.7)
AND A.mon_day = b.attendance_date
AND b.student_id = c.ID
Group of c.ID, student_id, c.last_name, c.first_name
Now I'm stuck on what I can pass this request in to get my result. What I've read, dynamic SQL method 4 would work if I incorporate Pro/C. I hope this isn't my only option. I have considered to try to do this in a function table in pipeline, but since the columns returned are not known in advance, I can't create a corresponding data type.
I'm starting to wonder if I forgot a simpler method to achieve this.
Published by: David Sumner on April 12, 2012 18:52Ignoring the actual query and looking at the dynamic SQL part of the question.
There are 3 ways to run a dynamic select SQL in PL/SQL code.
immediate execution requires a fixed number of bind variables, linking him in position and translates a single implicit output cursor extraction - requiring the projection of cursor to be known at the time of coding.
REF CURSOR are essentially the same - the only exception being that it requires an extraction explicit coding process output cursor.
DBMS_SQL differs in all of these respects. The connection is by name and not position. The connection is dynamic. Projection of the cursor must not be known at the time of coding. It is dynamically determined at runtime and fetch offers of release of the cursor with the projection of unknown SQL - coding time.
Apex uses DBMS_SQL internally (in fact he uses DBMS_SYS_SQL properly run dynamic and specific patterns of Oracle SQL, as if a session connected as a scheme runs the SQL code). This allows the Apex to take a dynamic SQL that you enter a region (which can contain a variable number of bind variable), run it and make the projection of the cursor as an HTML report.
Apex supports in turn also dynamic SQL - what you (Apex developer) to provide a dynamic SQL code for a region, instead of you having to provide SQL fixed (with bind variable) for the region in question.
As Apex creates DBMS_SQL sliders, it doesn't have your SQL as a ref cursor or cursor DBMS_SQL. All they need is the source of the SQL statement. And that's what you create dynamically.
So in the Apex, dynamic SQL means using a function from PL/SQL to return the source for Apex SQL analyze like a slider DBMS_SQL - instead of coding the source SQL statement in a fixed statement.
So, using the option of function for an area considered in the Apex, allows you to provide the following in the code that must run to get the SQL statement for the report Apex (Apex running this as a dynamic function that returns a string):
--// return the dynamic SQL for the report region return( case when :P1_OPTION = 1 then 'select * from emp' when :P1_OPTION = 2 then 'select * from dept where dept_id = :P1_DEPT_ID' end );
You can also write a PL/SQL function that is stored in the database and call this function so that it can determine what is the dynamic SQL source code statement. For example
--// calling database function to return the dynamic SQL for the report region return( GetDynamicReportSQL( page => 1, option => :P1_OPTION ) );
Dynamic SQL is fully supported by Apex - but does not require that you, the developer, to create the dynamic cursor and treat the dynamic linking and dynamic recovery of this slider.
All you have to do is to provide the source code of this dynamic SQL (including the bind variable) to the Apex and it will do the whole thing from cursor for you.
-
Hi all
I'm moving a table as a variable in dynamic SQl but with no result. Suppose that I it running on HR diagram example:
I get this error of invalid table name without knowing what was read for the variable. Any advice?declare sql_state varchar(100); hire_date date; temp_table varchar(9):='employees'; begin sql_state:= 'select hire_date from :1 where employee_id=206'; execute immediate sql_state into hire_date using temp_table; dbms_output.put_line('hire_date is '||hire_date); end; declare * ERROR at line 1: ORA-00903: invalid table name ORA-06512: at line 9
Best regards
ValHi Valerie,
To add to what Peter, said
"Binding" values in a query is done for a specific purpose, and this purpose is so that the optimizer can use the same query as the previous execution plan runs the query, which prevent it from having to analyze the hard the query each time. A query execution plan is based on the tables and columns are presented in the query, but with respect to the actual "values" of these columns, they are unlikely to change the execution plan. So, to keep the same execution plan, the query must seem identical (in terms of a query string) like the previous series, so if you want the same query, but just with different values, they can be replaced with bind variables (these things have a ': ' character) and then the values passed in the query, when it is run.
Now, if Oracle were to allow you to link in the names of objects, such as tables, this means that it could not use the previous execution plans, because he doesn't know until run time what tables will be consulted. Therefore, it would be useless link in the values of the query and it would be just as quick to implement your query string by concatenating all the values inside rather than link them. Considering that a query is parsed first and then the values in it, then it cannot be analyzed if the tables are not known everything first. (Take a look at how queries are formed and variables when you use the DBMS_SQL package).
So the key thing to remember is that, when it comes to bind variables, you can bind only the 'values', not 'objects '.
-
I'm having a problem with the generation of dynamic SQL code.
Specifically when I use single quotes in my SQL statements, they end by showing as quotes when the query is run.
Any ideas on how I can remdey it?
When I view my dynamic SQL code, it looks and works fine if I run it
AND (External_Group_Members LIKE ' % 1% ' OR External_Group_Members LIKE ' %, 3, %'))
but when these data are transmitted to the SQL, it looks at and I get an error
SELECT * FROM External_Groups WHERE 1 = 1 AND (External_Group_Members LIKE '% 1% ' OR External_Group_Members LIKE "%, 3, %'') ORDER BY External_Group_Name)
PreserveSingleQuotes().
-
Dynamic SQL instead of SQLLOADER
Hello
I use dynamic SQL to load and transform data files.
It works well, except that for reasons of speed I load the entire file into a temporary table before loading to its final destination along the lines of; -
It works very fast, BUT my problems come when; my example above; a field contains a non-numeric is loaded into a numeric field.insert into ap_invoices_interface (invoice_num, invoice_amount, etc....) (select field1, field2, etc from temp_table);
Is anyway, once again using dynamic SQL I can QUICKLY validate before for this kind of error, without doing it on a row by row basis?
NB: I have a table xx_interface_mapping - which maps field1 = > invoice_num, Field2 = > invoice_amount etc. - and I put this together to make the insert statement, is it possible to combine with all_tables to know the type of data in the fields and ensure that they are valid - ALL IN the SQL DYNAMICS zippy instructions?
Thanks for the suggestions - I is not looking for you to write the code, suggest only the concepts to use to get there...
Robert.You can also the values digital alpha eliminate by this way.
with TABLE1 as)
Select "999,99' column1 of union double all the»
Select ' + 999.112' of all the double union. "
Select "12321.54"of any double union. "
Select '-12ABC0.99' of all the double union
Select '122' in double union
Select '9878' across double Union
Select "xyzd" from double
)
SELECT * FROM TABLE1
where LENGTH (TRIM (TRANSLATE (column1, ' + -. 0123456789', ' '))) a null value -
the number of columns in dynamic sql
Hello
I was wondering if you could count the number of columns had a dynamic sql code.
Very simple eg.
Say I had a string 'select 1, 2,3,4,5,6 double' and I only immediate excute. Is it possible to count the number of column IE 6 columns.
I know s/n | THE USER | ALL_TAB_COLUMNS, but it could be a few different columns columns, and it is not a view.
Thanks for you advice/help.with the "immediate execution" option you cannot get metadata such as the number of columns for the executed query. Use rather dbms_sql...
Research of DESCRIBE_COLUMNS string in the link below... It will give you an idea of how to make to get the same.
http://www.morganslibrary.org/reference/DBMS_SQL.htmlRavi Kumar
Published by: ravikumar.sv on July 30, 2010 15:51
-
Hey everyone, I'm trying to understand how to use dynamic sql statements in Application Express. Specifically, I'm trying to write a query using substitution/bind variables. I don't know if you need a description of the application or not, but here's the query that will run in sqlplus:
There are three substitution variables, reference_id & file_id and & table_name. My basic setup is that I have a table full of table names, so I ask her to get a table name in a variable, then query this table for my data.ACCEPT file_id PROMPT "Enter the file_id (a number, e.g. 3): " -- Preliminary Query, to set table_name COLUMN reference_id_col NEW_VALUE reference_id COLUMN table_name_col NEW_VALUE table_name SELECT f.reference_id AS reference_id_col , t.reference_table AS table_name_col FROM aa_files f JOIN aa_type t ON f.file_type = t.type_id WHERE f.file_id = &file_id ; -- Main Query SELECT * FROM &table_name WHERE reference_id = &reference_id ;
I work inside the window of SQL commands to try to find the proper syntax to make this work in the APEX. I'm pretty sure that APEX does not allow the use of substitution variables, because they are one thing on the side of client SQL more right?
I'm still a student, so I'm not known and Oracle Application Express, but reading the documentation of the APEX and the Googling, I tell myself that bind variable should be able to do this for me, but I don't know how. I searched for some examples or documentation on the use of dynamic SQL statements in the APEX, but I could not find anything. I'm sure I could do this using a PL/SQL block, but I'd rather do it in pure SQL if possible.
So if someone could help me or giving me an example of syntax I would have to use to write a query that is running in Application Express, or could direct me to the literature on the use of dynamic sql statements in Application Express, it would be greatly appreciated!
If you need more information on my application, I can post my create table statements and some inserts sample data, if that would be helpful.
Thank you!
Published by: username, June 21, 2010 07:34OK, so one of the great things about SQL is your ability to choose what columns you want to include in your result set. You don't have to use all of them. You can do this in two ways: with dynamic SQL or individual areas for each type of file. This will depend on your use as to how many types different files will be added each day on which you want to go with.
If you go with dynamic SQL (and because you don't know until run time what columns you want to use, it is an appropriate use), you will need to build your query based on the file type. Something like this:
declare qry_type VARCHAR2(10); sql_qry VARCHAR2(4000); qry_select VARCHAR2(500); qry_from VARCHAR2(100); qry_where VARCHAR2(400); qry_order VARCHAR2(100); begin qry_type := :PX_QRY_TYPE; --Build the SELECT clause qry_select := 'select a.FILE_NAME, a.FILE_NAME, a.FILE_TYPE, a.LOCATION'; CASE qry_type WHEN 'PDF' THEN qry_select := qry_select || ', pdf.DATE_MODIFIED, pdf.SUMMARY, pdf.AUTHOR'; WHEN 'XLS' THEN qry_select := qry_select || ', xls.DATE_MODIFIED, xls.SUMMARY, xls.TOTAL_VALUE'; ... END CASE; --Build the FROM clause qry_from := ' from AA_FILE a, AA_FILETYPE_PDF pdf, AA_FILETYPE_XLS xls, AA_FILETYPE_PHOTO p'; --Build the WHERE clause qry_where := ' where a.FILE_ID = pdf.FILE_ID (+)'; qry_where := qry_where || ' and a.FILE_ID = xls.FILE_ID (+)'; qry_where := qry_where || ' and a.FILE_ID = p.FILE_ID (+)'; --Build the ORDER BY clause qry_order := ''; --Put it all together sql_qry := qry_select || qry_from || qry_where || qry_order; EXECUTE IMMEDIATE sql_qry; ... end;
Now this does not cover the addition of new file types. I still think you're going to be better off planning for as much as you can and handle manually creating additional tables, but this is going to be to you. I know you are trying to generate code to do everything for you, but when it comes to databases, I found that the creation of objects can quickly become uncontrolled if you're not very careful. These are going to be permanent, not temporary memory built database objects. Just a word of warning.
If you decide to go with a region and by file type, it does not require nearly as much work. Simply create a report region based on the view and set the conditional display based on your file type.
select * from V_FILES_PHOTO where FILE_ID = :PX_FILE_ID; condition: FILE_TYPE = 'PDF'
While you will need to add a region again every time that you add a new file type, once again, the question that arises is: file types how are you really going to have to worry? If you're talking about a dozen, I would like to do things manually. If you're talking about a hundred, it's maybe worth trying to find a method of programming. It is your call to make.
Maybe you are looking for
-
When I go to one of my sites work I click on the PDF file and an address bar is displayed and I can copy that then bind it where I want. Now, Miss me the address bars. Google and Internet Explorer still allow me the address bar. I don't remember chan
-
I enjoyed firefox 4 and used the quick note application. Now, my firefox has updated and I lost the quick note with all my notes of course application. If I go down, I'll be able to use the app and my docs will always be there.
-
Cannot install the update of security for MS Works 9
I tried to install this update over 90 times and it won't install and I get an "unknown error code. Any ideas?
-
Sending Explorer Option disappeared
Windows XP Home Edition, SP 3 with all updates. I just noticed that when I right click a file in the Explorer, the option send to no longer appears. Eudora is my email client. Just installed the latest version of Windows update last night, but I do
-
Can someone tell me where I can buy a replacement for my Aspire S3-951 OEM battery?
I bought one that was supposed to be compatible - and looked like exactly the same that the one came it with my Ultrabook - but my system comes the battery was "detected" and stop as soon as I pulled the power cable. Searched the web for help and fou