Variable Substitution [message #434760] |
Thu, 10 December 2009 11:02 ![Go to next message Go to next message](/forum/theme/orafaq/images/down.png) |
rkgoyal98
Messages: 39 Registered: October 2009
|
Member |
![rkgoyal_98](/forum/theme/orafaq/images/yahoo.png)
|
|
Hello,
I am a newbee here. I am working on a project. In one of the form i am required to do variable substitution in one of the calculation. Code for the same is like this.
DECLARE
V_RULE VARCHAR2(2000);
BEGIN
SELECT RULE INTO V_RULE FROM PRMARUT WHERE EDCODE = :BLK_PRMAMAS.EDCODE;
:AMT := SELECT &V_RULE FROM DUAL;
END;
RULE column in the table contains a set of calculations that are to be executed to get the value.
& works in SQLPLUS but gives error in forms 10 pl/sql compilation.
how can this be done.
Regards
EDIT: fixed code tags, you only need 1 on each side of the code block - CM
[Updated on: Thu, 10 December 2009 11:04] by Moderator Report message to a moderator
|
|
|
Re: Variable Substitution [message #434762 is a reply to message #434760] |
Thu, 10 December 2009 11:07 ![Go to previous message Go to previous message](/forum/theme/orafaq/images/up.png) ![Go to next message Go to next message](/forum/theme/orafaq/images/down.png) |
cookiemonster
Messages: 13963 Registered: September 2008 Location: Rainy Manchester
|
Senior Member |
|
|
You can't - variable substitution is something sqlplus does. It has no meaning in forms.
I suspect you need to use dynamic sql here. Give an example of the data v_rule contains.
|
|
|
|
Re: Variable Substitution [message #434780 is a reply to message #434760] |
Thu, 10 December 2009 12:13 ![Go to previous message Go to previous message](/forum/theme/orafaq/images/up.png) ![Go to next message Go to next message](/forum/theme/orafaq/images/down.png) |
cookiemonster
Messages: 13963 Registered: September 2008 Location: Rainy Manchester
|
Senior Member |
|
|
It's pretty similar, suggest you read up on execute immediate in the documentation.
Unfortunately you can't use it in forms so you're going to have to move the code into a stored procedure in the datatbase and call that from your form, passing the relevant datablock items.
Something like this:
DECLARE
V_RULE VARCHAR2(2000);
BEGIN
SELECT RULE INTO V_RULE FROM PRMARUT WHERE EDCODE = p_EDCODE;
EXECUTE IMMEDIATE 'SELECT '||v_rule||'from dual' into p_amt;
END;
|
|
|
Re: Variable Substitution [message #434977 is a reply to message #434760] |
Sat, 12 December 2009 10:12 ![Go to previous message Go to previous message](/forum/theme/orafaq/images/up.png) ![Go to next message Go to next message](/forum/theme/orafaq/images/down.png) |
rkgoyal98
Messages: 39 Registered: October 2009
|
Member |
![rkgoyal_98](/forum/theme/orafaq/images/yahoo.png)
|
|
Hello,
I have worked on the code today and made my code as under
FUNCTION CAL_ELECAMT(P_STATE CHAR,P_QUARTERTYPE CHAR,P_FROMDATE DATE,P_TODATE DATE,P_MONTHS NUMBER,P_CONS NUMBER ) RETURN NUMBER
AS
P_RULE VARCHAR(2000);
P_FROMDATE1 DATE;
P_TODATE1 DATE;
P_FROMDATE2 DATE;
P_TODATE2 DATE;
P_RATEFROMDATE DATE;
P_RATETODATE DATE;
R_AMT1 NUMBER;
R_AMT2 NUMBER;
R_AMT NUMBER;
SQLSTM VARCHAR2(2000);
P_UNIT NUMBER;
P_UNITRATE NUMBER;
P_ELECRATE NUMBER;
P_EDRATE NUMBER;
BEGIN
SELECT FROMDATE,NVL(TODATE,SYSDATE) INTO P_RATEFROMDATE,P_RATETODATE FROM PRMAQTRELRATE WHERE STATE = P_STATE AND QUARTERTYPE = P_QUARTERTYPE
AND P_CONS BETWEEN STARTRANGE AND ENDRANGE
AND P_FROMDATE BETWEEN FROMDATE AND NVL(TODATE,SYSDATE);
IF P_TODATE > P_RATETODATE THEN
P_FROMDATE1 := P_FROMDATE;
P_TODATE1 := P_RATETODATE;
P_FROMDATE2 := P_RATETODATE+1;
P_TODATE2 := P_TODATE;
/* SELECT RULE INTO P_RULE FROM PRMAQTRELRATE WHERE STATE = P_STATE AND QUARTERTYPE = P_QUARTERTYPE
AND P_CONS BETWEEN STARTRANGE AND ENDRANGE
AND P_FROMDATE1 BETWEEN FROMDATE AND NVL(TODATE,SYSDATE);
SQLSTM := 'SELECT '||P_RULE||'INTO R_AMT1 FROM PRMAQTRELRATE WHERE STATE = P_STATE AND QUARTERTYPE = P_QUARTERTYPE
AND P_CONS BETWEEN STARTRANGE AND ENDRANGE
AND P_FROMDATE1 BETWEEN FROMDATE AND NVL(TODATE,SYSDATE)';
EXECUTE IMMEDIATE SQLSTM;
SELECT RULE INTO P_RULE FROM PRMAQTRELRATE WHERE STATE = P_STATE AND QUARTERTYPE = P_QUARTERTYPE
AND P_CONS BETWEEN STARTRANGE AND ENDRANGE
AND P_FROMDATE2 BETWEEN FROMDATE AND NVL(TODATE,SYSDATE);
SQLSTM := 'SELECT '||P_RULE||'INTO R_AMT2 FROM PRMAQTRELRATE WHERE STATE = P_STATE AND QUARTERTYPE = P_QUARTERTYPE
AND P_CONS BETWEEN STARTRANGE AND ENDRANGE
AND P_FROMDATE2 BETWEEN FROMDATE AND NVL(TODATE,SYSDATE)';
EXECUTE IMMEDIATE SQLSTM;
R_AMT := NVL(R_AMT1,0)+NVL(R_AMT2,0);*/
ELSE
BEGIN
SELECT UNIT,UNITRATE,ELECRATE,EDRATE,RULE_FORMULLA INTO P_UNIT,P_UNITRATE,P_ELECRATE,P_EDRATE,P_RULE FROM PRMAQTRELRATE
WHERE STATE = P_STATE AND QUARTERTYPE = P_QUARTERTYPE
AND P_CONS BETWEEN STARTRANGE AND ENDRANGE
AND P_FROMDATE BETWEEN FROMDATE AND NVL(TODATE,SYSDATE);
END;
EXECUTE IMMEDIATE 'SELECT ' ||P_RULE || ' FROM DUAL' INTO R_AMT;
/* VALUE OF P_RULE
ROUND((((200*3)+(P_CONS-200)*P_ELECRATE))+(P_CONS*P_EDRATE)+(P_UNIT*P_UNITRATE),0)
THIS STATEMENT WORKS FINE IF RUN WITHOUT EXECUTE IMMEDIATE
SELECT ROUND((((200*3)+(P_CONS-200)*P_ELECRATE))+(P_CONS*P_EDRATE)+(P_UNIT*P_UNITRATE),0) INTO R_AMT FROM DUAL;
*/
END IF;
RETURN R_AMT;
END CAL_ELECAMT;
However i get error ora-00904 and am not able to work out the reason
Kindly help me
regards
[Updated on: Sat, 12 December 2009 10:15] Report message to a moderator
|
|
|
Re: Variable Substitution [message #434979 is a reply to message #434760] |
Sat, 12 December 2009 10:28 ![Go to previous message Go to previous message](/forum/theme/orafaq/images/up.png) ![Go to next message Go to next message](/forum/theme/orafaq/images/down.png) |
cookiemonster
Messages: 13963 Registered: September 2008 Location: Rainy Manchester
|
Senior Member |
|
|
Well you're missing some spaces for starters.
And if you look at my example the INTO <variable> bit goes outside the dynamic string, which is not what you've done.
|
|
|
|
Re: Variable Substitution [message #434982 is a reply to message #434760] |
Sat, 12 December 2009 11:09 ![Go to previous message Go to previous message](/forum/theme/orafaq/images/up.png) ![Go to next message Go to next message](/forum/theme/orafaq/images/down.png) |
cookiemonster
Messages: 13963 Registered: September 2008 Location: Rainy Manchester
|
Senior Member |
|
|
There are spaces missing immediately before two of the INTO's, but since those intos are in the wrong place I wouldn't worry about the space two much.
Standard way of debugging dynamic sql is output the entire dynamic string using dbms_output or similar. If after putting the INTO's in the right place you are still getting errors, do that to see what the problem is.
|
|
|
|
Re: Variable Substitution [message #434986 is a reply to message #434760] |
Sat, 12 December 2009 20:02 ![Go to previous message Go to previous message](/forum/theme/orafaq/images/up.png) ![Go to next message Go to next message](/forum/theme/orafaq/images/down.png) |
rkgoyal98
Messages: 39 Registered: October 2009
|
Member |
![rkgoyal_98](/forum/theme/orafaq/images/yahoo.png)
|
|
Hello,
After further trial and error i could make it work like this
FUNCTION CAL_ELECAMT(P_STATE CHAR,P_QUARTERTYPE CHAR,P_FROMDATE DATE,P_TODATE DATE,P_MONTHS NUMBER,P_CONS NUMBER ) RETURN NUMBER
AS
P_RULE VARCHAR(2000);
P_FROMDATE1 DATE;
P_TODATE1 DATE;
P_FROMDATE2 DATE;
P_TODATE2 DATE;
P_RATEFROMDATE DATE;
P_RATETODATE DATE;
R_AMT1 NUMBER;
R_AMT2 NUMBER;
R_AMT NUMBER;
SQLSTM VARCHAR2(2000);
P_UNIT NUMBER;
P_UNITRATE NUMBER;
P_ELECRATE NUMBER;
P_EDRATE NUMBER;
BEGIN
SELECT FROMDATE,NVL(TODATE,SYSDATE) INTO P_RATEFROMDATE,P_RATETODATE FROM PRMAQTRELRATE WHERE STATE = P_STATE AND QUARTERTYPE = P_QUARTERTYPE
AND P_CONS BETWEEN STARTRANGE AND ENDRANGE
AND P_FROMDATE BETWEEN FROMDATE AND NVL(TODATE,SYSDATE);
IF P_TODATE > P_RATETODATE THEN
P_FROMDATE1 := P_FROMDATE;
P_TODATE1 := P_RATETODATE;
P_FROMDATE2 := P_RATETODATE+1;
P_TODATE2 := P_TODATE;
R_AMT := NVL(R_AMT1,0)+NVL(R_AMT2,0);
ELSE
BEGIN
SELECT UNIT,UNITRATE,ELECRATE,EDRATE,RULE_FORMULLA INTO P_UNIT,P_UNITRATE,P_ELECRATE,P_EDRATE,P_RULE FROM PRMAQTRELRATE
WHERE STATE = P_STATE AND QUARTERTYPE = P_QUARTERTYPE
AND P_CONS BETWEEN STARTRANGE AND ENDRANGE
AND P_FROMDATE BETWEEN FROMDATE AND NVL(TODATE,SYSDATE);
END;
SQLSTM := 'SELECT '||P_RULE||' FROM DUAL ';
EXECUTE IMMEDIATE SQLSTM INTO R_AMT USING P_CONS,P_ELECRATE,P_CONS,P_EDRATE,P_UNIT,P_UNITRATE;
END IF;
RETURN R_AMT;
END CAL_ELECAMT;
But Problem with this is
1. DBMS_OUTPUT was showing correct systax but there was still an error so i tried "execute immediate ..... into .... useing ...." method and the same worked fine as in the above code.
2. Since p_rule is having different values and different no. of variable selected dynamically as such using clause also needs to be changed which is not possible.
3. It appears that execute immediate has some conditions that is causing some trouble but i am not able to get detailed article on the execute immediate
Regards
|
|
|
Re: Variable Substitution [message #434991 is a reply to message #434986] |
Sun, 13 December 2009 03:58 ![Go to previous message Go to previous message](/forum/theme/orafaq/images/up.png) ![Go to next message Go to next message](/forum/theme/orafaq/images/down.png) |
cookiemonster
Messages: 13963 Registered: September 2008 Location: Rainy Manchester
|
Senior Member |
|
|
rkgoyal98 wrote on Sun, 13 December 2009 02:02
2. Since p_rule is having different values and different no. of variable selected dynamically as such using clause also needs to be changed which is not possible.
In that case you might be better off using dbms_sql instead.
rkgoyal98 wrote on Sun, 13 December 2009 02:02
3. It appears that execute immediate has some conditions that is causing some trouble but i am not able to get detailed article on the execute immediate
What trouble? And did you try looking it up in the documentation?
|
|
|
|
Re: Variable Substitution [message #435000 is a reply to message #434999] |
Sun, 13 December 2009 09:36 ![Go to previous message Go to previous message](/forum/theme/orafaq/images/up.png) ![Go to next message Go to next message](/forum/theme/orafaq/images/down.png) |
![](/forum/images/custom_avatars/136107.jpg) |
BlackSwan
Messages: 26766 Registered: January 2009 Location: SoCal
|
Senior Member |
|
|
> However as no. of variables were also changing as such I solved the problem by putting the values of variables in a temprary table.
>Execute statement is now called on the columns of table. The programe is now running fine.
1) data is extracted from existing table
2) data is placed in temp table
3) data is obtained from temp table to construct dynamic SQL
4) dynamic SQL is executed to obtain desired answer.
I doubt this will scale well in multi-user production environment.
[Updated on: Sun, 13 December 2009 09:36] Report message to a moderator
|
|
|
|
|