use of bind variable - oracle

Can we use a bind variable in oracle inside a procedure or function ?
I'm trying to update a bind variable inside my procedure. Can I do so in any case?
if (condition) then
:v_bind:=10;
end if;
Can I do the above thing inside a procedure or function..?
variable v_bind number;
create procedure abc as v_one
BEGIN
select count(a) into v_one from ab;
if(v_one<>0) then
:v_bind:=10;
end if;
Will I able to do this? It is showing me bad variable v_bind

You can't create a procedure with a bind variable in it because stored procedures are server-side objects and bind variables only exist on the client side.
Suppose I'm using SQL*Plus, and that I've created some bind variables. Once I exit SQL*Plus, any bind variables I created don't exist any more. However, stored procedures have to persist in the database, and hence they can't have any reference to anything that was created and then destroyed on the client.
Here's an example showing that you can't create a procedure that references a bind variable:
SQL> variable i number
SQL> exec :i := 0;
PL/SQL procedure successfully completed.
SQL> print :i
I
----------
0
SQL> create or replace procedure test_proc
2 as
3 begin
4 :i := 9;
5 end;
6 /
Warning: Procedure created with compilation errors.
SQL> show errors procedure test_proc;
Errors for PROCEDURE TEST_PROC:
LINE/COL ERROR
-------- -----------------------------------------------------------------
4/3 PLS-00049: bad bind variable 'I'
You can, however, pass a bind variable as an OUT parameter for a procedure. The procedure can then assign a value to the OUT parameter, and this value will then be stored in your bind variable.
Suppose we have the following procedure:
CREATE OR REPLACE PROCEDURE do_stuff (
p_output OUT INTEGER
)
AS
BEGIN
p_output := 6;
END;
We can use this to set a bind variable as follows:
SQL> variable i number
SQL> exec :i := 0;
PL/SQL procedure successfully completed.
SQL> print :i
I
----------
0
SQL> exec do_stuff(:i);
PL/SQL procedure successfully completed.
SQL> print :i
I
----------
6

No, you cannot do what you are asking. Bind variables in plsql are handled transparently. You do not explicitly code bind variables unless you are going to use 'execute immediate' to run the code outside of plsql like this:
declare
v_bind number := 1;
begin
execute immediate 'select * from table where x = :v_bind';
end;`
The following code uses bind variables as well, but it is handled transparently by plsql:
declare
v_bind number := 1
y number;
begin
select count(*) into y from table where x = v_bind;
end;

You can't bind a sqlplus variable in a session to a function/procedure. It will give you error of "Bad bind variable". You can actually just pass bind variable from your oracle session to any procedure.
Let's see a example
variable v1 NUMBER;
begin
select salary into :v1 from employees where employee_id = 100;
dbms_output.put_line(:v1);
end;
/
And if you run the above example by enclosing in procedure/function it will show you error.
create or replace procedure proc is
begin
select salary into :v1 from employees where employee_id = 100;
dbms_output.put_line(:v1);
end;
/
Error -
PROCEDURE proc compiled
Warning: execution completed with warning
3/20 PLS-00049: bad bind variable 'V1'
4/22 PLS-00049: bad bind variable 'V1'
Thus, it is not possible to use session-level bind variables in procedures/functions. In below example t2 is a bind variable
create or replace procedure proc is
t2 NUMBER;
begin
select salary into t2 from employees where employee_id = 100;
dbms_output.put_line(t2);
end;
/
You can call this procedure from sqlplus as
exec proc;

Related

Can we use Parameter mode directly inside BEGIN part?

CREATE OR REPLACE PROCEDURE do_something(p_a IN OUT VARCHAR2)
AS
BEGIN
p_a := 'something';
END;
/
Procedure created.
SQL> set serveroutput on
SQL> VARIABLE a VARCHAR2(30)
SQL> exec do_something(:a);
PL/SQL procedure successfully completed.
While am execute above procedure, it wont show output called something from procedure. What is the reason, what is happening backend?
The variable holds the value you've assigned in your session context. You can use SQL*Plus PRINT to see it:
SQL> PRINT :a;

Why the select statement is not showing me table while executed in oracle?

I am new to oracle.I already have a table tempash.
So,I created a procedure to see the data of this table.
So,I created procedure as:
create or replace procedure offc.temp_sel(data1 varchar2) is
var1 varchar2(4000);
BEGIN
var1:='select * from offc.temp'||data1;
EXECUTE IMMEDIATE var1;
end;
So,I executed the statement but,it is not showing me anything.
exec offc.temp_sel('ash');
There is no any compilation error in my procedure.But why the select statement is not showing me data of that procedure?
Try adding out parameter:
create or replace procedure offc.temp_sel(data1 varchar2,result out sys_refcursor)
is
BEGIN
open result for 'select * from offc.temp'||data1;
end;
SQL> var rc refcursor
SQL> execute offc.temp_sel('ash',:rc)
PL/SQL procedure successfully completed.
SQL> print rc
You need to keep the result of the SELECT statement into a variable. As you perform SELECT * ..., you should put the result into a RECORD type but, as the result set contains more than 1 row, your variable needs to be a table of records.
In order to not be prone to error, the tables of records needs to be exactly like your table source structure.
CREATE OR REPLACE PROCEDURE OFFC.TEMP_SEL(DATA1 VARCHAR2) IS
VAR1 VARCHAR2(4000);
TYPE T_RESULT IS TABLE OF offc.temp%ROWTYPE;
-- defined the new type based on the structure of table TEMP from schema OFFC
v_result t_result;
-- define a variable of that type.
BEGIN
var1:='select * from offc.temp'||data1;
EXECUTE IMMEDIATE VAR1 BULK COLLECT INTO V_RESULT;
-- collect he result into the new variable
FOR I IN 1 ..v_result.count
LOOP
dbms_output.put_line(v_result(i).<<column_name from temp offc.table>>);
end loop;
-- loop through the variable(table of records) and display its content.
-- you need to replace the << ... >> with the name of your column from source tabel that you want to display.
end;
To execute the procedure, you should use:
set serveroutput on;
execute temp_sel( 'ash');
Best,
Mikcutu

How to call stored procedure with only OUT parameter?

I have created a stored procedure in Oracle 11g:
CREATE OR REPLACE PROCEDURE greetings(cnt OUT VARCHAR2)
AS
BEGIN
SELECT COUNT(*)
INTO cnt
FROM SYS.all_tables;
END greetings;
but I am unable to call it.
I have tried the following code snippets:
EXEC GREETINGS();
EXEC GREETINGS;
CALL GREETINGS;
The procedure requires one parameter, so - provide it.
SQL> CREATE OR REPLACE PROCEDURE greetings(cnt OUT VARCHAR2)
2 AS
3 BEGIN
4 SELECT COUNT(*)
5 INTO cnt
6 FROM SYS.all_tables;
7 END greetings;
8 /
Procedure created.
One option, which works everywhere, is to use an anonymous PL/SQL block:
SQL> set serveroutput on
SQL> declare
2 l_cnt number;
3 begin
4 greetings(l_cnt);
5 dbms_output.put_line(l_cnt);
6 end;
7 /
87
PL/SQL procedure successfully completed.
Another one works in SQL*Plus (or any other tool which is capable of simulating it):
SQL> var l_cnt number;
SQL> exec greetings(:l_cnt);
PL/SQL procedure successfully completed.
SQL> print l_cnt;
L_CNT
----------
87
Regarding the call example, this is explained in EXECUTE recognizes a stored procedure, CALL does not. It's not obvious from the syntax documentation but it does require brackets, so it is (rather unhelpfully) rejecting the whole thing and giving the impression that greetings is the problem, when actually it is not:
SQL> call greetings;
call greetings
*
ERROR at line 1:
ORA-06576: not a valid function or procedure name
while using the mandatory brackets gets you the real issue:
SQL> call greetings();
call greetings()
*
ERROR at line 1:
ORA-06553: PLS-306: wrong number or types of arguments in call to 'GREETINGS'
As others have pointed out, you are missing the parameter.
SQL> var n number
SQL>
SQL> call greetings(:n);
Call completed.
SQL> print :n
N
----------
134
execute is just a handy SQL*Plus shortcut for the PL/SQL block begin xxx; end; which is less fussy about brackets and gives the same error message with or without them.
(variable and print are SQL*Plus commands and may not be supported in other environments.)
There's no problem with the procedure body. You can call like this :
SQL> var nmr number;
SQL> exec greetings(:nmr);
PL/SQL procedure successfully completed
nmr
------------------------------------------
306 -- > <a numeric value returns in string format>
Oracle doesn't care assigning a numeric value to a string. The execution prints the result directly, but whenever you want you can recall that value of variable(nmr) again, and print as
SQL> print nmr
nmr
---------
306

How to write an Oracle procedure with a select statement (Specifically on SQL Developer)?

I want to create a simple Oracle Stored procedure on SQL Developer that will return some records on a simple select query. I do not want to pass in any parameter, but I just want the Records to be returned back from the procedure into a result set -> a suitable variable.
I have been trying to use the following syntax :
create or replace PROCEDURE Getmarketdetails2(data OUT varchar2)
IS
BEGIN
SELECT *
into data
from dual;
END Getmarketdetails2;
But it gives me an error while I try to execute with the following exec statement -->
Declare a Varchar2;
exec Getmarketdetails2(a);
Error: PLS-00103: Encountered the symbol "end-of-file" when expecting "something else".
Cause: Usually a PL/SQL compilation error.
Appreciate if anyone can help me out of this long pending situation! I have tried enough to find a basic guide to create a simple Oracle stored procedure and execute it in SQL Developer, but none of them answer to the point!!
You want:
DECLARE
a VARCHAR2(4000); -- Give it a size
BEGIN -- Begin the anonymous PL/SQL block
Getmarketdetails2(a); -- Call the procedure
DBMS_OUTPUT.PUT_LINE( a ); -- Output the value
END; -- End the anonymous PL/SQL block
/ -- End the PL/SQL statement
or:
VARIABLE a VARCHAR2(4000); -- Create a bind variable
EXEC Getmarketdetails2(:a); -- Execute the procedure using the bind variable
PRINT a -- Print the bind variable
Assuming an up-to-date Oracle version, you can use dbms_sql.return_result()
create or replace PROCEDURE Getmarketdetails2
IS
c1 SYS_REFCURSOR;
BEGIN
OPEN c1 FOR
SELECT *
from dual;
DBMS_SQL.RETURN_RESULT(c1);
END Getmarketdetails2;
/
Then simply run
exec Getmarketdetails2
The only drawback is that SQL Developer only displays the result as text, not as a proper result grid.
This is how I return a cursor in Oracle
PROCEDURE GetAllData (P_CURSOR OUT SYS_REFCURSOR)
IS
BEGIN
OPEN P_CURSOR FOR
SELECT *
FROM TABLE ;
END GetAllData ;
Declare a Varchar2;
exec Getmarketdetails2(a);
Your procedure is ok;
Instead of above query, use below query to run sp:
Declare
a Varchar2(10);
Begin
Getmarketdetails2(a);
End;

Calling a stored PROCEDURE in Toad

I have a defined a new stored procedure but get a error while calling it,
CREATE OR REPLACE PROCEDURE SCOTT.getempsal(
p_emp_id IN NUMBER,
p_emp_month IN CHAR,
p_emp_sal OUT INTEGER)
AS
BEGIN
SELECT EMP_SAL
INTO p_emp_sal
FROM EMPLOYEE_SAL
WHERE EMP_ID = p_emp_id
AND EMP_MONTH = p_emp_month;
END getempsal;
And trying to call it:
getempsal(1,'JAN',OUT) --Invalid sql statement.
Your procedure contains an out parameter, so you need to call it in block like:
declare
a number;
begin
getempsal(1,'JAN',a);
dbms_output.put_line(a);
end;
A simple procedure (let's say with a number parameter) can be called with
exec proc(1);
or
begin
proc(1);
end;
Just write EXECUTE procedure_name('provide_the_valueof_IN parameter','value of in parameter', :k) ;
Run this statement a popup will come set the parameters as in out and the datatype too. U will see the output in another popup window.

Resources