Clarification
A reader, August 09, 2002 - 3:10 pm UTC
I am not sure I understand.
I want to set the value of my_pkg.some_variable.
i.e. If
x varchar2(100) := 'my_pkg.some_variable'
I want to be able to do "something" to x and have it magically set the value of my_pkg.some_variable
August 09, 2002 - 4:36 pm UTC
Fine -- easy enough to do. Simple variation on a theme here:
ops$tkyte@ORA817DEV.US.ORACLE.COM> create or replace procedure set_value_of( p_name in varchar2, p_newval in varchar2 )
2 is
3 begin
4 execute immediate 'begin ' || p_name || ' := :x; end;' using in p_newval;
5 end;
6 /
Procedure created.
ops$tkyte@ORA817DEV.US.ORACLE.COM>
ops$tkyte@ORA817DEV.US.ORACLE.COM> exec set_value_of( 'my_pkg.some_variable', 1023 );
PL/SQL procedure successfully completed.
ops$tkyte@ORA817DEV.US.ORACLE.COM>
ops$tkyte@ORA817DEV.US.ORACLE.COM> exec dbms_output.put_line( 'the value is ' || value_of( 'my_pkg.some_variable' ) );
the value is 1023
PL/SQL procedure successfully completed.
ops$tkyte@ORA817DEV.US.ORACLE.COM> exec dbms_output.put_line( 'the value is ' || value_of( '2 * my_pkg.some_variable' ) );
the value is 2046
PL/SQL procedure successfully completed.
Reader
A reader, May 31, 2003 - 9:33 am UTC
Could you tell me why I get ORA- 903
SQL> create or replace function sumup(p_in varchar2)
2 return number is
3 l_out number;
4 begin
5 execute immediate 'select count(*) into l_out from :x' using in p_in;
6 return l_out;
7 end;
8 /
Function created.
SQL> show errors
No errors.
SQL> select sumup('T_1BYTE') from dual;
select sumup('T_1BYTE') from dual
*
ERROR at line 1:
ORA-00903: invalid table name
ORA-06512: at "USER.SUMUP", line 5
The user 'USER' owns the table 'T-1BYTE'.
Thanks
May 31, 2003 - 11:54 am UTC
you cannot bind identifiers.
You can use binds (should use binds in most cases) where ever you could put a character string literal.
for example:
select * from emp where ename = 'KING'
should be:
select * from emp where ename = :bv;
we can use a bind there because we can use a character string. However, we cannot:
select * from :bv where ename = 'KING'
because
select * from 'EMP' where ename = 'KING'
is not valid.
Reader
A reader, May 31, 2003 - 2:18 pm UTC
Is there an alternate way to write function thar computes
count(*) for a table. I think I saw something similar in
this site before. If identifiers can not be parsed, may be
I was wrong
Thanks
May 31, 2003 - 2:30 pm UTC
it would be
execute immediate 'select count(*) from ' || p_in into some_variable;
setting and getting privat global variable with dynamic procedure/function
ninoslav, August 01, 2003 - 7:24 am UTC
Hi Tom,
could You show the way we could use dynamic sql in procedure to set package body variable and function to get the value from it.
I have used for procedure:
execute immediate 'begin '
|| p_var_txt
|| ' := :x; end;'
using in p_val;
and
execute immediate 'begin :x := '
|| p_var_txt
|| '; end;'
using out lv_value_txt;
return lv_value_txt;
for function but it doesn't work for package body variable.
Thx
August 01, 2003 - 8:03 am UTC
it only works for globally accessible globals - globals in the spec.
the ones in the body are not visible EXCEPT in the body. Just pretend that "execute immediate" is a function call (it is really) -- the dynamically executed sql is taking place in an entirely different scope -- it is not run "in the body", it is called "from the body" -- hence package body variables do not exist.
setting and getting privat global variable with dynamic procedure/function
Ninoslav, August 06, 2003 - 6:03 am UTC
Hi Tom,
thx for Your explanation.
So, to sum up: we can't use dynamic sql for encapsulation data. At least, for now. We have to write explicit proc/function for every variable that we want to use as a privat global variable (package body variable). However, for me, use of dinamic sql for setting package specification variable is very usefull and i'm gonna leave my variables in package specification till something happen about this topic. I know it's not in the spirit of hiding information and advice about enapsulation, but it's much better that write many procedures and functions.
Agree ?
thx
nino
August 06, 2003 - 8:23 am UTC
I agree that using and abusing dynamic sql in order to create "really generic stuff" has an extremely high price to be paid in terms of resource utilization in the server....
be careful with this feature -- the old axiom "too much of a good thing" comes into play here.
Dynamic SQL: Set variable contained in another variable
Michel Meurisse, February 18, 2004 - 4:46 am UTC
Wonderull and seems so easy.
Thanks a lot.
dynamic sql
AD, January 22, 2008 - 6:37 pm UTC
Hi Tom,
Could you please suggest how to approach this. I have a table with certain fields. I have to derive a data element using this table, which is calculated as a function of number of fields of tab_a, however the exact expression is stored in a look up table - tab_b.
create table tab_a
(f1 number
,f2 number
)
create table tab_b
(id number
,expr varchar2(200))
INSERT INTO TAB_A ( F1, F2 ) VALUES ( 100, 1);
INSERT INTO TAB_A ( F1, F2 ) VALUES ( 200, 1);
INSERT INTO TAB_A ( F1, F2 ) VALUES ( 300, 2);
INSERT INTO TAB_A ( F1, F2 ) VALUES ( 400, 3);
INSERT INTO TAB_B ( ID, EXPR ) VALUES (1, 'EXP(-1)F1+F2');
INSERT INTO TAB_B ( ID, EXPR ) VALUES ( 2, 'EXP(-1)*F1-F2');
INSERT INTO TAB_B ( ID, EXPR ) VALUES ( 3, 'EXP(-1)*F1-10*F2');
commit;
SQL> select * from tab_a;
F1 F2
---------- ----------
100 1
200 1
300 2
400 3
select ID, expr from tab_b;
ID
----------
EXPR
--------------------------------------------------------------------------------
1
EXP(-1)*F1+F2
2
EXP(-1)*F1-F2
3
EXP(-1)*F1-10*F2
I would like to get a derived column, which will be added to tab_a, and the logic is:
if tab_a.f2 = tab_b.id then corresponding expression from tab_b will be used.
Many thanks
January 22, 2008 - 7:03 pm UTC
please, for the love of whatever, USE A VIEW
do not store some expression to be dynamically invoked.
DO create or replace a view with this.
Instead of stuffing these expressions into a table, create a view that contains these expressions as selected columns.
use a table if you want, but from the table - CREATE A VIEW.
sonu, June 16, 2011 - 5:08 pm UTC
Hi Tom,
v1 varchar2(50) := 'Main';
v2 number := 5;
v3 varcha2(10) := 'Name';
Now v1 := function () -- this function will return 'v2' ||'#'|| 'v3 -- this is nothing but
combination of two variables's name and store them into one variable.
dbms_output.put_line (v1) will print "v2 ||'#'|| v3" but I want to print 5#Name
is it possible?