I have a question regarding where bind variables can be used in a dynamic SQL statement in PL/SQL.
For example, I know that this is valid:
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;
/
I was wondering if you could use a bind variables in a select statement like this
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(*) INTO :into_bind FROM emp_'
|| p_loc
|| ' WHERE job = :bind_job';
EXECUTE IMMEDIATE v_query_str
USING out v_num_of_employees, p_job;
RETURN v_num_of_employees;
END;
/
Note I used a SELECT INTO statement as my dyamic string and used a bind variable in the INTO clause.
I am currently travelling right now and won't have access to my computer back at home for a few days, but this has been nagging me for a bit. Tried reading the PL/SQL reference but they don't have an example of a select like this.
Thanks
You can bind define variables in a dynamic query using the BULK COLLECT INTO clause. As shown in Example 7-4, you can use that clause in a bulk FETCH or bulk EXECUTE IMMEDIATE statement. Only INSERT , UPDATE , and DELETE statements can have output bind variables.
Executing dynamic SQL queries Dynamic SQL queries are those built at runtime based on one or more variable values. To execute those queries, we must concatenate them into one SQL statement and pass them as a parameter to the sp_executesql stored procedure.
Oracle provides two methods for using dynamic SQL within PL/SQL: native dynamic SQL and the DBMS_SQL package. Native dynamic SQL lets you place dynamic SQL statements directly into PL/SQL code.
In my opinion, a dynamic PL/SQL block is somewhat obscure. While is very flexible, is also hard to tune, hard to debug and hard to figure out what's up. My vote goes to your first option,
EXECUTE IMMEDIATE v_query_str INTO v_num_of_employees USING p_job;
Both uses bind variables, but first, for me, is more redeable and tuneable than @jonearles option.
No you can't use bind variables that way. In your second example :into_bind
in v_query_str
is just a placeholder for value of variable v_num_of_employees
. Your select into statement will turn into something like:
SELECT COUNT(*) INTO FROM emp_...
because the value of v_num_of_employees
is null
at EXECUTE IMMEDIATE
.
Your first example presents the correct way to bind the return value to a variable.
Edit
The original poster has edited the second code block that I'm referring in my answer to use OUT
parameter mode for v_num_of_employees
instead of the default IN
mode. This modification makes the both examples functionally equivalent.
Put the select statement in a dynamic PL/SQL 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;
/
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With