FORALL with dynamic SQL
Hello people,I'm just wondering that when you want to handle the large amount of lines we use FORALL to reduce the change of context. So, what happens if when we use dynamic sql instead of normal SQL FORALL. I mean using the dynamic SQL inside FORALL increase performance?
Because I know that when we use the variable binding in sql statements or questions, then it will scan only just 1 hour instead of every time. Therefore, other SQL statements don't need to analyze which does not have a performance gain?
FORALL reduced context switching AND SQL dynamic with bind variable prevent unnecessarily analysis, so wheren here are using hear, she will be better performance isn't? Please correct me if I'm wrong.
For example;
FORALL i IN l_in_tab.first .. l_in_tab.last
EXECUTE IMMEDIATE
'DELETE FROM bulk_collect_test
WHERE object_id = :1'
USING l_in_tab(i);
Thank you very much.
>
Dynamic SQL with variable bind unnecessarily prevent analysis
>
Yes - compared to dynamic SQL that does not bind variable.
Just use
DELETE FROM bulk_collect_test
WHERE object_id = l_in_tab(i);
FORALL essentially uses a form of BONDING in BULK already
See reduction in overhead costs of loop for DML statements and queries with SQL in bulk in Chapter 12 Applications of PL/SQL Tuning of Performance in the PL/SQL doc
http://docs.Oracle.com/CD/B28359_01/AppDev.111/b28370/tuning.htm#sthref1455
>
Bulk SQL uses PL/SQL collections to pass back and forth large quantities of data in simple operations. This process is called binding of bulk. If the collection has n elements, bulk binding uses a single operation to perform the equivalent of n SELECT INTO, INSERT, UPDATE, or DELETE statements
Tags: Database
Similar Questions
-
String with dynamic SQL in APEX
Hello
I need assistance with dynamic SQL new... sigh...
Could someone post Oracle rules use for the string of quoted text in the dynamic SQL statements?
How to encode the following SQL statement in dynamic SQL?
Select * from emp where State in ('CA', 'HI')
declare
l_sql varchar2 (400)
Start
l_sql: = ' select * from emp where indicate in ("' CA" '...)
end;
Please provide coding rules... Thank you very much
Chris :)Hello
Two single quotes will be replaced by a single quotation mark when used in a string. So:
declare l_sql varchar2(400) begin l_sql := 'select * from emp where state in (''CA'' ..... end;
If you need to close the string to be concatenated to another channel, then you use an other single quotation mark to close the chain and open it again later:
declare l_sql varchar2(400) begin l_sql := 'select * from emp where state in (''' || a_string_variable || ''' ..... end;
Andy
-
Tables created in a stored procedure cannot be used with dynamic SQL? The impact?
There is a thread on the forum which explains how to create tables within a stored procedure (How to create a table in a stored procedure , however, it does create a table as such, but not how to use it (insert, select, update, etc.) the table in the stored procedure.) Looking around and in the light of the tests, it seems that you need to use dynamic SQL statements to execute ddl in a stored procedure in Oracle DB. In addition, it also seems that you cannot use dynamic SQL statements for reuse (insert, select, update, etc.) the table that was created in the stored procedure? Is this really the case?
If this is the case, I am afraid that if tables cannot be 'created and used"in a stored procedure using the dynamic SQL, as is the case with most of the servers of DB dynamic SQL is not a part of the implementation plan and, therefore, is quite expensive (slow). This is the case with Oracle, and if yes what is the performance impact? (Apparently, with Informix, yield loss is about 3 - 4 times, MS SQL - 4 - 5 times and so on).
In summary, tables created within a stored procedure cannot be 'used' with dynamic SQL, and if so, what is the impact of performance as such?
Thank you and best regards,
Amedeo.
Published by: AGF on March 17, 2009 10:51AGF says:
Hi, Frank.Thank you for your response. I understand that the dynamic SQL is required in this context.
Unfortunately, I am yet to discover "that seeks to" using temporary tables inside stored procedures. I'm helping a migration from MySQL to Oracle DB, and this was one of the dilemmas encountered. I'll post what is the attempt, when more.
In Oracle, we use [global temporary Tables | http://www.psoug.org/reference/OLD/gtt.html?PHPSESSID=67b3adaeaf970906c5e037b23ed380c2] aka TWG these tables need only be created once everything like a normal table, but they act differently when they are used. The data inserted in TWG will be visible at the session that inserted data, allowing you to use the table for their own temporary needs while not collide with them of all sessions. The data of the TWG will be automatically deleted (if not deleted programmatically) when a) a commit is issued or b) the session ends according to the parameter that is used during the creation of the TWG. There is no real need in Oracle to create tables dynamically in code.
I noticed that many people say that the "Creation of the tables within a stored procedure" is not a good idea, but nobody seems necessarily explain why? Think you could elaborate a little bit? Would be appreciated.
The main reason is that when you come to compile PL/SQL code on the database, all explicit references to tables in the code must correspond to an existing table, otherwise a djab error will occur. This is necessary so that Oracle can validate the columns that are referenced, the data types of those columns etc.. These compilation controls are an important element to ensure that the compiled code is as error free as possible (there is no accounting for the logic of programmers though ;)).
If you start to create tables dynamically in your PL/SQL code, so any time you want to reference this table you must ensure that you write your SQL queries dynamically too. Once you start doing this, then Oracle will not be able to validate your SQL syntax, check the types of data or SQL logic. This makes your code more difficult to write and harder to debug, because inevitably it contains errors. It also means that for example if you want to write a simple query to get that one out in a variable value (which would take a single line of SQL with static tables), you end up writing a dynamic slider all for her. Very heavy and very messy. You also get the situation in which, if you create tables dynamically in the code, you are also likely to drop tables dynamically in code. If it is a fixed table name, then in an environment multi-user, you get in a mess well when different user sessions are trying to determine if the table exists already or is the last one to use so they can drop etc. What headache! If you create tables with table names, then variable Dynamics not only make you a lot end up creating (and falling) of objects on the database, which can cause an overload on the update of the data dictionary, but how can ensure you that you clean the tables, if your code has an exception any. Indeed, you'll find yourself with redundant tables lying around on your database, may contain sensitive data that should be removed.
With the TWG, you have none of these issues.
Also, what is the impact on the performance of the dynamic SQL statements in Oracle? I read some contrasting opinions, some indicating that it is not a lot of difference between static SQL and SQL dynamic in more recent versions of Oracle DB (Re: why dynamic sql is slower than static sql is this true?)
When the query runs on the database, there will be no difference in performance because it is just a request for enforcement in the SQL engine. Performance problems may occur if your dynamic query is not binding variable in the query correctly (because this would cause difficult analysis of the query rather than sweet), and also the extra time, to dynamically write the query running.
Another risk of dynamic query is SQL injection which may result in a security risk on the database.
Good programming will have little need for the tables of dynamically created dynamically or SQL.
-
I would like to create a ViewObject based on a PIVOT query. The question I have is that the PIVOT columns are based on a subquery. It seems that it is not possible with regular SQL:
Select *.
from TABLE1 as T
Pivot
(
Max (T.value)
for T.POINTNAME in (SELECT pointname from point)
) as P
I tried the query in SQL Developer.The solution is to use a dynamic query, so I was wondering if VO supports this type of query
Hello
What about using a normal view object and then use a PivotTable for the user to perform its analysis. If not, what happened to create a database view or start a display on a stored procedure object? So there seems to be 3 possibilities, where I think that the first (using the PivotTable)
Frank
-
Works with dynamic sql and list of numbers as return value
Hello.
Problems:
1. How can I insert the USERNAME variable in the string so it will be replaced over time.
2. I intend to return a list of IDS as 1,4,6,7,2 I want to use later in an IN clause.
How to complete the return function with the dynamic sql output variable?
I have no preference to dynamic sql but it was just something that came into my mind
When I thought that the implementation of the obligation to choose a list of offices for specific user groups.
(select statements from the sample are cut short, they're actually really big and I want to reuse this function in my)
BI Publisher data model for multiple modells).
CREATE or REPLACE FUNCTION F_OFFICES (-input parameters)
USERNAME IN VARCHAR2
USERGROUP IN VARCHAR2,
)
-Output parameter
RETURN VARCHAR2 AS
dynSQL VARCHAR2 (1000);
BEGIN
IF USERGROUP = "local" THEN
dynSQL: = 'xxx SELECT FROM CO_B WHERE Userid = username';
ELSIF USERGROUP = "regional" THEN
dynSQL: = "SELECT...". » ;
ELSIF USERGROUP 'federal' = THEN
dynSQL: = "SELECT...". » ;
END IF;
EXECUTE IMMEDIATE dynSQL;
-RETURN?;
END F_OFFICES;
Thanks for any help.As you have presented essentially pseudo-code we can only give you a Pseudo-solution :)
But the principle is:
... --Output parameter RETURN VARCHAR2 AS dynSQL VARCHAR2(1000); return_value varchar2(30): BEGIN IF USERGROUP = 'local' THEN dynSQL:= 'SELECT xxx FROM CO_B WHERE userid = :1'; -- placeholder for parameter ... END IF; EXECUTE IMMEDIATE dynSQL using USERNAME -- pass parameters in placeholder order into return_value; -- obviously this must match the projection of the dynamic query RETURN return_value; END F_OFFICES ;
This approach is not good if you want to vary the dynamic query projection. In this case, you can use a REF CURSOR or maybe DBMS_SQL.
Cheers, APC
-
Hello
I have the following function that works well:
FUNCTION to CREATE or REPLACE Get_Partition_Name (sTable VARCHAR2, iImportIndex INTEGER)
RETURN VARCHAR2 IS
cursor c is select A.partition_name from (select table_name, nom_partition,
ExtractValue)
dbms_xmlgen.
() getxmltype
"Select high_value of all_tab_partitions where table_name =" '. "
|| table-name
|| ' ' and table_owner = "'
|| TABLE_OWNER
|| ' ' and nom_partition = "'
|| nom_partition
|| ''''),
import_value of all_tab_partitions) where table_name sTable = and A.import_value = iImportIndex;
sPartitionName varchar (20);
err_num NUMBER;
BEGIN
Open c;
extract the c in sPartitionName;
IF c % ISOPEN THEN
C CLOSE;
END IF;
RETURN sPartitionName;
EXCEPTION
WHILE OTHERS THEN
err_num: = SQLCODE;
-Save the error in the log table
NEWSPAPER. SAVELINE (SQLCODE, SQLERRM);
END Get_Partition_Name;
I am trying to replace the dynamic SQL, something like cursor statement (see below), but it's broken. According to me, Miss me some quotes.
FUNCTION to CREATE or REPLACE Get_Partition_Name (sTable VARCHAR2, iImportIndex INTEGER)
RETURN VARCHAR2 IS
TYPE t1 IS REF CURSOR;
c t1;
sSql VARCHAR2 (500);
sPartitionName varchar (20);
err_num NUMBER;
BEGIN
sSql: = ' select A.partition_name from (select table_name, nom_partition,
ExtractValue)
dbms_xmlgen.
() getxmltype
'select high_value of all_tab_partitions where table_name ="'
|| table-name
|| ' ' and table_owner = "'
|| TABLE_OWNER
|| ' ' and nom_partition = "'
|| nom_partition
|| ''''''),
text() ") import_value of all_tab_partitions) where table_name =: a and A.import_value =: b';
C OPEN sSql USING sTable, iImportIndex;
extract the c in sPartitionName;
IF c % ISOPEN THEN
C CLOSE;
END IF;
RETURN sPartitionName;
EXCEPTION
WHILE OTHERS THEN
err_num: = SQLCODE;
-Save the error in the log table
NEWSPAPER. SAVELINE (SQLCODE, SQLERRM);
END Get_Partition_Name;
/
Please advise,
Kind regards
M.R.Assuming that the requirement is to find the partition in the table provided with the provided high value and the problem is that dba/all_tab_partitions.high_value is of type long, an alternative solution in the same sense that you already made is as follows. (I just used a slider instead of a function for the simplicity of the demo).
SQL> var r refcursor SQL> set autoprint on SQL> declare 2 ctx dbms_xmlgen.ctxhandle; 3 v_table_name VARCHAR2(40) := 'LOGMNR_USER$'; 4 v_value NUMBER := 100; 5 begin 6 ctx := DBMS_XMLGEN.NEWCONTEXT 7 ('select table_name 8 , partition_name 9 , high_value hi_val 10 from dba_tab_partitions 11 where table_name = :table_name'); 12 dbms_xmlgen.setbindvalue(ctx,'TABLE_NAME',v_table_name); 13 open:r for 14 with x as 15 (select xmltype(dbms_xmlgen.getxml(ctx)) myxml 16 from dual) 17 select extractvalue(x.object_value,'/ROW/TABLE_NAME') table_name 18 , extractvalue(x.object_value,'/ROW/PARTITION_NAME') partition_name 19 , extractvalue(x.object_value,'/ROW/HI_VAL') hi_val 20 from x 21 , TABLE(XMLSEQUENCE(EXTRACT(x.myxml,'/ROWSET/ROW'))) x 22 where extractvalue(x.object_value,'/ROW/HI_VAL') = v_value; 23 end; 24 / PL/SQL procedure successfully completed. TABLE_NAME ------------------------------------------------------------------------------- PARTITION_NAME ------------------------------------------------------------------------------- HI_VAL ------------------------------------------------------------------------------- LOGMNR_USER$ P_LESSTHAN100 100 SQL>
I don't know that there are other ways as well. Especially with the XML features, there are normally several ways to skin a cat.
-
ORA-00900 when you use the command COPY with dynamic SQL
Helllo,
I created the following procedure:
create or replace procedure copyTable (pSourceTableOwner IN varchar2
pSourceTableOwnerPasword IN varchar2
pTargetTableOwner IN varchar2
pTableName IN varchar2
pDatabaseLink IN varchar2)
as
vStatement varchar2 (250): = null;
Start
vStatement: = "copy of". pSourceTableOwner | '/' || pSourceTableOwnerPasword | '@' || pDatabaseLink |
"Insert" | pTargetTableOwner | '.' || pTableName | ' using select * from '. pTableName;
immediately run vStatement;
end;
/
The generated command (variable vStatement) looks like this:
"Insert a copy of O_GLCEN/o_glcen@SELLENTW o_jh. "X_PLZ_CD_MERGED_CTIS using select * from X_PLZ_CD_MERGED_CTIS".
When you call this procedure as "exec copyTable ('O_GLCEN', 'o_glcen', 'o_jh', 'X_PLZ_CD_MERGED_CTIS', 'SELLENTW');" the following lifts:
FEHLER in line 1:
ORA-00900: invalid SQL statement
ORA-06512: at "SYSTEMTECHNIK". COPYTABLE", line 20
ORA-06512: at line 1
But when you call the command COPY directly from SQL prompt the statement runs without error.
Is in general not possible to use the dynamic COPY with SQL command? If it is possible does anyone has an idea what I am doing wrong?
Any help will be appreciated...
Rgds
JHI would like to use something like
vStatement: = ' start in f (select * from ' | pSourceTableOwner |) '.' || pTableName | '@' || pDatabaseLink | Insert loop ') in ' | pTargetTableOwner | '.' || pTableName | "f-values; end loop; end; »
immediately run vStatement; -
Order to decode with dynamic SQL
Hi Experts,
I question something like:
In this dynamic query, I need to get recording output according to the order of values of deptno data entry.CREATE OR REPLACE PACKAGE SCOTT.REFCURSOR_PKG AS TYPE vTypRefCursor IS REF CURSOR; END REFCURSOR_PKG; / DECLARE vCursor REFCURSOR_PKG.VTYPREFCURSOR.vTypRefCursor; vDeptNo VARCHAR2(100):='40,10,20'; BEGIN OPEN vCursor FOR ' SELECT DEPT.DEPTNO, EMPNO EMPNO, ENAME ENAME FROM EMP EMP, DEPT DEPT WHERE DEPT.DEPTNO=EMP.DEPTNO AND DEPT.DEPTNO IN ('||vDeptNo||')'; END;
How can I get something like that?
Thank you
Dharan V
Published by: DharanV on December 30, 2009 16:09Hi, try something like this:
SQL> select deptno from dept; DEPTNO ---------- 10 20 30 40 50 60 3 SQL> select deptno 2 from dept 3 where deptno in (30,50,10,3) 4 order by regexp_instr('30,50,10,3','(^|,)'||deptno||'(,|$)'); DEPTNO ---------- 30 50 10 3
Your selection becomes (* not tested *)
SELECT DEPT.DEPTNO, EMPNO EMPNO, ENAME ENAME FROM EMP EMP, DEPT DEPT WHERE DEPT.DEPTNO=EMP.DEPTNO AND DEPT.DEPTNO IN ('||vDeptNo||')'|| ORDER BY REGEXP_INSTR('''||vDeptNo||''',''(^|,)''||deptno||''(,|$)'')';
Max
[My Italian blog Oracle | http://oracleitalia.wordpress.com/2009/12/29/estrarre-i-dati-in-formato-xml-da-sql/]Published by: Massimo Ruocchio, December 30, 2009 11:55
Extra single quote -
Char invalid when you use dynamic sql statements with cursor
Hello guys,.
I'm opening a following cursor with dynamic sql
my cursor statement isv_sql := 'SELECT OS.table_name FROM OBJECT_STATS_CONTROL OS, ALL_TABLES AT WHERE OS.analyze_flag <> ''N'' AND OS.last_analyze < sysdate -1 AND AT.last_analyzed < sysdate - 1 '||v_1||';';
I get an error messageBEGIN OPEN v_cur FOR v_sql; LOOP FETCH v_cur INTO v_tabname; ......
can any body suggest me where I'm wrong0911 invalid char
Thank youRemove the semicolon at the end:
||';' -- remove this.
-
run immediately with bind sql collection
Hi, I'm working on an implementation immediate execution where to use a binding that is to an SQL array type. The type of table is produced by be transmitted from an array of Java.
So it looks like:
execute immediate mystatement using myarray;
"mystatement" contains a forall command. I thought that it wouldn't work, because of limitations in the use of tables to link with dynamic sql, but it does. Also, I see in the Oracle documentation that allows dynamic sql to binds to SQL collection types. Am I so I read the documentation correctly, please, that this is a correct use of the immediate execution with a SQL collection?
I tested on 10.2 and 11 g
Thank you
David979394 wrote:
Hi, I'm working on an implementation immediate execution where to use a binding that is to an SQL array type. The type of table is produced by be transmitted from an array of Java.So it looks like:
execute immediate mystatement using myarray;
"mystatement" contains a forall command. I thought that it wouldn't work, because of limitations in the use of tables to link with dynamic sql, but it does. Also, I see in the Oracle documentation that allows dynamic sql to binds to SQL collection types. Am I so I read the documentation correctly, please, that this is a correct use of the immediate execution with a SQL collection?
I tested on 10.2 and 11 g
Thank you
David
Welcome to the Forum!
Here is a small demonstration to what Solomon said: (not the best of examples I would say, but should provide an indication)drop table depts; drop table emps; drop type type_depts; create table depts (dept_no number, dept_name varchar2(25), loc varchar2(10)); create table emps (empno number, name varchar2(25), dept_no number, salary number); create or replace type type_depts is table of number; insert into depts values (10, 'ABC', '111'); insert into depts values (20, 'ABC1', '111'); insert into depts values (30, 'ABC2', '111'); insert into depts values (40, 'ABC3', '111'); insert into depts values (50, 'ABC4', '111'); insert into emps values (1, 'PQR', 10, 100); insert into emps values (2, 'PQR1', 20, 100); insert into emps values (3, 'PQR2', 30, 100); insert into emps values (4, 'PQR3', 10, 100); insert into emps values (5, 'PQR4', 30, 100); insert into emps values (6, 'PQR5', 10, 100); insert into emps values (7, 'PQR6', 40, 100); insert into emps values (8, 'PQR7', 80, 100); commit; /* Block to find a DEPT_NO in EMP that does not exist in DEPT table */ set serveroutput on; declare dept type_depts; type type_emp is table of pls_integer index by pls_integer; emp type_emp; idx pls_integer; begin select dept_no bulk collect into dept from depts; execute immediate 'select empno from emps where dept_no not in (select column_value from table(:1))' bulk collect into emp using dept; for i in emp.first..emp.last loop dbms_output.put_line('Emp No:- ' || emp(i)); end loop; end; anonymous block completed Emp No:- 8
As you say, the 'mystatement"contains the FORALL statement; Is the name of the Table known at runtime, or it is passed as an additional parameter? If the Table name is known, then, IMO, there is no any dynamic SQL. A FORALL statement should be enough.
Please provide details. In addition, please read {message identifier: = 9360002}.
-
Hi all
I have a procedure that takes as an input parameter v_emp_id which is of type varchar.
emp_id are sent separated by commas to v_emp_id. Ex: v_emp_id = 7,2,1
In my code I use a cursor for loop recover data from the table emp like this
I'm in (select * from emp where emp_id in v_emp_id) loop
-----
end loop;
It does not work. How do I use dynamic sql statements to retrieve data by using the CURSOR LOOP FOR only?
Thanks in advanceMR Marie wrote:
How do I use dynamic sql statements to retrieve data by using the CURSOR LOOP FOR only?
Not with dynamic sql statements. I suggest you use collections:
SQL> create or replace 2 procedure p1( 3 p_empno sys.OdciNumberList 4 ) 5 is 6 begin 7 for v_rec in (select ename from emp where empno in (select * from table(p_empno))) loop 8 dbms_output.put_line(v_rec.ename); 9 end loop; 10 end; 11 / Procedure created. SQL> set serveroutput on SQL> exec p1(sys.OdciNumberList(7566,7844,7900)); JONES TURNER JAMES PL/SQL procedure successfully completed. SQL>
SY.
-
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.
-
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.
-
Dynamic SQL with in bulk in the record type
Oracle 10.2 g
I received this Tom
[http://asktom.oracle.com/pls/apex/f?p=100:11:0:NO:]
I'm able to do this without dynamic SQL, but my requirement is to do it in dynamic SQL
There is a work around in 11g, but can we do something in 10g?create table t1 ( x int, y int ); insert into t1 select rownum, rownum+1 from all_users where rownum <= 5; create table t2 ( x int, y int, z int ); declare type array is table of t1%rowtype; l_data array; begin select * bulk collect into l_data from t1; forall i in 1 .. l_data.count execute immediate 'insert into (select x, y from t2) values :x' using l_data(i); end; Error at line 1 ORA-06550: line 9, column 90: PLS-00457: expressions have to be of SQL types ORA-06550: line 9, column 20: PL/SQL: Statement ignored
Thank you
HESH.HESH wrote:
but following does not.
declare type array is table of t1%rowtype; l_data array; begin select * bulk collect into l_data from t1; forall i in 1 .. l_data.count execute immediate 'insert into (select x, y from t2) values :x' using l_data(i); end;
I want just a dynamic SQL code for the insert with FORALL statement would adopt as well as collections.
Doesn't make much sense.
Extract you the data from the SQL engine in the table of the record type. If the output data that cursor SQL must be read in the SQL engine and copied into the memory of PL/SQL engine.
Then, you send that VERY SAME DATA back to the SQL engine to be used by a SQL insert cursor.
Where is the logic behind the extraction of data from SQL in a PL/SQL table structure and then push this same structure table on the SQL engine database? What is the purpose to send data on a detour of underperforming and non-scalale through the PL/SQL engine?
You have any justification (technical or functional wise) to back up this absurd approach?
Why this can be achieved using a single SQL cursor that does both the choice (extraction) and (in bulk) insertion - using the plain old INSERT... SELECT structure?
And if the insert is variable, then what? Create a dynamic INSERT... SELECT cursor and execute it (using bind values). This simple... Right?
-
How the date can be filled with timestamp in dynamic sql
Hi all
Below we have sql
v_stmt: = ' MERGE IN MTH_EQUIPMENTS_EXT_B ED
WITH THE HELP OF)
SELECT TAG_DATA,
EQUIPMENT_FK_KEY,
WORKORDER_FK_KEY,
SEGMENT_FK_KEY,
SHIFT_WORKDAY_FK_KEY,
HOUR_FK_KEY,
ITEM_FK_KEY,
READ_TIME,
ATTR_GROUP_ID,
RECIPE_NUM,
RECIPE_VERSION,
NVL (FND_GLOBAL. User_Id,-1) l_updated_by,.
NVL (FND_GLOBAL. Login_Id,-1) l_last_update_login
OF MTH_TAG_READINGS_T_STG
WHERE DB_COL = ' | " ' || v_colname | " ' ||') TS
WE (';)
v_stmt: = v_stmt | "ED. EQUIPMENT_PK_KEY = TS. EQUIPMENT_FK_KEY AND
ED. READ_TIME = TS. READ_TIME AND
ED. ATTR_GROUP_ID = TS. ATTR_GROUP_ID)
WHEN MATCHED THEN
UPDATE
GAME ED.'. v_colname |' = TS. TAG_DATA,
ED. LAST_UPDATED_BY = 1, ";
v_stmt: = v_stmt | "ED. LAST_UPDATE_LOGIN = TS.l_last_update_login
WHEN NOT MATCHED THEN
INSERT ('| v_colname |', EXTENSION_ID, EQUIPMENT_PK_KEY, WORKORDER_FK_KEY, SEGMENT_FK_KEY, SHIFT_WORKDAY_FK_KEY, HOUR_FK_KEY, ITEM_FK_KEY, READ_TIME, ATTR_GROUP_ID, LAST_UPDATE_DATE, LAST_UPDATED_BY,';)
v_stmt: =.
v_stmt | ("LAST_UPDATE_LOGIN, CREATED_BY, CREATION_DATE, RECIPE_NUM, RECIPE_VERSION)
VALUES (TS. TAG_DATA, EGO_EXTFWK_S.NEXTVAL, TS. EQUIPMENT_FK_KEY, TS. WORKORDER_FK_KEY, TS. SEGMENT_FK_KEY, TS. SHIFT_WORKDAY_FK_KEY, TS. HOUR_FK_KEY, TS. ITEM_FK_KEY, TS. READ_TIME,';
v_stmt: = v_stmt | "TS. ATTR_GROUP_ID,' | '''|| SYSDATE | "'| ', 1, TS.l_last_update_login, TS.l_updated_by,'|"' | SYSDATE | " ' ||', TS. RECIPE_NUM, TS. RECIPE_VERSION)';
EXECUTE IMMEDIATE v_stmt;
After you run the above SQL last date of update in MTH_EQUIPMENST_EXT_B is filled with sysdate but timestamp is not its always 00:00:00. Can we have timestamp also populated through dynamic sql in the last update date
Kind regards
Amrit
Values to hardcode in the dynamic SQL - never use bind variables:
v_stmt: = ' MERGE IN MTH_EQUIPMENTS_EXT_B ED
WITH THE HELP OF)
SELECT TAG_DATA,
EQUIPMENT_FK_KEY,
WORKORDER_FK_KEY,
SEGMENT_FK_KEY,
SHIFT_WORKDAY_FK_KEY,
HOUR_FK_KEY,
ITEM_FK_KEY,
READ_TIME,
ATTR_GROUP_ID,
RECIPE_NUM,
RECIPE_VERSION,
NVL (FND_GLOBAL. User_Id,-1) l_updated_by,.
NVL (FND_GLOBAL. Login_Id,-1) l_last_update_login
OF MTH_TAG_READINGS_T_STG
WHERE DB_COL =: 1) TS
WE (';)
v_stmt: = v_stmt | "ED. EQUIPMENT_PK_KEY = TS. EQUIPMENT_FK_KEY AND
ED. READ_TIME = TS. READ_TIME AND
ED. ATTR_GROUP_ID = TS. ATTR_GROUP_ID)
WHEN MATCHED THEN
UPDATE
GAME ED.'. v_colname |' = TS. TAG_DATA,
ED. LAST_UPDATED_BY = 1, ";
v_stmt: = v_stmt | "ED. LAST_UPDATE_LOGIN = TS.l_last_update_login
WHEN NOT MATCHED THEN
INSERT ('| v_colname |', EXTENSION_ID, EQUIPMENT_PK_KEY, WORKORDER_FK_KEY, SEGMENT_FK_KEY, SHIFT_WORKDAY_FK_KEY, HOUR_FK_KEY, ITEM_FK_KEY, READ_TIME, ATTR_GROUP_ID, LAST_UPDATE_DATE, LAST_UPDATED_BY,';)
v_stmt: =.
v_stmt | ("LAST_UPDATE_LOGIN, CREATED_BY, CREATION_DATE, RECIPE_NUM, RECIPE_VERSION)
VALUES (TS. TAG_DATA, EGO_EXTFWK_S.NEXTVAL, TS. EQUIPMENT_FK_KEY, TS. WORKORDER_FK_KEY, TS. SEGMENT_FK_KEY, TS. SHIFT_WORKDAY_FK_KEY, TS. HOUR_FK_KEY, TS. ITEM_FK_KEY, TS. READ_TIME,';
v_stmt: = v_stmt | "TS. ATTR_GROUP_ID,: 2, 1, TS.l_last_update_login, TS.l_updated_by,: 3, TS. RECIPE_NUM, TS. RECIPE_VERSION)';
V_stmt EXECUTE IMMEDIATE
With the HELP of v_colname,.
SYSDATE,
SYSDATE;
SY.
Maybe you are looking for
-
Help baterry sinks faster after up until ios 9.3.3
After I have my iPhone iOS 9.3.3 it down quickly from 100% to 90% only 1 hour please help me!
-
I need to make a worksheet that shows the different values which is my price of clients for work that we do, but they take 39 percent of the value, so I need to know how to quickly convert the spreadsheet to display the amount I have them for the inv
-
We use the El X 10.11.5 captain recently, we updated the software being offered bij Apple tot the new version of iLife Subsequently, iPhoto was not longer working, and all of our 25 000 photos have been migrated to (imported in) Photos (1.5 V). Unfor
-
AT10LE - model differences?
Hello Son of learning has split the screen on his Tablet AT10LE-A108 excite Pro and I would like to try DIY repair because it is very attached to it! Via Ebay, I can find a screen at reasonable price / digitizer but it says it's only for the model A1
-
I tried to remove DFBFAA.tmp in my temp folder. I still get used by another program/person. Impossible to determine what/who uses. How can I remove this temporary file?