Home » SQL & PL/SQL » SQL & PL/SQL » calling a function in another function to insert a dml record is failing
calling a function in another function to insert a dml record is failing [message #597842] |
Tue, 08 October 2013 12:29 |
|
912345
Messages: 7 Registered: October 2013
|
Junior Member |
|
|
Hi all ,
Am calling the Function Batch to insert an update statemtnt into Batch_statement table in the DOWNLOAD_FUNC .But its failing with the error
SQL Error : ORA-14551: cannot perform a DML operation inside a query
Please help me....
Below Is the code:
FUNCTION BATCH(numTABLE_ID IN NUMBER, varSTMT IN VARCHAR2) RETURN NUMBER IS
BEGIN
INSERT INTO BATCH_STATEMENT(QUEUE_ID,TABLE_ID,STATEMENT,QUEUE_SEQUENCE_ID)
VALUES (numQUEUE_ID,numTABLE_ID,varSTMT,1);
RETURN 1;
EXCEPTION WHEN OTHERS THEN
PROC_LOG('Failed in BATCH');
PROC_LOG('SQL Error : ' || SUBSTR(SQLERRM,1,1000));
RETURN -1;
END BATCH;
-------------------------------------------------------------------------------
FUNCTION DOWNLOAD_FUNC(numMERCHANT_NUMBER Number) RETURN VARCHAR2 IS
varRETURN_VALUE VARCHAR2(25):= NULL;
numALLOWED_COUNT PROD.COUNTER.ALLOWED_COUNT%TYPE;
numLAST_COUNT_ADDED PROD.COUNTER.LAST_COUNT_ADDED%TYPE;
dtCHANGE_DATE DATE := NULL;
myVar VARCHAR2(32767);
varSTMT VARCHAR2(32767);
Yes_SAS_Mer VARCHAR2(1);
blnSAS_Allowed BOOLEAN ;
BEGIN
BEGIN
SELECT 'Y' into Yes_SAS_Mer
FROM PROD.SAS_ASSIGNED_MERCHANTS sam
WHERE sam.MERCHANT_NUMBER = numMERCHANT_NUMBER;
dbms_output.put_line('GDS_MERCHANT_NUMBER FOUND : ' || numMERCHANT_NUMBER);
EXCEPTION WHEN OTHERS
THEN
dbms_output.put_line('ERROR IN SAM SELECT : ' || SUBSTR (SQLERRM, 1, 1000));
END;
BEGIN
SELECT CHANGE_DATE, LAST_COUNT_ADDED, ALLOWED_COUNT
INTO dtCHANGE_DATE, numLAST_COUNT_ADDED, numALLOWED_COUNT
FROM PROD.COUNTER
WHERE PROCESS_NAME = 'DAILY' AND COUNTER_IND = 'ABCD' AND PROCESS_FLAG = 'Y';
IF dtCHANGE_DATE <= TRUNC(SYSDATE) THEN
numLAST_COUNT_ADDED := 0;
END IF;
EXCEPTION WHEN OTHERS
THEN
numLAST_COUNT_ADDED := 0;
numALLOWED_COUNT := 1;
END;
IF numALLOWED_COUNT >= numLAST_COUNT_ADDED+1 THEN
blnSAS_Allowed :=True;
varSTMT := 'UPDATE PROD.COUNTER ';
varSTMT := varSTMT ||'SET last_count_added = ' || (numLAST_COUNT_ADDED + 1);
varSTMT:= varSTMT||' WHERE process_name = ''DAILY''';
varSTMT := varSTMT ||' AND COUNTER_IND = ''ABCD''';
dbms_output.put_line(' COUNTER STATEMENT FOR UPDATING IS :-' ||varSTMT);
IF BATCH(98,varSTMT)>0 THEN
NULL;
END IF;
ELSE
dbms_output.put_line('REACHED MAX ALLOWED COUNT SO ENDING :'||SYSDATE);
END IF;
IF (Yes_SAS_Mer='Y') or (Not blnSAS_Allowed) THEN
varRETURN_VALUE :='GDS' ;
END IF;
RETURN varRETURN_VALUE ;
EXCEPTION WHEN OTHERS THEN
dbms_output.put_line('FAILED in DOWNLOAD_FUNC ');
dbms_output.put_line('SQL Error : ' || SUBSTR(SQLERRM,1,1000));
RETURN NULL;
END DOWNLOAD_FUNC;
Desc Batch_Statement
QUEUE_ID Number(15) not null,
TABLE_ID Number(2)not null ,
STATEMENT varchar2(4000 byte) not null,
QUEUE_SEQUENCE_ID number(5) not null ;
*BlackSwan added {code} tags. Please do so yourself in the future.
[Updated on: Tue, 08 October 2013 13:22] by Moderator Report message to a moderator
|
|
|
|
|
Re: calling a function in another function to insert a dml record is failing [message #597886 is a reply to message #597848] |
Wed, 09 October 2013 02:21 |
pablolee
Messages: 2882 Registered: May 2007 Location: Scotland
|
Senior Member |
|
|
Lalit, those blocks allow an error to occur without stopping the execution of the outer block:
begin
begin
-- process
exception
--if an exception occurs exit this block gracefully
end;
begin
--this block will execute even if the previous block raised an error
--because the previous block still exited gracefully
--etc etc
end;
/
Don't get me wrong, the actual implementation isn't great here (i.e. using when others rather than trapping explicit errors) but the premise is sound.
|
|
|
|
|
|
|
|
Re: calling a function in another function to insert a dml record is failing [message #597909 is a reply to message #597902] |
Wed, 09 October 2013 04:39 |
Lalit Kumar B
Messages: 3174 Registered: May 2013 Location: World Wide on the Web
|
Senior Member |
|
|
pablolee wrote on Wed, 09 October 2013 14:01Quote:questioning about BEGIN-END in disguise. What does this mean?
I mean, my intention was to tell wbout the exception handling, however, my statement is not clear. It sounds as if I was asking OP about why the BEGIN-END blocks have been used. But my intention was to point to the unuseful exception block.
Thanks to you for making things clear.
|
|
|
Re: calling a function in another function to insert a dml record is failing [message #598141 is a reply to message #597909] |
Thu, 10 October 2013 11:34 |
|
912345
Messages: 7 Registered: October 2013
|
Junior Member |
|
|
Hi pablolee ,Michel Cadot,lalit
Thank you all for taking time and look into it...I have tried using Pragma Autonomous_transaction for DOWNLOAD_FUNC .
This Time ..1)It Inserted the Dml into the Batch_statment table .
3)Updated the prod.counter.last_count_added column .
4)Batch function returned with 1.
So my concern is ,can i use the autonomous transaction here to avoid the error or not... Please suggest or is there any way to fix this issue..
FUNCTION BATCH(numTABLE_ID IN NUMBER, varSTMT IN VARCHAR2) RETURN NUMBER IS
BEGIN
INSERT INTO BATCH_STATEMENT(QUEUE_ID,TABLE_ID,STATEMENT,QUEUE_SEQUENCE_ID)
VALUES (numQUEUE_ID,numTABLE_ID,varSTMT,1);
RETURN 1;
EXCEPTION WHEN OTHERS THEN
PROC_LOG('Failed in BATCH');
PROC_LOG('SQL Error : ' || SUBSTR(SQLERRM,1,1000));
RETURN -1;
END BATCH;
-------------------------------------------------------------------------------
FUNCTION DOWNLOAD_FUNC(numMERCHANT_NUMBER Number) RETURN VARCHAR2 IS
varRETURN_VALUE VARCHAR2(25):= NULL;
PRAGMA AUTONOMOUS_TRANSACTION ;
numALLOWED_COUNT PROD.COUNTER.ALLOWED_COUNT%TYPE;
numLAST_COUNT_ADDED PROD.COUNTER.LAST_COUNT_ADDED%TYPE;
dtCHANGE_DATE DATE := NULL;
myVar VARCHAR2(32767);
varSTMT VARCHAR2(32767);
Yes_SAS_Mer VARCHAR2(1);
blnSAS_Allowed BOOLEAN ;
BEGIN
BEGIN
SELECT 'Y' into Yes_SAS_Mer
FROM PROD.SAS_ASSIGNED_MERCHANTS sam
WHERE sam.MERCHANT_NUMBER = numMERCHANT_NUMBER;
dbms_output.put_line('GDS_MERCHANT_NUMBER FOUND : ' || numMERCHANT_NUMBER);
EXCEPTION WHEN OTHERS
THEN
dbms_output.put_line('ERROR IN SAM SELECT : ' || SUBSTR (SQLERRM, 1, 1000));
END;
BEGIN
SELECT CHANGE_DATE, LAST_COUNT_ADDED, ALLOWED_COUNT
INTO dtCHANGE_DATE, numLAST_COUNT_ADDED, numALLOWED_COUNT
FROM PROD.COUNTER
WHERE PROCESS_NAME = 'DAILY' AND COUNTER_IND = 'ABCD' AND PROCESS_FLAG = 'Y';
IF dtCHANGE_DATE <= TRUNC(SYSDATE) THEN
numLAST_COUNT_ADDED := 0;
END IF;
EXCEPTION WHEN OTHERS
THEN
numLAST_COUNT_ADDED := 0;
numALLOWED_COUNT := 1;
END;
IF numALLOWED_COUNT >= numLAST_COUNT_ADDED+1 THEN
blnSAS_Allowed :=True;
varSTMT := 'UPDATE PROD.COUNTER ';
varSTMT := varSTMT ||'SET last_count_added = ' || (numLAST_COUNT_ADDED + 1);
varSTMT:= varSTMT||' WHERE process_name = ''DAILY''';
varSTMT := varSTMT ||' AND COUNTER_IND = ''ABCD''';
dbms_output.put_line(' COUNTER STATEMENT FOR UPDATING IS :-' ||varSTMT);
BEGIN
myvar :=INSERT_BATCH(96,varSTMT) ;
Commit;
IF myvar >0 THEN
NULL;
END IF;
EXCEPTION
WHEN OTHERS THEN
ROLLBACK;
raise_application_error(-20001,'An error was encountered - '||SQLCODE||' -ERROR- '||SQLERRM);
END;
ELSE
dbms_output.put_line('REACHED MAX ALLOWED COUNT SO ENDING :'||SYSDATE);
END IF;
IF (Yes_SAS_Mer='Y') or (Not blnSAS_Allowed) THEN
varRETURN_VALUE :='GDS' ;
END IF;
RETURN varRETURN_VALUE ;
EXCEPTION WHEN OTHERS THEN
dbms_output.put_line('FAILED in DOWNLOAD_FUNC ');
dbms_output.put_line('SQL Error : ' || SUBSTR(SQLERRM,1,1000));
RETURN NULL;
END DOWNLOAD_FUNC;
|
|
|
|
Re: calling a function in another function to insert a dml record is failing [message #598148 is a reply to message #598142] |
Thu, 10 October 2013 12:09 |
|
912345
Messages: 7 Registered: October 2013
|
Junior Member |
|
|
Hi pablolee ,Michel Cadot,lalit
Thank you all for taking time and look into it...I have tried using Pragma Autonomous_transaction for DOWNLOAD_FUNC .
This Time ..1)It Inserted the Dml into the Batch_statment table .
3)Updated the prod.counter.last_count_added column .
4)Batch function returned with 1.
So my concern is ,can i use the autonomous transaction here to avoid the error or not... Please suggest or is there any way to fix this issue..
FUNCTION BATCH(numTABLE_ID IN NUMBER, varSTMT IN VARCHAR2) RETURN NUMBER IS
BEGIN
INSERT INTO BATCH_STATEMENT(QUEUE_ID,TABLE_ID,STATEMENT,QUEUE_SEQUENCE_ID)
VALUES (numQUEUE_ID,numTABLE_ID,varSTMT,1);
RETURN 1;
EXCEPTION WHEN OTHERS THEN
RETURN -1;
END BATCH;
-------------------------------------------------------------------------------
FUNCTION DOWNLOAD_FUNC(numMERCHANT_NUMBER Number) RETURN VARCHAR2 IS
varRETURN_VALUE VARCHAR2(25):= NULL;
PRAGMA AUTONOMOUS_TRANSACTION ;
numALLOWED_COUNT PROD.COUNTER.ALLOWED_COUNT%TYPE;
numLAST_COUNT_ADDED PROD.COUNTER.LAST_COUNT_ADDED%TYPE;
dtCHANGE_DATE DATE := NULL;
myVar VARCHAR2(32767);
varSTMT VARCHAR2(32767);
Yes_SAS_Mer VARCHAR2(1);
blnSAS_Allowed BOOLEAN ;
BEGIN
BEGIN
SELECT 'Y' into Yes_SAS_Mer
FROM PROD.SAS_ASSIGNED_MERCHANTS sam
WHERE sam.MERCHANT_NUMBER = numMERCHANT_NUMBER;
EXCEPTION WHEN OTHERS
THEN
NULL;
END;
BEGIN
SELECT CHANGE_DATE, LAST_COUNT_ADDED, ALLOWED_COUNT
INTO dtCHANGE_DATE, numLAST_COUNT_ADDED, numALLOWED_COUNT
FROM PROD.COUNTER
WHERE PROCESS_NAME = 'DAILY' AND COUNTER_IND = 'ABCD' AND PROCESS_FLAG = 'Y';
IF dtCHANGE_DATE <= TRUNC(SYSDATE) THEN
numLAST_COUNT_ADDED := 0;
END IF;
EXCEPTION WHEN OTHERS
THEN
numLAST_COUNT_ADDED := 0;
numALLOWED_COUNT := 1;
END;
IF numALLOWED_COUNT >= numLAST_COUNT_ADDED+1 THEN
blnSAS_Allowed :=True;
varSTMT := 'UPDATE PROD.COUNTER ';
varSTMT := varSTMT ||'SET last_count_added = ' || (numLAST_COUNT_ADDED + 1);
varSTMT:= varSTMT||' WHERE process_name = ''DAILY''';
varSTMT := varSTMT ||' AND COUNTER_IND = ''ABCD''';
BEGIN
myvar :=INSERT_BATCH(96,varSTMT) ;
Commit;
IF myvar >0 THEN
NULL;
END IF;
EXCEPTION
WHEN OTHERS THEN
ROLLBACK;
raise_application_error(-20001,'An error was encountered - '||SQLCODE||' -ERROR- '||SQLERRM);
END;
ELSE
END IF;
IF (Yes_SAS_Mer='Y') or (Not blnSAS_Allowed) THEN
varRETURN_VALUE :='GDS' ;
END IF;
RETURN varRETURN_VALUE ;
EXCEPTION WHEN OTHERS THEN
RETURN NULL;
END DOWNLOAD_FUNC;
|
|
|
|
Re: calling a function in another function to insert a dml record is failing [message #598153 is a reply to message #598148] |
Thu, 10 October 2013 13:10 |
pablolee
Messages: 2882 Registered: May 2007 Location: Scotland
|
Senior Member |
|
|
Having a when others without a raise is generally considered to be a bug, and is a very, very poor programming practice. As BS said
Please remove all of these bugs, trap expected exceptions, allow unexpected exceptions to propagate, then post your code again, this time, please format it so that it is more readable (indents particularly help with this as Michel said.
Can you also tell us what exactly it is that you;re trying to do? Why o you need the batch function to be a function? Why do you need to have that insert occur?
|
|
|
Re: calling a function in another function to insert a dml record is failing [message #598154 is a reply to message #598150] |
Thu, 10 October 2013 13:14 |
|
912345
Messages: 7 Registered: October 2013
|
Junior Member |
|
|
Sorry ..here you go
FUNCTION BATCH(numTABLE_ID IN NUMBER, varSTMT IN VARCHAR2) RETURN NUMBER IS
BEGIN
INSERT INTO BATCH_STATEMENT(QUEUE_ID,TABLE_ID,STATEMENT,QUEUE_SEQUENCE_ID)
VALUES (numQUEUE_ID,numTABLE_ID,varSTMT,1);
RETURN 1;
EXCEPTION WHEN OTHERS
THEN
RETURN -1;
END BATCH;
-------------------------------------------------------------------------------
FUNCTION DOWNLOAD_FUNC(numMERCHANT_NUMBER Number) RETURN VARCHAR2 IS
varRETURN_VALUE VARCHAR2(25):= NULL;
numALLOWED_COUNT PROD.COUNTER.ALLOWED_COUNT%TYPE;
numLAST_COUNT_ADDED PROD.COUNTER.LAST_COUNT_ADDED%TYPE;
dtCHANGE_DATE DATE := NULL;
myVar VARCHAR2(32767);
varSTMT VARCHAR2(32767);
Yes_SAS_Mer VARCHAR2(1);
blnSAS_Allowed BOOLEAN ;
BEGIN
BEGIN
SELECT 'Y' into Yes_SAS_Mer
FROM PROD.SAS_ASSIGNED_MERCHANTS sam
WHERE sam.MERCHANT_NUMBER = numMERCHANT_NUMBER;
EXCEPTION WHEN OTHERS
THEN
null ;
END;
BEGIN
SELECT CHANGE_DATE, LAST_COUNT_ADDED, ALLOWED_COUNT
INTO dtCHANGE_DATE, numLAST_COUNT_ADDED, numALLOWED_COUNT
FROM PROD.COUNTER
WHERE PROCESS_NAME = 'DAILY' AND COUNTER_IND = 'ABCD' AND PROCESS_FLAG = 'Y';
IF dtCHANGE_DATE <= TRUNC(SYSDATE) THEN
numLAST_COUNT_ADDED := 0;
END IF;
EXCEPTION WHEN OTHERS
THEN
numLAST_COUNT_ADDED := 0;
numALLOWED_COUNT := 1;
END;
IF numALLOWED_COUNT >= numLAST_COUNT_ADDED+1 THEN
blnSAS_Allowed :=True;
varSTMT := 'UPDATE PROD.COUNTER ';
varSTMT := varSTMT ||'SET last_count_added = ' || (numLAST_COUNT_ADDED + 1);
varSTMT:= varSTMT||' WHERE process_name = ''DAILY''';
varSTMT := varSTMT ||' AND COUNTER_IND = ''ABCD''';
BEGIN
myvar :=INSERT_BATCH(96,varSTMT) ;
Commit;
IF myvar >0 THEN
NULL;
END IF;
ELSE
blnSAS_Allowed :=flase;
END IF;
IF (Yes_SAS_Mer='Y') or (Not blnSAS_Allowed) THEN
varRETURN_VALUE :='GDS' ;
END IF;
RETURN varRETURN_VALUE ;
EXCEPTION WHEN OTHERS
THEN
RETURN NULL;
END DOWNLOAD_FUNC;
|
|
|
|
|
Re: calling a function in another function to insert a dml record is failing [message #598183 is a reply to message #598148] |
Fri, 11 October 2013 01:39 |
flyboy
Messages: 1903 Registered: November 2006
|
Senior Member |
|
|
912345 wrote on Thu, 10 October 2013 19:091)It Inserted the Dml into the Batch_statment table .
3)Updated the prod.counter.last_count_added column .
4)Batch function returned with 1.
No UPDATE statement is called in BATCH function (by the way, in DOWNLOAD_FUNC you are calling INSERT_BATCH, which is totally different function).
If you refer to the content of VARSTMT, it is only stored into BATCH_STATEMENT.STATEMENT column of the newly inserted row.
912345 wrote on Thu, 10 October 2013 19:09So my concern is ,can i use the autonomous transaction here to avoid the error or not...
Wrong concern. Autonomous transaction should not be uset to avoid any error. They should be used to make changes independently on the main transaction. The correct question is: after rolling back the calling transaction, do you want to keep the rows in BATCH_STATEMENT table or should those INSERTs be rolled back too??? It depends on exact requirements on that function, so only you (or the one who designed it) is able to answer it.
Quote:Please suggest or is there any way to fix this issue..
Do not call it (most probably DOWNLOAD_FUNC) in a query, call it in PL/SQL assignment (as you did with INSERT_BATCH).
As you did not post its call here, there is nothing more to suggest.
|
|
|
Re: calling a function in another function to insert a dml record is failing [message #598233 is a reply to message #598183] |
Fri, 11 October 2013 11:16 |
|
912345
Messages: 7 Registered: October 2013
|
Junior Member |
|
|
No UPDATE statement is called in BATCH function (by the way, in DOWNLOAD_FUNC you are calling INSERT_BATCH, which is totally different function).
--Batch is a typo , the fuicntion name is Insert_Batch .
If you refer to the content of VARSTMT, it is only stored into BATCH_STATEMENT.STATEMENT column of the newly inserted row.
Yes.the actual process is to store the record in the bath_satement table and then the record will be executed by a fucntion alled execute_batch_statement as below..(here the dml will happen).
am just pasting few lines as below :
FUNCTION execute_batch_statement return varchar2 is
varBATCH_STATEMENT VARCHAR2(32767):= NULL;
CURSOR BATCH_STATEMENT_CUR IS
SELECT TABLE_ID, STATEMENT
FROM BATCH_STATEMENT
WHERE QUEUE_ID = numQUEUE_ID --(this is a sequence_id)
ORDER BY TABLE_ID,QUEUE_SEQUENCE_ID;
---------------------------------------------
varBATCH_STATEMENT := BATCH_STATEMENT_REC.STATEMENT;
-----------
varBATCH_STATEMENT := REPLACE(varBATCH_STATEMENT,'''SYSDATE''','TO_DATE('''||varSYS_DATE_STRING||''',''YYYYMMDDHH24MISS'')');
------------
EXECUTE IMMEDIATE varBATCH_STATEMENT;
My question was not about the auditing purpose of the records into Batch_statement table.
Here when the records are stored into the batch_statement table ,and are called by the same pacakge.fucntion to excute the dml statements.
So is it the correct way to use the autonomous transaction in a funciton to call another function with a dml statement ?
|
|
|
|
|
Re: calling a function in another function to insert a dml record is failing [message #598248 is a reply to message #598233] |
Fri, 11 October 2013 13:41 |
flyboy
Messages: 1903 Registered: November 2006
|
Senior Member |
|
|
912345 wrote on Fri, 11 October 2013 18:16--Batch is a typo , the fuicntion name is Insert_Batch .
Unfortunately, Oracle does not "self-correct" typos (e.g "fuicntion" in the above sentence, if you would enter it anywhere). How can anyone in the forum distinguish between wrong statements you ran and typos you made when posting?
912345 wrote on Fri, 11 October 2013 18:16So is it the correct way to use the autonomous transaction in a funciton to call another function with a dml statement ?
It depends on the answer on my question: flyboy wrote on Fri, 11 October 2013 08:39after rolling back the calling transaction, do you want to keep the rows in BATCH_STATEMENT table or should those INSERTs be rolled back too???
When using AUTONOMOUS TRANSACTION, do not be surprised that BATCH_STATEMENT will contain the newly added rows even after the main transaction fails anywhere after the call to DOWNLOAD_FUNC.
912345 wrote on Fri, 11 October 2013 19:43Please suggest other than thought what would be the solution ...??
Again, you should read my post to the end, as the answer is there: flyboy wrote on Fri, 11 October 2013 08:39Do not call it (most probably DOWNLOAD_FUNC) in a query, call it in PL/SQL assignment (as you did with INSERT_BATCH).
As you did not post its call here, there is nothing more to suggest.
|
|
|
Re: calling a function in another function to insert a dml record is failing [message #598259 is a reply to message #598242] |
Fri, 11 October 2013 16:02 |
Lalit Kumar B
Messages: 3174 Registered: May 2013 Location: World Wide on the Web
|
Senior Member |
|
|
912345 wrote on Fri, 11 October 2013 23:13Lailt ..
Please suggest other than thought what would be the solution ...??
because when i used the autonomous transaction ,everything worked as expected for me ....
Firstly, Autonomous transactions are commonly used by error logging routines, where the error messages must be preserved, regardless of the the commit/rollback status of the transaction.
|
|
|
Re: calling a function in another function to insert a dml record is failing [message #598332 is a reply to message #598259] |
Sun, 13 October 2013 21:11 |
|
912345
Messages: 7 Registered: October 2013
|
Junior Member |
|
|
@flyboy :
The DOWNLOAD_FUNC is calling by a procedure FINAL based on the record data in the Fields table ....
PROCEDURE FINAL(varUPDATE_TYPE VARCHAR2,varTABLE_NAME VARCHAR2 ) IS
CURSOR IM_FIELDS IS (SELECT F.COLUMN_NAME,F.SELECT_FUNC,F.EXE_FUNC,F.IM_FIELD
FROM FIELDS F , CHANGE C
WHERE F.IMP_FIELD IS NOT NULL
AND F.IM_FIELD = C.FIELD_ID
AND F.FIELD_ID NOT IN(SELECT C.FIELD_ID FROM CHANGE C, FIELDS F WHERE C.FIELD_ID = F.FIELD_ID AND F.IM_FIELD <>C.FIELD_ID AND C.QUEUE_ID = numQUEUE_ID)
AND C.QUEUE_ID = numQUEUE_ID --(this Queue_id is a sequence # assigned globaly.)
AND F.TABLE_NAME = varTABLE_NAME);
varDEFAULT VARCHAR2(255):=NULL;
BEGIN
FOR IM_FIELDS_REC IN IM_FIELDS LOOP
IF varUPDATE_TYPE = 'A' THEN
varFUNC_RESULT := NULL;
varFUNC_STATEMENT := NULL;
IF IMP_FIELDS_REC.EXE_FUNC IS NULL THEN -- (this column has null value )
varFUNC_STATEMENT := 'SELECT BATCH.' || IMP_FIELDS_REC.SELECT_FUNC || '(''' || varUPDATE_TYPE || ''', ''' || IM_FIELDS_REC.COLUMN_NAME || ''', NULL,'''|| ''', ''' || IM_FIELDS_REC.IM_FIELD || ''') FROM DUAL'; --DOWNLOAd_func is called from here.
BEGIN
EXECUTE IMMEDIATE varFUNC_STATEMENT INTO varFUNC_RESULT ;
END;
END IF;
END IF;
END LOOP;
END final;
This is the table structure and record values for FIELDs for DOWNLOAD_FUNC
DAta setup in the Fields table for the Download_func
COLUMN_NAME SELECT_FUNC EXE_FUNC IM_FIELD TABLE_NAME
OWN_SYS DOWNLOAD_FUNC 22222 MINAL
Purpose of Dowload_func is to set the MINAL.OWN_SYS
|
|
|
|
Re: calling a function in another function to insert a dml record is failing [message #598334 is a reply to message #597842] |
Sun, 13 October 2013 23:33 |
flyboy
Messages: 1903 Registered: November 2006
|
Senior Member |
|
|
@BlackSwan: I am sure that were just small "typos" like call of different function in previous posts; I have no idea for its reason, but I would bet on laziness.
@912345: Just meditate over the difference between the present call (by the way, using SELECT FROM DUAL for variable assignment is bad practice in PL/SQL)
declare
l_dynamic_func varchar2(100) := 'regexp_instr';
l_source_str varchar2(100) := 'Am I understanding SQL?';
l_regexp_mask varchar2(100) := 'Sql';
l_match_param varchar2(1) := 'i';
varfunc_result integer;
begin
EXECUTE IMMEDIATE 'SELECT '||l_dynamic_func||'( ''' || l_source_str || ''', ''' || l_regexp_mask || ''', 1, 1, 0, ''' || l_match_param || ''') FROM DUAL'
INTO varfunc_result;
--dbms_output.put_line( 'result: '||to_char(varfunc_result) );
end; and simple variable assignment from a dynamic statement declare
l_dynamic_func varchar2(100) := 'regexp_instr';
l_source_str varchar2(100) := 'Am I understanding SQL?';
l_regexp_mask varchar2(100) := 'Sql';
l_match_param varchar2(1) := 'i';
varfunc_result integer;
begin
EXECUTE IMMEDIATE 'begin :res := '||l_dynamic_func||'( :l_source_str, :l_regexp_mask, 1, 1, 0, :l_match_param ); end;'
USING OUT varfunc_result, l_source_str, l_regexp_mask, l_match_param;
--dbms_output.put_line( 'result: '||to_char(varfunc_result) );
end;
And the very important thing to mention: do not forget to bind the literals that change as I did in the second block of demonstration code (as you can see, it is also much more transparent than concatenating string variables).
http://www.akadia.com/services/ora_bind_variables.html
|
|
|
|
Goto Forum:
Current Time: Wed Apr 24 04:26:49 CDT 2024
|