Question on Dynamic SQL Execution
Hi,
Our company is currently using Oracle 7 but will move to Oracle 8i soon. I am trying to execute a dynamic SQL statement in a function and it always error-out during execution. The SQL statement is NOT doing any update to a table. Its doing a select only. The function is being called during an execution of another dynamic SQL statement in a procedure. Here are examples of the code listing for the procedure and function:
CREATE OR REPLACE PROCEDURE TEST_PROC
lookup_cursor integer;
ignore integer;
VARvalue number;
begin
lookup_cursor := DBMS_SQL.open_cursor;
DBMS_SQL.PARSE( lookup_cursor,
'SELECT ' || TEST_FUNCTION || ' FROM DUAL,
DBMS_SQL.NATIVE);
DBMS_SQL.DEFINE_COLUMN( lookup_cursor, 1, VARvalue);
ignore := DBMS_SQL.EXECUTE(lookup_cursor);
loop
IF DBMS_SQL.FETCH_ROWS(lookup_cursor) > 0 THEN
DBMS_SQL.COLUMN_VALUE(lookup_cursor, 1, VARvalue);
ELSE
EXIT;
END IF;
END LOOP;
DBMS_SQL.CLOSE_CURSOR(lookup_cursor);
end TEST_PROC;
CREATE OR REPLACE PROCEDURE TEST_FUNCTION
lookup_cursor integer;
ignore integer;
VARvalue number;
VARsql_string VARCHAR2(200);
begin
lookup_cursor := DBMS_SQL.open_cursor;
VARsql_string := SOME GENERATED SQL STATEMENT;
DBMS_SQL.PARSE( lookup_cursor,
VARsql_string,
DBMS_SQL.NATIVE);
DBMS_SQL.DEFINE_COLUMN( lookup_cursor, 1, VARvalue);
ignore := DBMS_SQL.EXECUTE(lookup_cursor);
loop
IF DBMS_SQL.FETCH_ROWS(lookup_cursor) > 0 THEN
DBMS_SQL.COLUMN_VALUE(lookup_cursor, 1, VARvalue);
ELSE
EXIT;
END IF;
END LOOP;
RETURN VARvalue;
end TEST_FUNCTION;
The error I received during execution of TEST_PROC is:
ORA-06571: Function TEST_FUNCTION does not guarantee not to update database
ORA-06512: at "SYS.DBMS_SYS_SQL", line 239
ORA-06512: at "SYS.DBMS_SQL", line 32
It may seem like the example procedure doesnt need to use a dynamic SQL execution to call TEST_FUNCTION but the actual code that I extracted from does.
Does Oracle 7 always treat the dynamic SQL command set as some kind of update statement? Is that a bug? I understand that the EXECUTE IMMEDIATE command in Oracle 8i will replace the old command set found in the above examples. Will using the new EXECUTE IMMEDIATE command in Oracle 8i solve this problem?
Thank you for any help,
Tony
In Oracle 7, for a function to be called from a select statement it has to follow the 'purity rule' that it does not modify any database table or package variable.
Probably you will have to use the compiler directive PRAGMA RESTRICT_REFERENCES (WNDS,WNPS) on your TEST_FUNCTION so that it can be called within a SQL statement.
This restriction is removed in Oracle 8i onwards.
Hope this solves your problem.
Regards
Similar Messages
-
Improving Performance of Dynamic SQL in Pro*C
I am using Dynamic sql format 3 in pro*C,
i.e prepare sqlstmt from :sql_stmt
declare cursor c1 for sqlstmt
But the query is slow .I am also using
order by with ltrim(rtrim(colname))
& sometimes group by .
can anyone tell how to improve performance
of cursors in dynamic sql,or how can
I use the same in Pl/sql with simultaneous
printing of the rows returned,on a file.
nullManoj,
Typically, the slow performance is due to the SQL statement itself rather than the dynamic SQL execution code in Pro*C.
Check your explain plan to see if the query performs well. I suspect that you will find your problem here. -
Dynamic SQL and GRANT CREATE ANY TABLE
hi gurus,
i have a dynamic SQL in a procedure where a table will be created from an existing table without data.
strSQL:='create table ' || strTemp || ' as select * from ' || strArc || ' where 1=2';
execute immediate strSQL;
without GRANT CREATE ANY TABLE for the user, *"ORA-01031: insufficient privileges"* error during execution.
Is there a way to tackle this issue without providing GRANT CREATE ANY TABLE privilige?
many thanks,
Charlesravikumar.sv wrote:
The problem is not because of dynamic sql...It probably has something to do with dynamic SQL or, more accurately, dynamic SQL within a stored procedure.
From a SQL*Plus command prompt, you can create a table if your account has the CREATE TABLE privilege either granted directly to it or granted to a role that has been granted to your account. Most people probably have the CREATE TABLE privilege through a role (hopefully a custom "developer role" that has whatever privileges you grant to users that will own objects but potentially through the default RESOURCE role). That is not sufficient to create tables dynamically via a definer's rights stored procedure. Only privileges that are granted directly to the user, not those granted via a role, are visible in that case.
I expect that the DBAs are granting the CREATE ANY TABLE privilege directly to the account in question rather than through whatever role(s) are being used which is why that appears to solve the problem.
Justin -
Dynamic SQL and 255 bytes per line limit
I would like to create a Dynamic SQL statement that is longer than 255 bytes. What do I need to do to embed a carriage return or something so that the resultant string is broken up into multiple lines?
Please ignore. This was a stupid question!
-
Dynamic SQL and PL/SQL Gateway
This question is kind of out of curiosity...I had created a procedure that used some dynamic sql (execute immediate), and was trying to use it on pl/sql gateway. I kept getting page not found errors until I removed the execute immediate statement, and reverted to using static sql statements.
I am just curious, is dynamic sql not supported at all with pl/sql gateway?
Thanks
Kevin> Relax damorgan, no need to be condescending. Of course I read the docs ..
Well, you're one of the few that actually read the docs.. And one of many that lacked to state any real technical details for forum members to understand the actual problem, the actual error, and what the environment is that this is happening in.
Remember that you came to this forum for forum members to help you. In order for us to do that, you need to help us understand
- your problem
- your environment
- what you have tried
What PL/SQL Gateway do you refer to? Thus is an old term for an old product - today in Oracle there are two "gateways" into the PL/SQL engine via HTTP. Via Apache/mod_plsql and via the internal Java servlet web engine called EPG inside Oracle.
As for what the "Gateway" access to the PL/SQL engine via HTTP.. whether it supports EXECUTE IMMEDIATE or not is like asking if a car "supports" soft drinks or not (just because a human that may consume soft drinks acts as the driver of the car). Not sensible or relevant at all.
mod_plsql creates an Oracle session to the database instance, and executes a PL/SQL procedure in the database. This is no different from any other client connection to Oracle. Oracle has no clue that the client is mod_plsql and not TOAD or Java or VB or PHP or Perl or whatever else.
So how can this support or not support the EXECUTE IMMEDIATE command? Does PL/SQL support EXECUTE IMMEDIATE? Well duh...
Why do you get a generic 404? Because the PL/SQL call made by mod_plsql failed with an unhandled exception. mod_plsql gets that exception and now what? Was a valid HTP buffer created for it to stream to the web browser? If the buffer perhaps partially completed? All that mod_plsql knows is that it asked for a HTP buffer via that PL/SQL call and it got an exception in return.
A 404 HTTP error is the only reasonable and logical response for it to pass to the web browser in this case.
PS. to see why mod_plsql fail, refer to the access_log and error_log of that Apache httpd server -
ORA-01008 with ref cursor and dynamic sql
When I run the follwing procedure:
variable x refcursor
set autoprint on
begin
Crosstab.pivot(p_max_cols => 4,
p_query => 'select job, count(*) cnt, deptno, row_number() over (partition by job order by deptno) rn from scott.emp group by job, deptno',
p_anchor => Crosstab.array('JOB'),
p_pivot => Crosstab.array('DEPTNO', 'CNT'),
p_cursor => :x );
end;I get the following error:
^----------------
Statement Ignored
set autoprint on
begin
adsmgr.Crosstab.pivot(p_max_cols => 4,
p_query => 'select job, count(*) cnt, deptno, row_number() over (partition by
p_anchor => adsmgr.Crosstab.array('JOB'),
p_pivot => adsmgr.Crosstab.array('DEPTNO', 'CNT'),
p_cursor => :x );
end;
ORA-01008: not all variables bound
I am running this on a stored procedure as follows:
create or replace package Crosstab
as
type refcursor is ref cursor;
type array is table of varchar2(30);
procedure pivot( p_max_cols in number default null,
p_max_cols_query in varchar2 default null,
p_query in varchar2,
p_anchor in array,
p_pivot in array,
p_cursor in out refcursor );
end;
create or replace package body Crosstab
as
procedure pivot( p_max_cols in number default null,
p_max_cols_query in varchar2 default null,
p_query in varchar2,
p_anchor in array,
p_pivot in array,
p_cursor in out refcursor )
as
l_max_cols number;
l_query long;
l_cnames array;
begin
-- figure out the number of columns we must support
-- we either KNOW this or we have a query that can tell us
if ( p_max_cols is not null )
then
l_max_cols := p_max_cols;
elsif ( p_max_cols_query is not null )
then
execute immediate p_max_cols_query into l_max_cols;
else
RAISE_APPLICATION_ERROR(-20001, 'Cannot figure out max cols');
end if;
-- Now, construct the query that can answer the question for us...
-- start with the C1, C2, ... CX columns:
l_query := 'select ';
for i in 1 .. p_anchor.count
loop
l_query := l_query || p_anchor(i) || ',';
end loop;
-- Now add in the C{x+1}... CN columns to be pivoted:
-- the format is "max(decode(rn,1,C{X+1},null)) cx+1_1"
for i in 1 .. l_max_cols
loop
for j in 1 .. p_pivot.count
loop
l_query := l_query ||
'max(decode(rn,'||i||','||
p_pivot(j)||',null)) ' ||
p_pivot(j) || '_' || i || ',';
end loop;
end loop;
-- Now just add in the original query
l_query := rtrim(l_query,',')||' from ( '||p_query||') group by ';
-- and then the group by columns...
for i in 1 .. p_anchor.count
loop
l_query := l_query || p_anchor(i) || ',';
end loop;
l_query := rtrim(l_query,',');
-- and return it
execute immediate 'alter session set cursor_sharing=force';
open p_cursor for l_query;
execute immediate 'alter session set cursor_sharing=exact';
end;
end;
/I can see from the error message that it is ignoring the x declaration, I assume it is because it does not recognise the type refcursor from the procedure.
How do I get it to recognise this?
Thank you in advanceThank you for your help
This is the version of Oracle I am running, so this may have something to do with that.
Oracle9i Enterprise Edition Release 9.2.0.8.0 - Production
With the Partitioning, OLAP and Oracle Data Mining options
JServer Release 9.2.0.8.0 - Production
I found this on Ask Tom (http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:3027089372477)
Hello, Tom.
I have one bind variable in a dynamic SQL expression.
When I open cursor for this sql, it gets me to ora-01008.
Please consider:
Connected to:
Oracle8i Enterprise Edition Release 8.1.7.4.1 - Production
JServer Release 8.1.7.4.1 - Production
SQL> declare
2 type cur is ref cursor;
3 res cur;
4 begin
5 open res for
6 'select * from (select * from dual where :p = 1) connect by 1 = 1'
7 using 1;
8 end;
9 /
declare
ERROR at line 1:
ORA-01008: not all variables bound
ORA-06512: at line 5
SQL> declare
2 type cur is ref cursor;
3 res cur;
4 begin
5 open res for
6 'select * from (select * from dual where :p = 1) connect by 1 = 1'
7 using 1, 2;
8 end;
9 /
PL/SQL procedure successfully completed.
And if I run the same thing on 10g -- all goes conversely. The first part runs ok, and the second
part reports "ORA-01006: bind variable does not exist" (as it should be, I think). Remember, there
is ONE bind variable in sql, not two. Is it a bug in 8i?
What should we do to avoid this error running the same plsql program code on different Oracle
versions?
P.S. Thank you for your invaluable work on this site.
Followup June 9, 2005 - 6pm US/Eastern:
what is the purpose of this query really?
but it would appear to be a bug in 8i (since it should need but one). You will have to work that
via support. I changed the type to tarray to see if the reserved word was causing a problem.
variable v_refcursor refcursor;
set autoprint on;
begin
crosstab.pivot (p_max_cols => 4,
p_query =>
'SELECT job, COUNT (*) cnt, deptno, ' ||
' ROW_NUMBER () OVER ( ' ||
' PARTITION BY job ' ||
' ORDER BY deptno) rn ' ||
'FROM emp ' ||
'GROUP BY job, deptno',
p_anchor => crosstab.tarray ('JOB'),
p_pivot => crosstab.tarray ('DEPTNO', 'CNT'),
p_cursor => :v_refcursor);
end;
/Was going to use this package as a stored procedure in forms but I not sure it's going to work now. -
Insert into using a select and dynamic sql
Hi,
I've got hopefully easy question. I have a procedure that updates 3 tables with 3 different update statements. The procedure goes through and updates through ranges I pass in. I am hoping to create another table which will pass in those updates as an insert statement and append the data on to the existing data.
I am thinking of using dynamic sql, but I am sure there is an easy way to do it using PL/SQL as well. I have pasted the procedure below, and what I'm thinking would be a good way to do it. Below I have pasted my procedure and the bottom is the insert statement I want to use. I am faily sure I can do it using dynamic SQL, but I am not familiar with the syntax.
CREATE OR REPLACE PROCEDURE ACTIVATE_PHONE_CARDS (min_login in VARCHAR2, max_login in VARCHAR2, vperc in VARCHAR2) IS
BEGIN
UPDATE service_t SET status = 10100
WHERE poid_id0 in
(SELECT poid_id0 FROM service_t
WHERE poid_type='/service/telephony'
AND login >= min_login AND login <= max_login);
DBMS_OUTPUT.put_line( 'Service Status:' || sql%rowcount);
UPDATE account_t SET status = 10100
WHERE poid_id0 IN
(SELECT account_obj_id0 FROM service_t
WHERE poid_type = '/service/telephony'
AND login >= min_login AND login <= max_login);
DBMS_OUTPUT.put_line( 'Account Status:' || sql%rowcount);
UPDATE account_nameinfo_t SET title=Initcap(vperc)
WHERE obj_id0 IN
(SELECT account_obj_id0 FROM service_t
WHERE poid_type='/service/telephony'
AND login >=min_login AND login <= max_login);
DBMS_OUTPUT.put_line('Job Title:' || sql%rowcount);
INSERT INTO phone_card_activation values which = 'select a.status, s.status, s.login, to_char(d.sysdate,DD-MON-YYYY), ani.title
from account_t a, service_t s, account_nameinfo_t ani, dual d
where service_t.login between service_t.min_login and service_t.max_login
and ani.for_key=a.pri_key
and s.for_key=a.pri_key;'
END;
Thanks for any advice, and have a good weekend.
GeordieCorrect my if I am wrong but aren't these equal?
UPDATE service_t SET status = 10100
WHERE poid_id0 in
(SELECT poid_id0 FROM service_t
WHERE poid_type='/service/telephony'
AND login >= min_login AND login <= max_login);
(update all the records where there id is in the sub-query that meet the WHERE Clause)
AND
UPDATE service_t SET status = 10100
WHERE poid_type='/service/telephony'
AND login >= min_login AND login <= max_login);
(update all the records that meet the WHERE Clause)
This should equate to the same record set, in which case the second update would be quicker without the sub-query. -
Performance between SQL Statement and Dynamic SQL
Select emp_id
into id_val
from emp
where emp_id = 100
EXECUTE IMMEDIATE
'Select '|| t_emp_id ||
'from emp '
'where emp_id = 100'
into id_valWill there be more impact in performance while using Dynamic SQL?CP wrote:
Will there be more impact in performance while using Dynamic SQL?All SQLs are parsed and executed as SQL cursors.
The 2 SQLs (dynamic and static) results in the exact same SQL cursor. So both methods will use an identical cursor. There are therefore no performance differences ito of how fast that SQL cursor will be.
If an identical SQL cursor is not found (a soft parse), the SQL engine needs to compile the SQL source code supplied, into a SQL cursor (a hard parse).
Hard parsing burns a lot of CPU cycles. Soft parsing burns less CPU cycles and is therefore better. However, no parsing at all is the best.
To explain: if the code creates a cursor (e.g. INSERT INTO tab VALUES( :1, :2, :3 ) for inserting data), it can do it as follows:
while More Data Found loop
parse INSERT cursor
bind variables to INSERT cursor
execute INSERT cursor
close INSERT cursor
end loopIf that INSERT cursor does not yet exists, it will be hard parsed and a cursor created. Each subsequent loop iteration will result in a soft parse.
However, the code will be far more optimal as follows:
parse INSERT cursor
while More Data Found loop
bind variables to INSERT cursor
execute INSERT cursor
end loop
close INSERT cursorWith this approach the cursor is parsed (hard or soft), once only. The cursor handle is then used again and again. And when the application is done inserting data, the cursor handle is released.
With dynamic SQL in PL/SQL, you cannot really follow the optimal approach - unless you use DBMS_SQL (a complex cursor interface). With static SQL, the PL/SQL's optimiser can kick in and it can optimise its access to the cursors your code create and minimise parsing all together.
This is however not the only consideration when using dynamic SQL. Dynamic SQL makes coding a lot more complex. The SQL code can now only be checked at execution time and not at development time. There is the issue of creating shareable SQL cursors using bind variables. There is the risk of SQL injection. Etc.
So dynamic SQL is seldom a good idea. And IMO, the vast majority of people that post problems here relating to dynamic SQL, are using dynamic SQL unnecessary. For no justified and logical reasons. Creating unstable code, insecure code and non-performing code. -
Dynamic SQL Joining between tables and Primary keys being configured within master tables
Team , Thanks for your help in advance !
I'm looking out to code a dynamic SQL which should refer Master tables for table names and Primary keys and then Join for insertion into target tables .
EG:
INSERT INTO HUB.dbo.lp_order
SELECT *
FROM del.dbo.lp_order t1
where not exists ( select *
from hub.dbo.lp_order tw
where t1.order_id = t2.order_id )
SET @rows = @@ROWCOUNT
PRINT 'Table: lp_order; Inserted Records: '+ Cast(@rows AS VARCHAR)
-- Please note Databse names are going to remain the same but table names and join conditions on keys
-- should vary for each table(s) being configured in master tables
Sample of Master configuration tables with table info and PK Info :
Table Info
Table_info_ID Table_Name
1 lp_order
7 lp__transition_record
Table_PK_Info
Table_PK_Info_ID Table_info_ID PK_Column_Name
2 1 order_id
8 7 transition_record_id
There can be more than one join condition for each table
Thanks you !
Rajkumar YeluguHi Rajkumar,
It is glad to hear that you figured the question out by yourself.
There's a flaw with your while loop in your sample code, just in case you hadn't noticed that, please see below.
--In this case, it goes to infinite loop
DECLARE @T TABLE(ID INT)
INSERT INTO @T VALUES(1),(3),(2)
DECLARE @ID INT
SELECT @ID = MIN(ID) FROM @T
WHILE @ID IS NOT NULL
PRINT @ID
SELECT @ID =ID FROM @T WHERE ID > @ID
So a cursor would be the appropriate option in your case, please reference below.
DECLARE @Table_Info TABLE
Table_info_ID INT,
Table_Name VARCHAR(99)
INSERT INTO @Table_Info VALUES(1,'lp_order'),(7,'lp__transition_record');
DECLARE @Table_PK_Info TABLE
Table_PK_Info_ID INT,
Table_info_ID INT,
PK_Column_Name VARCHAR(99)
INSERT INTO @Table_PK_Info VALUES(2,1,'order_id'),(8,7,'transition_record_id'),(3,1,'order_id2')
DECLARE @SQL NVarchar(MAX),
@ID INT,
@Table_Name VARCHAR(20),
@whereCondition VARCHAR(99)
DECLARE cur_Tabel_Info CURSOR
FOR SELECT Table_info_ID,Table_Name FROM @Table_Info
OPEN cur_Tabel_Info
FETCH NEXT FROM cur_Tabel_Info
INTO @ID, @Table_Name
WHILE @@FETCH_STATUS = 0
BEGIN
SELECT @whereCondition =ISNULL(@whereCondition+' AND ','') +'t1.'+PK_Column_Name+'='+'t2.'+PK_Column_Name FROM @Table_PK_Info WHERE Table_info_ID=@ID
SET @SQL = 'INSERT INTO hub.dbo.'+@Table_Name+'
SELECT * FROM del.dbo.'+@Table_Name+' AS T1
WHERE NOT EXISTS (
SELECT *
FROM hub.dbo.'+@Table_Name+' AS T2
WHERE '+@whereCondition+')'
SELECT @SQL
--EXEC(@SQL)
SET @whereCondition = NULL
FETCH NEXT FROM cur_Tabel_Info
INTO @ID, @Table_Name
END
Supposing you had noticed and fixed the flaw, your answer sharing is always welcome.
If you have any question, feel free to let me know.
Eric Zhang
TechNet Community Support -
Dynamic SQL Error -ORA-00904: invalid identifier
Hello!
I'm really hoping I can get some fast help on this. In the interest of honesty, this is for a university oracle programming assignment. I've searched everywhere I can for the answer and haven't had any luck.
Anyway, the problem in a nutshell. I have to write a package to write a text file. The formatting information for the file is held in a table, which has columns to define the various characteristics like justification, padding character and field value.
RECORDTYPE FIELDNAME FIELDVALUE FIELDSIZE FIELDORDER PADDINGCHAR JUSTIFICATION DATASOURCE
7 CreditTotal v_credit 10 5 '0' LPAD PROGRAM
7 RecordType '7' 1 1 ' ' RPAD HARDCODE
I can build the whole file except this footer. the FieldValue "v_credit" references a variable that has the calculated total of the credit amounts for the file. There are also "v_debit", and "(v_credit-v_debt)" entries.
My question seems simple... How can I use this VARCHAR2 value from the table, and have it reference the variable within a Dynamic SQL string? If I use the textvalue of the column in the SQL string it gives me the invalid identifier error when it hits the EXECUTE IMMEDIATE statement. There is another row for the header which has "to_char(sysdate,'DDMMYYYY')" in it, and that runs fine. I'm assuming because they are native SQL statements and variables.
I have tried encapsulating the v_credit in "s, and using dynamica bind variables but had the same problem passing the names to the USING clause.
The SQL string created by the procedure is: SELECT LPAD(v_credit,10,'0' ) FROM dual
The full error is:
ORA-00904: "V_CREDIT": invalid identifier
ORA-06512: at "BWOOD.PKG_BRIAN", line 108
ORA-06512: at line 2
Line 108 is the EXECUTE IMMEDIATE statement
I would really appreciate someones help! I'm happy to post the procedure I've written, with the caveat that it's sloppy student work and needs cleaning up of all the experimental commented attempts:)
Edited by: user5426606 on 20-May-2009 03:34 - Added a few more facts.Thank you for the fast replies. I'll post a short chunk of code to demonstrate.
The actual procedure is quite a bit longer, but this should give you the idea.
PROCEDURE build_dbfile (p_settlement_date IN DATE, p_settlement_key IN VARCHAR2, p_type IN VARCHAR2) AS
v_sqlString VARCHAR2(4000) := 'SELECT ';
v_rectype NUMBER := 7;
v_line LONG;
v_debit NUMBER := 0;
v_credit NUMBER := 0;
v_nrRecords NUMBER := 0;
CURSOR c_settlement IS... -- to select records for data rows
-- cursor to select the rows with the file formatting and data info
CURSOR c_header IS SELECT NVL(fieldvalue,fieldname) db_field, <---- selects the data column
fieldsize,
NVL(paddingchar, ''' ''') paddingchar,
NVL(justification,'LPAD') justification,
datasource
FROM FSS_DESKBANK_REF
WHERE recordtype = r_rec_types.recordtype
ORDER BY recordType, fieldorder;
-- SELECT to get the SUM of datarows for v_credit
SELECT SUM(transactionamount)
INTO v_credit...
-- SELECT to get the SUM of datarows for v_debit
SELECT SUM(transactionamount)
INTO v_debit....
FOR r_head IN c_header LOOP
v_sqlString := v_sqlString || r_head.justification|| '('
|| r_head.db_field ||','
|| r_head.fieldsize || ','
|| r_head.paddingchar || ')';
v_sqlString := v_sqlString || ' FROM ' || v_tbl_name;
DBMS_OUTPUT.PUT_LINE('SQL --> '||v_sqlString);
EXECUTE IMMEDIATE v_sqlString INTO v_line;
END LOOP;
DBMS_OUTPUT.PUT_LINE(v_line);
END build_dbfile;So the loop goes through the table rows, grabs each data value and formatting column, and builds the sql string, which is then passed to the execute statement. The issue is the ones where the datarow contains a reference to v_credit, and the error is generated. ie r_head.db_field contains the string "v_credit"
Satish, the sql does look like that in the string, but the string is built from the table, not hardcoded. ie v_sqlString = "SELECT LPAD(v_credit,10,'0' ) FROM dual" when it is passed to the EXECUTE IMMEDIATE.
Edited by: user5426606 on 20-May-2009 05:19 -
Using NVL function in Dynamic SQL
Hi ,
I have created a procedure using the Dynamic SqL and while using the NVL() getting the following error . ORA-00936: missing expression.
The query I have written as
SQL_Txt:=' INSERT INTO VF.tblCData (A, B, C, D, E, F,G,H,I,J)
SELECT '||l_A||',
'||l_B||',
'||l_C||',
'||l_D||',
NULL ,
'||L_F||',
NVL('||Param1||',''''),
NVL('||Param2||',''''),
NVL('||Param3||',''''),
NULL
FROM '||ParamTbl1||' WHERE ' ;
and so on.
For Param1 I have data for one execution and Param2 and Param3 is null for that execution.
While executing the same I am getting below
INSERT INTO VF.tblCData (A, B, C, D, E, F,G,H,I,J)
SELECT 25,
1,
7,
6,
NULL ,
5,
NVL(PurchaseDate,''),
NVL(,''),
NVL(,''),
NULL
FROM xyz.PBuyer@pocdb WHERE
and error ORA-00936: missing expression is popping up for Param2 and Param3 NVL(,'')
Any suggestion to resolve this issue is highly appreciable.
Thanks
SudiptaNVL(,''),Where's the first argument to NVL? That's the obvious problem. Empty strings are NULL in Oracle anyway, so just lose the NVL and insert the values...
C:\>
C:\>sqlplus hr/hr
SQL*Plus: Release 11.2.0.3.0 Production on Wed May 8 10:08:53 2013
Copyright (c) 1982, 2011, Oracle. All rights reserved.
Connected to:
Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 - 64bit Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options
SQL> set NULL I_AM_NULL
SQL> create table x(y varchar2(20));
Table created.
SQL> insert into x values ('');
1 row created.
SQL> select * from x;
Y
I_AM_NULL
SQL> -
Dynamic PL/SQL block vs dynamic SQL SELECT
Hi there,
I have a question regarding the optimal way to code a dynamic SELECT INTO statement. Below are the 2 posiibilities I know of:
_1. Dynamically executing the SELECT statement and making use of the INTO clause of the EXECUTE IMMEDIATE statement_
CREATE OR REPLACE FUNCTION get_num_of_employees (p_loc VARCHAR2, p_job VARCHAR2)
RETURN NUMBER
IS
v_query_str VARCHAR2(1000);
v_num_of_employees NUMBER;
BEGIN
v_query_str := 'SELECT COUNT(*) FROM emp_'
|| p_loc
|| ' WHERE job = :bind_job';
EXECUTE IMMEDIATE v_query_str
INTO v_num_of_employees
USING p_job;
RETURN v_num_of_employees;
END;
_2. Encapsulating the SELECT INTO statement in a block and dynamically exectuting the block_
CREATE OR REPLACE FUNCTION get_num_of_employees (p_loc VARCHAR2, p_job VARCHAR2)
RETURN NUMBER
IS
v_query_str VARCHAR2(1000);
v_num_of_employees NUMBER;
BEGIN
v_query_str := 'begin
SELECT COUNT(*) INTO :into_bind FROM emp_'
|| p_loc
|| ' WHERE job = :bind_job;
end;';
EXECUTE IMMEDIATE v_query_str
USING out v_num_of_employees, p_job;
RETURN v_num_of_employees;
END;
I was just wondering which way would be preferred? I know the second method uses a bind variable for the INTO clause, but does the first one also use bind varialbes (no semi-colon)? Any differences in terms of efficiency or speed?
Thanks alot
Edited by: BYS2 on Oct 19, 2011 1:23 AMsybrand_b wrote:
No difference in terms of performance or speed
Both variants will wreck the primary purpose of PL/SQL: to avoid parsing.
When I would see a 'developer' do this, I would fire him on the spot.
Why abuse PL/SQL in such a fashion? Both statements don't require parsing, as there is nothing dynamic in them and indicate a complete lack of understanding of Oracle, or a desire to deliver completely unscalable applications, resulting in end-users desiring to lynch you, and rightly so.
Remove the dynamic SQL or find another job.
Sybrand Bakker
Senior Oracle DBANot dynamic? What if p_loc and p_job were generated dynamically based on user-input? or what if there were potentially thousands of tables that p_loc could refer to? Should I make a CASE statement with a thousand cases?
In addition, the first example was actually taken directly from the official Oracle Database Application Developer's Guide (version 10.2). http://download.oracle.com/docs/cd/B19306_01/appdev.102/b14251/adfns_dynamic_sql.htm#i1006429 - look under 'Sample Single-Row Query Using Native Dynamic SQL' heading. Therefore, if you have any issues with this alleged 'improper' usage of dynamic SQL, perhaps you should go talk to Oracle directly.
While I appreciate your response, I don't think it has occurred that you that not everyone is a 'developer'. In fact, I have only very recently (several days ago) taught myself how to use Oracle SQL, PL/SQL and XMLDB by reading several of the official Oracle language and developer's guides. It is more a passing interest to me as I am working on some medical research which may require the use of a database. I am actually in medical school at the moment but have an undergraduate degree in Electrical and Computer engineering so I am generally well-versed in programming.
Perhaps the next time, you post your rubbish, rude and unhelpful comments, you should stop and think that people come to this forum because they need help and not because they want to be told to 'find another job'. In fact, I am quite certain that I could make you look absolutely stupid in any topic of electrical engineering or medicine.
Please do us all a favour and stop polluting this forum with your vapid posts. While I understand that your behavior is likely a compensatory mechanism to cope with your inferiority complex, know that help IS available if you need it.
Edited by: BYS2 on Oct 19, 2011 2:13 AM -
How to control the maximum time that a dynamic sql can execute
Hi,
I want to restrict the maximum time that a dynamic sql can execute in a plsql block.
If the execution is not completed, the execution should be terminated and a exception should be raised.
Please let me know, if there is any provision for the same in Oracle 10g.
I was reading about Oracle Resource Database Resource Manager, which talks about restricting the maximum time of execution for Oracle session for a user.
However I am not sure, if this can be used to control the execution of dynamic sql in a plsql block.
Please provide some pointers.
Thank you,
Warm Regards,
Navin Srivastavanavsriva wrote:
We are building a messaging framework, which is used to send time sensitive messages to boundary system.I assume this means across application/database/server boundaries? Or is the message processing fully localised in the Oracle database instance?
Every message has a time to live. if the processing of message does not occurs within the specified time, we have to rollback this processing and mark the message in error state.This is a problematic requirement.. Time is not consistent ito data processing on any platform (except real-time ones). For example, messageFoo1 has a TTL (time to live) of 1 sec. It needs to read a number of rows from a table. The mere factor of whether those rows are cached in the database buffer cache, or still residing on disk, will play a major role in execution time. Physical I/O is significantly slower that logical I/O.
As a result, with the rows on disk, messageFoo1 exceeds the 1s TTL and fails. messageFoo2 is an identical message. It now finds most of the rows that were read by messageFoo1 in the buffer cache, enabling it to complete its processing under 1s.
What is the business logic behind the fact that given this approach, messageFoo1 failed, and the identical messageFoo2 succeeded? The only difference was physical versus logical I/O. How can that influence the business validation/requirement model?
If it does, then you need to look instead at a real-time operating system and server platform. Not Windows/Linux/Unix/etc. Not Oracle/SQL-Server/DB2/etc.
TTL is also not time based in other s/w layers and processing. Take for example the traceroute and ping commands for the Internet Protocol (IP) stack. These commands send an ICMP (Internet Control Message Protocol) packet.
This packet is constructed with a TTL value too. When TTL is exceeded, the packet expires and the sender receives a notification packet to that regard.
However, this TTL is not time based, but "+hop+" based. Each server's IP stack that receives an ICMP packet as it is routed through the network, subtracts 1 from the TTL and the forwards the packet (with the new TTL value). When a server's IP stack sees that TTL is zero, it does not forward the packet (with a -1 TTL), but instead responds back to the sender with an ICMP packet informing the sender that the packet's TTL has expired.
As you can see, this is a very sensible and practical implementation of TTL. Imagine now that this is time based.. and the complexities that will be involved for the IP stack s/w to deal with it in that format.
Making exact response/execution times part of the actual functional business requirements need to be carefully considered.. as this is very unusual and typically only found in solutions implemented in real-time systems. -
Hello Everyone
I am using database 11g. Can someone pl suggest what are the rules for putting single quotes for dynamic sql like
1) how many single quotes before/after a sql statement .
2) Rules for putting single quotes if there exists i) a variable in the sql statement
ii) a constant for e.g 100 in the sql statment.
If you could give the answers with a simple select statement, it will be even better !!!
Thanks and regards
Gautamms wrote:
Hello Everyone
I am using database 11g. Can someone pl suggest what are the rules for putting single quotes for dynamic sql like
1) how many single quotes before/after a sql statement .
2) Rules for putting single quotes if there exists i) a variable in the sql statement
ii) a constant for e.g 100 in the sql statment.
If you could give the answers with a simple select statement, it will be even better !!!
Thanks and regards
Gautamwrite the SQL statement as you would for any SQL client & enclose it using Q-quote
http://askanantha.blogspot.com/2007/12/q-quote-operator-introduced-in-oracle.html
Handle: ms
Status Level: Newbie
Registered: Jun 3, 2007
Total Posts: 46
Total Questions: 17 (17 unresolved)
WOW!
*NEVER got any answer in 5+ years & still wasting time here again, still!
You must be an eternal optimist.
I hope I get credited for your FIRST answer. -
Flash chart with dynamic sql query does not display
Hi,
In my schema SIVOA I have a lot of tables declared like this :
CREATE TABLE "SIVOA"."EVV_xxxx"
( "CLEF_VAR" NUMBER(4,0),
"DATE1" DATE,
"VALEUR" NUMBER(16,8) Only the last part of the name changes "xxxx". For example E009, E019, etc....
I am making a chart page with report and want the user to select a name of a table and I will display using dynamic sql query, the table report and chart.
P184_ENAME is a select list returning the last part of the name of the table, fro example 'E009', 'E019', etc.
P8_CLEF_VAR is an item containing a value. This value is a key retrieved like this :SELECT CLEF_VAR
FROM SIVOA.SITE_ECHELLE
WHERE SITE = :P184_ENAMEI built a classic report using a sql dynamic function :DECLARE
x VARCHAR2 (4000);
BEGIN
x := 'SELECT NULL, DATE1, VALEUR FROM SIVOA.EVV_'
|| UPPER(:p184_ename)
|| ' WHERE CLEF_VAR = :p8_clef_var' ;
RETURN (x);
END;:p8_clef_var is an itme containing the value '4544'.
This works perfectly fine !
When I use this sql fucytion into a flash chart it does not work. I get this message "No data found".
I do not understand why a the report get a result and not the chart !
But if i hard-code the number of the CLEF_VAR instead of fetching it from :p8_clef_var I get a nice chart ! Go figure !DECLARE
x VARCHAR2 (4000);
BEGIN
x := 'SELECT NULL, DATE1, VALEUR FROM SIVOA.EVV_'
|| UPPER(:p184_ename)
|| ' WHERE CLEF_VAR = 4544 ' ;
RETURN (x);
I cannot stay with the key (CLEF_VAR) hard-coded unformtunately !
My question is how to get the chart displaying properly ??
Thank you for your kind answers.
ChristianAlex,
Using your request, with the classic report I get results (data), but I get the same message with the Flash chart : "No data found" ! I don't know how to investigate this. i tried many things but nothing works.
Christian
PS I tried this :
DECLARE
X VARCHAR2 (4000);
BEGIN
x := 'SELECT NULL, DATE1, ROUND(VALEUR,2) FROM SIVOA.EVV_'
|| UPPER (:p184_ename) ||
' WHERE CLEF_VAR = '
|| :p8_clef_var ||
' AND DATE1 BETWEEN TO_DATE ('''
||:P8_DATE_DEBUT||''', ''DD/MM/YYYY HH24:MI'') AND TO_DATE ('''
||:P8_DATE_FIN||''', ''DD/MM/YYYY HH24:MI'')'
RETURN (X);
END; But it does not work either. I could find that the SLQ syntax generated is good becaus I put it into an item which display the return done by the pls/sql.
What is sttange also with the classic report is that if I do click on next or previous to see another rows, I get the message "No data found". If I try to export the report I get an excel file with "No data fouid".
Does anybody already tried my "need" here ? i find strange thant I should not be the firs one trying to get a report an tables which name would be "dynamic".
Tahnk you.
Edited by: Christian from France on Feb 13, 2009 3:05 AM
Maybe you are looking for
-
My 1 tb hard disk is detecting but is not showing up in "my computer"
I have bought a 1 tb hp hard disk and its under warrenty the problem with my hard disk is that is dosen't show up in my computers as i insert my hard disk there's a pop up sound of inserting hard disk then it shows that device is ready to uswe but wh
-
Very simple, but not working Table to Flat File
I'm new to ODI, but I am having too much difficulty in performing a very basic task. I have data in a table and I want to load the data to a flat file. I've been all over this board, all over the documentation, and all over the Googles, and I can not
-
Anyone know how to get chromes device emulator to load the /tablet/ or /phone/ content? I published a Adobe Muse website to BC and i get my /tablet/ and /phone/ content when hitting the website with a physical iPhone or iPad, but the chrome device em
-
AS3 iOS Twitter Reader not working
I created a Twitter Feed reader using a tut from fladev.com. By itself, it works GREAT! However when I try to incoroporate it into my fla for compiling into my ipa it doesn't work in my swf. I know that if I compile the twitter reader at runtime wi
-
What is the maximum number of devices that can be linked to the same cloud?
Hi, How many devices can be linked to the same icloud account? Is there a max? Thanks.