Execute PROCEDURE on Oracle PL/SQL with DECLARE variable - oracle

I just currently learning about Oracle PL/SQL. I wanna create store procedure with variable and then call it with another script. Is it possible?
I tried use simple script without variable and it works:
CREATE OR REPLACE PROCEDURE testmyproc AS
BEGIN
INSERT INTO tes_table(dt)
VALUES (sysdate);
commit;
END testmyproc;
Then I call it with another script abc.sql
begin
testmyproc;
end;
It works successfully.
But, unfortunately if I use DECLARE (variable) at my PROCEDURE, it show error when I execute (but it success in create procedure).
Here's my PROCEDURE (no error):
CREATE OR REPLACE PROCEDURE sp_testmyproc AS
DECLARE
job_name varchar(100);
status_key number;
status_desc varchar(100);
notes varchar(250);
BEGIN
status_key := 1;
status_desc := 'SUCCESS';
notes := 'Process Completed';
INSERT INTO automation_log(job_name, dt, status_key, status_desc, notes)
VALUES (job_name, sysdate, status_key, status_desc, notes);
commit;
END sp_testmyproc;
Here's my execure script abc.sql (show error when i execute it)
-without DECLARE
begin
sp_testmyproc;
end;
-I tried to execute it with DECLARE
DECLARE
job_name varchar(100);
status_key number;
status_desc varchar(100);
notes varchar(250);
begin
status_key := 1;
status_desc := 'SUCCESS';
notes := 'Process Completed';
sp_testmyproc;
end;
It show error like this:
> ORA-06550: line 8, column 11:
> PLS-00905: SP_TESTMYPROC is invalid
> ORA-06550: line 8, column 3:
> PL/SQL: Statement ignored
Can I call Procedure for another script? Is It best practice?
I just think PROCEDURE can be used for many cases (something like function in programming).
Thank you!

You need to learn the syntax of the procedure.
In Procedure, You should not use the keyword DECLARE. Any variables you want to declare must be between AS and BEGIN in the procedure.
Your procedure should look like follows:
CREATE OR REPLACE PROCEDURE sp_testmyproc AS
--DECLARE
job_name varchar(100);
status_key number;
status_desc varchar(100);
notes varchar(250);
BEGIN
status_key := 1;
.....
.....
.....
Refer to this document for the syntax of the oracle procedure as it is very easy to follow.

Please note the difference when creating a stored procedure in SQL*Plus:
SQL> create or replace procedure test_ok as
2 v number;
3 begin
4 v:=0;
5 end;
6 /
Procedure created.
SQL> show errors
No errors.
SQL> create or replace procedure test_ko as
2 declare
3 v number;
4 begin
5 v:=0;
6 end;
7 /
Warning: Procedure created with compilation errors.
SQL> show errors
Errors for PROCEDURE TEST_KO:
LINE/COL ERROR
-------- -----------------------------------------------------------------
2/1 PLS-00103: Encountered the symbol "DECLARE" when expecting one of
the following:
begin function pragma procedure subtype type <an identifier>
<a double-quoted delimited-identifier> current cursor delete
exists prior external language
SQL>
If you have compilation errors you get at least Warning: Procedure created with compilation errors. If you have compilation errors and use show errors you get all error messages.

Related

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;

How can a stored procedure be executed in Oracle with in and out parameters?

Here's my stored procedure:
CREATE OR REPLACE PROCEDURE STATS_SD
(
P_ID IN NUMBER,
PRC OUT SYS_REFCURSOR
)
IS
BEGIN
OPEN PRC FOR
SELECT
ID,
SESID
FROM RESPONSES
WHERE ID IN (P_ID)
END;
When I try to execute it using
EXEC EXAM_STATS_STUDENTS_SD('6901');
I get the following error:
PLS-00306: wrong number or types of arguments in call to 'STATS_SD'
Do you have any ideas why?
Here is an example using an OUT parameter that is a sys_refcursor. Note that I close the cursor in the pl/sql block that uses it (which is important!):
create or replace procedure get_data(o_cur OUT SYS_REFCURSOR) as
begin
OPEN o_cur FOR
select * from emp;
end;
And using the get_data procedure:
declare
l_cur sys_refcursor;
l_row emp%rowtype;
begin
get_data(l_cur);
LOOP
fetch l_cur
into l_row;
exit when l_cur%notfound;
-- do something with l_row here
END LOOP;
close l_cur;
end;
You are passing a wrong datatype to your procedure.
According to your declaration a NUMBER is expected:
P_ID IN NUMBER
However, you pass a VARCHAR2 in your exec command:
EXEC EXAM_STATS_STUDENTS_SD('6901');
Note the '' around the value.
Try calling this instead:
EXEC EXAM_STATS_STUDENTS_SD(6901);
Apart from that you are missing the second parameter completely.

How to call Oracle Procedure which has one OUT parameter

My oracle procedure structure,
CREATE OR REPLACE PACKAGE BODY NLS_ADMIN."MY_PKG"
AS
PROCEDURE DATA_PRC (oresult OUT NUMBER )
IS
varKeyValue varchar2(1);
BEGIN
...
...
END;
I tried to call above procedure by executing below statement,
declare
oresult NUMBER;
begin
EXECUTE DATA_PRC(oresult);
end;
But getting below exception. Please help me how to call this procedure.
ORA-06550: line 8, column 9:
PLS-00103: Encountered the symbol "DATA_PRC" when expecting one of the following:
:= . ( # % ; immediate
The symbol ":=" was substituted for "DATA_PRC" to continue.
Simply this:
declare
oresult NUMBER;
begin
MY_PKG.DATA_PRC(oresult);
end;

syntax error when declaring variables in a pl/sql procedure

This is sending me a bit mad. I'm trying to add in a variable to a procedure, but it wasn't working - I just got this error message:
[Error] Syntax check (25: 7): ERROR line 25, col 7, ending_line 25,
ending_col 12, Found 'number', Expecting: ; -or- .. := DEFAULT
NOT NULL -or- % -or- ( . #
I knocked up a really basic procedure below to isolate the problem and now I'm completely stuck, as every basic syntax guide I've looked as says to do what I've done. Why can't i declare variables as shown below? I normally code in SQL Server if that's any clue as to my problem. Many thanks if anyone can help!
CREATE OR REPLACE PROCEDURE MRCS.pro_xxx_test1 (cats out sys_refcursor)
IS
declare
spoon number;
balls varchar2(3);
BEGIN
open cats for select * from dual;
end;
/
Remove the "DECLARE". Not needed in a function / procedure declaration
CREATE OR REPLACE PROCEDURE MRCS.pro_xxx_test1 (cats out sys_refcursor)
IS
spoon number;
balls varchar2(3);
BEGIN
open cats for select * from dual;
end;
/
Declare local variable between IS and BEGIN block for procedure and function
CREATE OR REPLACE PROCEDURE MRCS.pro_xxx_test1 (cats out sys_refcursor)
IS
spoon number;
balls varchar2(3);
BEGIN
open cats for select * from dual;
end;
/

Run Stored Procedure in SQL Developer?

I am trying to run a stored procedure that has multiple in and out parameters. The procedure can only be viewed in my Connections panel by navigating
Other Users | <user> | Packages | <package> | <procedure>
If I right click , the menu items are "Order Members By..." and "Create Unit Test" (greyed out). The ability to "Run" the procedure does not seem possible when it's accessed by user.
I have been trying to find an example of how to create an anonymous block so that I can run the procedure as a SQL file, but haven't found anything that works.
Does anyone know how I can execute this procedure from SQL Developer? I am using Version 2.1.1.64.
EDIT 1:
The procedure I want to call has this signature:
user.package.procedure(
p_1 IN NUMBER,
p_2 IN NUMBER,
p_3 OUT VARCHAR2,
p_4 OUT VARCHAR2,
p_5 OUT VARCHAR2,
p_6 OUT NUMBER)
If I write my anonymous block like this:
DECLARE
out1 VARCHAR2(100);
out2 VARCHAR2(100);
out3 VARCHAR2(100);
out4 NUMBER(100);
BEGIN
EXECUTE user.package.procedure (33,89, :out1, :out2, :out3, :out4);
END;
I get the error:
Bind Varialbe "out1" is NOT DECLCARED
anonymous block completed
I've tried initializing the out* variables:
out1 VARCHAR2(100) := '';
but get the same error:
EDIT 2:
Based on Alex's answer, I tried removing the colons from in front of the params and get this:
Error starting at line 1 in command:
DECLARE
out1 VARCHAR2(100);
out2 VARCHAR2(100);
out3 VARCHAR2(100);
out4 NUMBER(100);
BEGIN
EXECUTE user.package.procedure (33,89, out1, out2, out3, out4);
END;
Error report:
ORA-06550: line 13, column 17:
PLS-00103: Encountered the symbol "USER" when expecting one of the following:
:= . ( # % ; immediate
The symbol ":=" was substituted for "USER" to continue.
06550. 00000 - "line %s, column %s:\n%s"
*Cause: Usually a PL/SQL compilation error.
*Action:
With simple parameter types (i.e. not refcursors etc.) you can do something like this:
SET serveroutput on;
DECLARE
InParam1 number;
InParam2 number;
OutParam1 varchar2(100);
OutParam2 varchar2(100);
OutParam3 varchar2(100);
OutParam4 number;
BEGIN
/* Assign values to IN parameters */
InParam1 := 33;
InParam2 := 89;
/* Call procedure within package, identifying schema if necessary */
schema.package.procedure(InParam1, InParam2,
OutParam1, OutParam2, OutParam3, OutParam4);
/* Display OUT parameters */
dbms_output.put_line('OutParam1: ' || OutParam1);
dbms_output.put_line('OutParam2: ' || OutParam2);
dbms_output.put_line('OutParam3: ' || OutParam3);
dbms_output.put_line('OutParam4: ' || OutParam4);
END;
/
Edited to use the OP's spec, and with an alternative approach to utilise :var bind variables:
var InParam1 number;
var InParam2 number;
var OutParam1 varchar2(100);
var OutParam2 varchar2(100);
var OutParam3 varchar2(100);
var OutParam4 number;
BEGIN
/* Assign values to IN parameters */
:InParam1 := 33;
:InParam2 := 89;
/* Call procedure within package, identifying schema if necessary */
schema.package.procedure(:InParam1, :InParam2,
:OutParam1, :OutParam2, :OutParam3, :OutParam4);
END;
/
-- Display OUT parameters
print :OutParam1;
print :OutParam2;
print :OutParam3;
print :OutParam4;
Executing easy. Getting the results can be hard.
Take a look at this question I asked Best way/tool to get the results from an oracle package procedure
The summary of it goes like this.
Assuming you had a Package named mypackage and procedure called getQuestions. It returns a refcursor and takes in string user name.
All you have to do is create new SQL File (file new). Set the connection and paste in the following and execute.
var r refcursor;
exec mypackage.getquestions(:r, 'OMG Ponies');
print r;
For those using SqlDeveloper 3+, in case you missed that:
SqlDeveloper has feature to execute stored proc/function directly, and output are displayed in a easy-to-read manner.
Just right click on the package/stored proc/ stored function, Click on Run and choose target to be the proc/func you want to execute, SqlDeveloper will generate the code snippet to execute (so that you can put your input parameters). Once executed, output parameters are displayed in lower half of the dialog box, and it even have built-in support for ref cursor: result of cursor will be displayed as a separate output tab.
Open the procedure in SQL Developer and run it from there. SQL Developer displays the SQL that it runs.
BEGIN
PROCEEDURE_NAME_HERE();
END;
Use:
BEGIN
PACKAGE_NAME.PROCEDURE_NAME(parameter_value, ...);
END;
Replace "PACKAGE_NAME", "PROCEDURE_NAME", and "parameter_value" with what you need. OUT parameters will need to be declared prior to.
Though this question is quite old, I keep stumbling into same result without finding an easy way to run from sql developer.
After couple of tries, I found an easy way to execute the stored procedure from sql developer itself.
Under packages, select your desired package and right click on the package name (not on the stored procedure name).
You will find option to run. Select that and supply the required arguments. Click OK and you can see the output in output variables section below
I'm using SQL developer version 4.1.3.20
None of these other answers worked for me. Here's what I had to do to run a procedure in SQL Developer 3.2.20.10:
SET serveroutput on;
DECLARE
testvar varchar(100);
BEGIN
testvar := 'dude';
schema.MY_PROC(testvar);
dbms_output.enable;
dbms_output.put_line(testvar);
END;
And then you'd have to go check the table for whatever your proc was supposed to do with that passed-in variable -- the output will just confirm that the variable received the value (and theoretically, passed it to the proc).
NOTE (differences with mine vs. others):
No : prior to the variable name
No putting .package. or .packages. between the schema name and the procedure name
No having to put an & in the variable's value.
No using print anywhere
No using var to declare the variable
All of these problems left me scratching my head for the longest and these answers that have these egregious errors out to be taken out and tarred and feathered.
Can't believe, this won't execute in SQL Developer:
var r refcursor;
exec PCK.SOME_SP(:r,
'02619857');
print r;
BUT this will:
var r refcursor;
exec TAPI_OVLASCENJA.ARH_SELECT_NAKON_PRESTANKA_REG(:r, '02619857');
print r;
Obviously everything has to be in one line..
Using SQL Developer Version 4.0.2.15 Build 15.21 the following works:
SET SERVEROUTPUT ON
var InParam1 varchar2(100)
var InParam2 varchar2(100)
var InParam3 varchar2(100)
var OutParam1 varchar2(100)
BEGIN
/* Assign values to IN parameters */
:InParam1 := 'one';
:InParam2 := 'two';
:InParam3 := 'three';
/* Call procedure within package, identifying schema if necessary */
schema.package.procedure(:InParam1, :InParam2, :InParam3, :OutParam1);
dbms_output.enable;
dbms_output.put_line('OutParam1: ' || :OutParam1);
END;
/
To run procedure from SQL developer-only execute following command
EXECUTE PROCEDURE_NAME;
I had a stored procedure that returned a cursor, in my case it was actually of a custom package type (T_CURSOR, looks like a convention to me) that is defined as REF CURSOR.
There may be a better way to do this, but I defined variables for all the columns of the table that the cursor was iterating, looped the cursor fetching each row into those variables, then printed them out.
SET serveroutput on;
DECLARE
testvar number;
v_cur SYS_REFCURSOR;
ORIGINAL_EMP_NUM NUMBER;
TEMPORARY_EMP_NUM NUMBER;
ORG_UNIT_CODE VARCHAR2(2 BYTE);
MRU_CODE VARCHAR2(10 BYTE);
CTRL_COMPANY_CODE VARCHAR2(10 BYTE);
IS_TEMP_FLAG VARCHAR2(1 BYTE);
BEGIN
testvar := 420;
foo.updates.get_temporary_authorisations(testvar, v_cur);
dbms_output.enable;
dbms_output.put_line(testvar);
LOOP
FETCH v_cur INTO ORIGINAL_EMP_NUM, TEMPORARY_EMP_NUM, ORG_UNIT_CODE, MRU_CODE, CTRL_COMPANY_CODE, IS_TEMP_FLAG;
EXIT WHEN v_cur%NOTFOUND;
dbms_output.put_line(ORIGINAL_EMP_NUM || ',' || TEMPORARY_EMP_NUM || ',' || ORG_UNIT_CODE || ',' || MRU_CODE|| ',' || CTRL_COMPANY_CODE|| ',' || IS_TEMP_FLAG);
END LOOP;
CLOSE v_cur;
END;
I wasn't able to get #Alex Poole answers working. However, by trial and error, I found the following works (using SQL Developer version 3.0.04). Posting it here in case it helps others:
SET serveroutput on;
DECLARE
var InParam1 number;
var InParam2 number;
var OutParam1 varchar2(100);
var OutParam2 varchar2(100);
var OutParam3 varchar2(100);
var OutParam4 number;
BEGIN
/* Assign values to IN parameters */
InParam1 := 33;
InParam2 := 89;
/* Call procedure within package, identifying schema if necessary */
schema.package.procedure(InParam1, InParam2,
OutParam1, OutParam2, OutParam3, OutParam4);
/* Display OUT parameters */
dbms_output.put_line('OutParam1: ' || OutParam1);
dbms_output.put_line('OutParam2: ' || OutParam2);
dbms_output.put_line('OutParam3: ' || OutParam3);
dbms_output.put_line('OutParam4: ' || OutParam4);
END;
--for setting buffer size needed most of time to avoid `anonymous block completed` message
set serveroutput on size 30000;
-- declaration block in case output need to catch
DECLARE
--declaration for in and out parameter
V_OUT_1 NUMBER;
V_OUT_2 VARCHAR2(200);
BEGIN
--your stored procedure name
schema.package.procedure(
--declaration for in and out parameter
V_OUT_1 => V_OUT_1,
V_OUT_2 => V_OUT_2
);
V_OUT_1 := V_OUT_1;
V_OUT_2 := V_OUT_2;
-- console output, no need to open DBMS OUTPUT seperatly
-- also no need to print each output on seperat line
DBMS_OUTPUT.PUT_LINE('Ouput => ' || V_OUT_1 || ': ' || V_OUT_2);
END;
Creating Pl/SQL block can be painful if you have a lot of procedures which have a lot of parameters. There is an application written on python that do it for you.
It parses the file with procedure declarations and creates the web app for convenient procedure invocations.
var out_para_name refcursor;
execute package_name.procedure_name(inpu_para_val1,input_para_val2,... ,:out_para_name);
print :out_para_name;

Resources