This page is about Oracle bind variables and how to use them with stored procedure. We are trying to keep the examples as simple as possible so explanations are basic using and users’ common mistakes.
To go through the examples below we’ll need a stored procedure. The following script will create “my_bind_test” procedure that has two input parameters: “p_text” and “p_number“. The purpose of the procedure is to show those input parameters on screen using build-in DBMS_OUTPUT procedure. Please take a look at the script below.
CREATE PROCEDURE my_bind_test( p_text VARCHAR2, p_number PLS_INTEGER) IS BEGIN DBMS_OUTPUT.PUT_LINE('p_text:'||p_text||' p_number:'||p_number); END my_bind_test;
Let’s try out the new procedure we just created. To call out the my_bind_test procedure with bind variables we’ll need to execute it dynamically; you can use either command “EXECUTE IMMEDIATE” and bind variables are marked with colon (:) and name. For example in this example the bind variables are “:a” and “:b“. To assigne values to variables there is keyword “USING” and values or PL/SQL variables are following it. We have declared two PL/SQL variables “v_text” as “Hello Bind” and “v_number” as “101“. Thouse values are given to my_bind_test procedure through the “USING” keyword as on the following example.
DECLARE v_text VARCHAR2(10) := 'Hello Bind'; v_number PLS_INTEGER := 101; BEGIN EXECUTE IMMEDIATE ('BEGIN my_bind_test (:a, :b); END;') USING v_text, v_number; END;
The first common mistake is to use same bind variable name for different input parameters and Oracle database will detect that you have declared two input values and using only one of it. The error message in this case is ORA-01006: bind variable does not exist and it says in plain text a bind variable is missing.
DECLARE v_text VARCHAR2(10) := 'Hello Bind'; v_number PLS_INTEGER := 101; BEGIN EXECUTE IMMEDIATE ('BEGIN my_bind_test (:a, :a); END;') USING v_text, v_number; END;
The second mistake would be to set bind variables correctly but mist out some PL/SQL variable and Oracle database will let us know this with error ORA-01008: not all variables bound. The following example has two bind variables “:a” and “:b” and only one PL/SQL variable “v_text” in script body.
DECLARE v_text VARCHAR2(10) := 'Hello Bind'; v_number PLS_INTEGER := 101; BEGIN EXECUTE IMMEDIATE ('BEGIN my_bind_test (:a, :b); END;') USING v_text; END;
Now to continue with mistakes the following one is very common one because loads of examples are showing how to use OUT parameter with bind variables and the PL/SQL stored procedure has created in a different way using only IN parameters. When you forget to check your database procedure or function and you are declaring “OUT” keyword with “USING” keyword the error can be following ORA-06537: OUT bind variable bound to an IN position.
DECLARE v_text VARCHAR2(10) := 'Hello Bind'; v_number PLS_INTEGER := 101; BEGIN EXECUTE IMMEDIATE ('BEGIN my_bind_test (:a, :b); END;') USING OUT v_text, v_number; END;
The last mistake with this stored procedure is executing a stored procedure as SQL query. When you execute a procedure or a function always use “BEGIN” and “END” or “CALL” keywords. The example below does not have any of them and it’s calling out the my_bind_test procedure. The raised error is ORA-00900: invalid SQL statement because Oracle database expects to receive a SQL query.
DECLARE v_text VARCHAR2(10) := 'Hello Bind'; v_number PLS_INTEGER := 101; BEGIN EXECUTE IMMEDIATE ('my_bind_test (:a, :b)') USING v_text, v_number; END;
To try out other examples we’ll need to make some changes in the procedure so to make sure you’ll have the stored procedure with changed code drop the existing procedure first as the following script shows.
DROP PROCEDURE my_bind_test;
Now to create the amended version of my_bind_test use to script below. The stored procedure has two OUT parameters with the same names and types. The DBMS_OUTPUT has replaced with assigning values since they are OUT or returning parameters.
CREATE PROCEDURE my_bind_test( p_text OUT VARCHAR2, p_number OUT PLS_INTEGER) IS BEGIN p_text := 'Hello my_bind_test!'; p_number := 202; END my_bind_test;
The stored procedure has changed and let’s try to call it out with the first PL/SQL script with additional DBMS_OUTPUT command. This time the script doesn’t return two values as it did on the first example and instead we got error ORA-06536: IN bind variable bound to an OUT position. The error is raised because my_bind_test procedure has declared two OUT parameters and we are using them as IN without setting “OUT” keywords. To see how to do it take a look at the example after this following script .
DECLARE v_text VARCHAR2(20); v_number PLS_INTEGER; BEGIN EXECUTE IMMEDIATE ('BEGIN my_bind_test (:a, :b); END;') USING v_text, v_number; DBMS_OUTPUT.PUT_LINE('v_text:'||v_text||' v_number:'||v_number); END;
This anonymous PL/SQL block has only two changes – both PL/SQL variables has “OUT” keyword in front of them. That way declared bind variables will be used as returning variables and Oracle database wouldn’t look for existing values inside them. The output below has values we set to variables inside the stored procedure body.
DECLARE v_text VARCHAR2(20); v_number PLS_INTEGER; BEGIN EXECUTE IMMEDIATE ('BEGIN my_bind_test (:a, :b); END;') USING OUT v_text, OUT v_number; DBMS_OUTPUT.PUT_LINE('v_text:'||v_text||' v_number:'||v_number); END;
Using the OUT parameters quite often people has idea that one OUT keyword would be applying on both following PL/SQL variables. This idea is incorrect because every “IN“, “OUT” or “IN OUT” keyword applies only on following PL/SQL variable and as the example below has only one OUT keyword. This example gets Oracle database error ORA-06536: IN bind variable bound to an OUT position because the second variable is treated as IN parameter type and the stored procedure has both parameters as OUT.
DECLARE v_text VARCHAR2(20); v_number PLS_INTEGER; BEGIN EXECUTE IMMEDIATE ('BEGIN my_bind_test (:a, :b); END;') USING OUT v_text, v_number; DBMS_OUTPUT.PUT_LINE('v_text:'||v_text||' v_number:'||v_number); END;
There is still left to try out paraters with IN OUT option and to do so we’ll need to amend the my_bind_test procedure again. Though you can do it with CREATE OR REPLACE keywords that doesn’t need DROP statement but to play safe we’ll do it with DROP and CREATE statements as the following scripts.
DROP PROCEDURE my_bind_test;
Now create the amended version for the stored procedure.
CREATE PROCEDURE my_bind_test( p_text IN OUT VARCHAR2, p_number IN OUT PLS_INTEGER) IS BEGIN p_text := 'Hello '||p_text; p_number := 1000 + p_number; END my_bind_test;
The following example is using “IN OUT” parameters as they are declared in my_bind_test procedure. Both keywords are set in front of both PL/SQL variables and the script returns on output the values amended by the procedure.
DECLARE v_text VARCHAR2(20) := 'Oracle'; v_number PLS_INTEGER := 33; BEGIN EXECUTE IMMEDIATE ('BEGIN my_bind_test (:a, :b); END;') USING IN OUT v_text, IN OUT v_number; DBMS_OUTPUT.PUT_LINE('v_text:'||v_text||' v_number:'||v_number); END;
Through all examples we have been using only “IN“, “OUT” or “IN OUT” together but you can also use them mixed. The fourth procedure is about using mixed parameter types.
DROP PROCEDURE my_bind_test;
The amended version of the stored procedure.
CREATE PROCEDURE my_bind_test( p_date DATE, p_text OUT VARCHAR2, p_number IN OUT PLS_INTEGER) IS BEGIN NULL; END my_bind_test;
This example shows how to use mixed parameter types and take a look at the declaration behind “USING” keyword. The “v_date” is IN parameters (without “IN“-keyword); “v_text” has set as OUT parameter and “v_number” is IN OUT. Now take a look at the my_bind_test procedure and you’ll see the same parameter type order. The script runs without returning any error.
DECLARE v_date DATE := SYSDATE; v_text VARCHAR2(20) := 'Oracle'; v_number PLS_INTEGER := 44; BEGIN EXECUTE IMMEDIATE ('BEGIN my_bind_test (:a, :b, :c); END;') USING v_date, OUT v_text, IN OUT v_number; END;
The same parameter type mix can be used in different order while it is as the stored procedure or funcion has.
See Also:
Oracle Select Online Tech Support Home