I need to test a stored procedure that has several subprocedures in the is block. I have copied everything to a test window, however, putting these subprocedures in the declare block does not seem to work. When I attempt to call them from the begin block, I get an error saying that they have not been declared. I haven't changed anything other than moving the contents of is to declare. What can I do?
You can declare procedure, however:
1) You declare it without 'create or replace' keywords
2) If you declare any variables in the same block, all procedures and functions must be declared after the last variable declaration.
So, for example, this:
declare
some_text varchar2(10) := 'SOME_TEXT';
procedure print_4 is
x number := 4;
begin
dbms_output.put_line(x);
end print_4;
begin
print_4;
end;
is a valid pl/sql block, while this:
declare
procedure print_4 is
x number := 4;
begin
dbms_output.put_line(x);
end print_4;
some_text varchar2(10) := 'SOME_TEXT';
begin
print_4;
end;
is not.
If you post your code we might find some other errors.
I'm building a procedure which would require to get an input from user to print few details. But when I use & to get values it fails with errors. the logic is as follows..
DBMS_OUTPUT.PUT_LINE('Enter Y to display Unauthorized records OR N to skip the display');
--SELECT &1 INTO lv_choice FROM DUAL;
IF NOT ('&lv_choice'='Y') THEN
DBMS_OUTPUT.PUT_LINE ('RECORDS WILL NOT BE DISPLAYED');
ELSE
DBMS_OUTPUT.PUT_LINE ('RECORDS TO BE DISPLAYED ARE:');
......
I have tried using &1 into dual or directly calling &lv_choice which is failing with PLSQL internal errors.
Any methods to get input from user to proceed further in the procedure?
This isn't possible in PL/SQL - PL/SQL doesn't have access to the terminal(unless you do something like plug in Java or call your program from a something like SQL*Plus(in which you can use commands like ACCEPT/PROMPT before you run the procedure).
The & variables are substitution variables, and are specific to SQL*Plus, not PL/SQL
If you are using some UI Terminal like SQLDeveloper or TOAD, you can achieve it using below code:
CREATE OR REPLACE INPUTPROCEDURE (LV_CHOICE IN VARCHAR2)
AS
BEGIN
DBMS_OUTPUT.PUT_LINE('Enter Y to display Unauthorized records OR N to skip the display');
--SELECT &1 INTO lv_choice FROM DUAL;
IF lv_choice <> 'Y' THEN
DBMS_OUTPUT.PUT_LINE ('RECORDS WILL NOT BE DISPLAYED');
ELSE
DBMS_OUTPUT.PUT_LINE ('RECORDS TO BE DISPLAYED ARE:');
END INPUTPROCEDURE;
And Invoke the above Procedure like below:
DECLARE
dyn_stmt VARCHAR2(200);
b BOOLEAN := TRUE;
BEGIN
dyn_stmt := 'BEGIN INPUTPROCEDURE(:LV_CHOICE); END;';
EXECUTE IMMEDIATE dyn_stmt USING b;
END;
I have a need to test a stored procedure involving arrays that are written in PL/SQL. I have no way of seeing the PL/SQL contents (shop rules) but need to call the proc. I'd like to know how to call the following proc that invovles 3 arrays of integers directly from toad. The method signature looks like this.
Procedure persistChanges(myKey in NUMBER, arrayOfIntsFirst numberTableType, arrayOfIntsSecond numberTableType, arrayOfIntsThird numberTableType).
How can I call a PL/SQL proc in TOAD where I can hard-code the values for the paramters to test the proc? I'm told there's no way this could be done in Toad. Much appreciated!!!
I have to believe there's a way to poplate these variables but just not sure how to go about doing so...
DECLARE
myKey NUMBER;
arrayOfIntsFirst PL/SQL TABLE;
arrayOfIntsSecond PL/SQL TABLE;
arrayOfIntsThird PL/SQL TABLE;
BEGIN
myKey := NULL;
-- arrayOfIntsFirst := NULL; Modify the code to initialize this parameter
-- arrayOfIntsSecond := NULL; Modify the code to initialize this parameter
-- arrayOfIntsThird := NULL; Modify the code to initialize this parameter
MY_SCHEMA.PKG_MYPACKAGE.PERSISTCHANGES ( myKey, arrayOfIntsFirst,
arrayOfIntsSecond, arrayOfIntsThird );
COMMIT;
END;
Try something like:
declare
l_nums t_num_tab;
begin
l_nums := t_num_tab();
l_nums.extend(2);
l_nums(1) := 56;
l_nums(2) := 42;
for i in l_nums.first .. l_nums.last
loop
dbms_output.put_line( 'Number is: ' || l_nums(i) );
end loop;
end;
And Toad is just a development environment, it won't limit you from writing an anonymous block like above. The t_num_tab is defined as a table of numbers:
CREATE OR REPLACE TYPE t_num_tab as table of number;
You don't even need to formally extend the collection first and assign values. You can initialize in one step:
declare
l_nums t_num_tab;
begin
l_nums := t_num_tab(23,89,152);
...
end;
Read more here. Hope that helps.
I have a bash script running several sql files via sqlplus:
sqlplus $connectioninfo << end
start file1.sql
start file2.sql
start file3.sql $variable
quit
end
file3 has some PL/SQL:
BEGIN
DBMS_OUTPUT.PUT_LINE(&1);
END;
/
But it just prints the literal "&1" instead of the value of $variable. I have also tried the following in file3:
DEFINE var_a = &1;
BEGIN
DBMS_OUTPUT.PUT_LINE(var_a);
END;
/
and also the following:
DECLARE
var_b VARCHAR2(64) := &1;
BEGIN
DBMS_OUTPUT.PUT_LINE(var_b);
END;
/
and finally:
DEFINE var_a = &1;
DECLARE
var_b VARCHAR2(64) := var_a;
BEGIN
DBMS_OUTPUT.PUT_LINE(var_b);
END;
/
However, I am getting various errors or just the literal value '&1' for all of these.
Try adding SET DEFINE ON to the start of your script file3.sql.
If SET DEFINE is ON, SQL*Plus will replace &... substitution parameters with their values. If SET DEFINE is OFF (which it seems to be for you), SQL*Plus won't do this.
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;