I have a pckage plch_pkg as follows
create type plch_number_nt is table of number;
create or replace package plch_pkg
authid definer
is
g_numbers plch_numbers_nt:=plch_numbers_nt(1);
procedure empty_the_nt_fail(numbers_io IN OUT plch_numbers_nt);
procedure empty_the_nt(numbers_io IN OUT plch_numbers_nt);
end plch_pkg;
create or replace package body plch_pkg
is
procedure empty_the_nt_fail(numbers_io in out plch_numbers_nt)
is
begin
dbms_output.put_line('empty_the_nt_fail');
numbers_io.delete;
raise program_error;
end empty_the_nt_fail;
procedure empty_the_nt(numbers_io in out plch_numbers_nt)
is
begin
dbms_output.put_line('empty_the_nt');
numbers_io.delete;
end empty_the_nt;
end plch_pkg;
Later I created this procedure.
create or replace procedure plch_proc
authid definer
is
l_numbers plch_numbers_nt := plch_numbers_nt(1);
procedure show_numbers
is
begin
dbms_output.put_line('count='||l_numbers.count);
end;
begin
plch_pkg.empty_the_nt_fail(l_numbers);
show_numbers;
exception
when others then
show_numbers;
end plch_proc;
Now when i call this procedure as follows
declare
begin
plch_proc;
end;
I get the output as count=0.
This is my understanding. My procedure plch_proc the empty_the_nt_fail procedure in the plch_pkg.After deleting all the elements from numbers_io nested table,it raises an error.
The oracle documentation says that "Only when the procedure has finished without exception is the result value copied back to the formal parameter".
This copying of numbers_io to my actual parameter l_numbers should not happen as the error occured. But when I called the procedure plch_proc,it printed the count as 0,which means that formal parameter value was copied to actual parameter. Could somebody please explain
I found the explaination for copying actual parameters and formal parameters here
https://docs.oracle.com/cd/B10500_01/appdev.920/a96624/08_subs.htm#895
https://docs.oracle.com/cd/B13789_01/appdev.101/b10807/08_subs.htm#i23202
http://www.dba-oracle.com/t_pl_sql_nocopy_data_structures.htm
Related
In PL/SQL I have learned that there are two ways to define procedures like below.
Method 1
DECLARE
a number;
PROCEDURE print(mynum number) IS
BEGIN
dbms_output.put_line(mynum);
END;
Method 2
CREATE print(mynum number) IS
BEGIN
dbms_output.print_line(mynum);
END;
But only in method 2, the procedure will store in DBMS as we can call it again and again. What is the difference between two different methods of creating a PLSQL procedure and how we can create and save the store procedure in DBMS which consists of declared variables?
Although you posted invalid syntax, OK - I think I understand the question.
If you want the procedure to be stored, you have to use what you called "Method 2", e.g.
create or replace procedure print (mynum number) is
a number; --> locally declared variable
begin
a := mynum * mynum;
dbms_output.put_line(mynum);
dbms_output.put_line(a);
end;
/
The first piece of code ("Method 1") represents an anonymous PL/SQL block whose contents is "lost" at the end of your session (i.e. when you disconnect).
I'm trying to create a procedure that will update a column in my table with an ORDSYS.ORD Image. The code I have is bellow and it keeps telling me errors when I'm trying to use it. Can some please help? Thank you
Procedure code:
create or replace
PROCEDURE Inserting_Images (REST_ID NUMBER, RESTImage ORDSYS.ORDImage) AS
ctx RAW(64):=NULL;
BEGIN
UPDATE restaurant_table
Set RESTImage = RESTImage
WHERE REST_id = REST_ID;
COMMIT;
EXCEPTION
WHEN others THEN
BEGIN
ROLLBACK;
dbms_output.put_line(sqlerrm);
END;
--Error Handling.
END;
--Ends the procedure.
Using Procedure:
BEGIN
inserting_images(52, 'YUSKIN.jpeg');
END;
The function Inserting_Images accepts an argument of ORDSYS.ORDImage, whereas what you are actually sending it is a VARCHAR, to get the behaviour you want, you need to initialize the ORDImage object first like so:
CREATE OR REPLACE DIRECTORY FILE_DIR as '/mydir/work';
GRANT READ ON DIRECTORY FILE_DIR TO 'user';
inserting_images(52, ORDSYS.ORDImage.init('FILE', 'FILE_DIR','speaker.jpg'));
(Quoted from docs.oracle.com)
Is there any way of calling a stored procedure from another stored procedure, and use retrieved value (from the second procedure) back in the first one?
-- procedure #1
create or replace procedure Proc1(p_RetValue out SomeDataType)
is
begin
-- any logic goes here
p_retValue := 5+5; -- for example. Let's assume that the SomeDataType is number;
end;
-- second procedure
create or replace procedure Proc2 is
l_variable number;
begin
Proc1(l_variable); -- the value 10 will be assigned to l_variable;
end;
I have a stored procedure that starts with the following:
CREATE PROCEDURE somename.tablename (IN P_DATE DATE,
OUT P_ROWS_TO_INSERT INTEGER)
Can someone please explain the purpose of the IN and OUT parameter calls?
So SQL OUT parameter allows the stored procedure to the pass data value back to invoker. IN param is param what you adding to your stored procedure.
Basic example:
DECLARE
V_OUT INTEGER;
BEGIN
EXECUTE SomeName('22.2.2000', V_OUT);
DBMS_OUTPUT.PUT_LINE('OUT is: ' || V_OUT);
END;
Does anyone know of a way, or even if its possible, to call a stored procedure from within another? If so, how would you do it?
Here is my test code:
SET SERVEROUTPUT ON;
DROP PROCEDURE test_sp_1;
DROP PROCEDURE test_sp;
CREATE PROCEDURE test_sp
AS
BEGIN
DBMS_OUTPUT.PUT_LINE('Test works');
END;
/
CREATE PROCEDURE test_sp_1
AS
BEGIN
DBMS_OUTPUT.PUT_LINE('Testing');
test_sp;
END;
/
CALL test_sp_1;
Your stored procedures work as coded. The problem is with the last line, it is unable to invoke either of your stored procedures.
Three choices in SQL*Plus are: call, exec, and an anoymous PL/SQL block.
call appears to be a SQL keyword, and is documented in the SQL Reference. http://download.oracle.com/docs/cd/B19306_01/server.102/b14200/statements_4008.htm#BABDEHHG The syntax diagram indicates that parentesis are required, even when no arguments are passed to the call routine.
CALL test_sp_1();
An anonymous PL/SQL block is PL/SQL that is not inside a named procedure, function, trigger, etc. It can be used to call your procedure.
BEGIN
test_sp_1;
END;
/
Exec is a SQL*Plus command that is a shortcut for the above anonymous block. EXEC <procedure_name> will be passed to the DB server as BEGIN <procedure_name>; END;
Full example:
SQL> SET SERVEROUTPUT ON
SQL> CREATE OR REPLACE PROCEDURE test_sp
2 AS
3 BEGIN
4 DBMS_OUTPUT.PUT_LINE('Test works');
5 END;
6 /
Procedure created.
SQL> CREATE OR REPLACE PROCEDURE test_sp_1
2 AS
3 BEGIN
4 DBMS_OUTPUT.PUT_LINE('Testing');
5 test_sp;
6 END;
7 /
Procedure created.
SQL> CALL test_sp_1();
Testing
Test works
Call completed.
SQL> exec test_sp_1
Testing
Test works
PL/SQL procedure successfully completed.
SQL> begin
2 test_sp_1;
3 end;
4 /
Testing
Test works
PL/SQL procedure successfully completed.
SQL>
Sure, you just call it from within the SP, there's no special syntax.
Ex:
PROCEDURE some_sp
AS
BEGIN
some_other_sp('parm1', 10, 20.42);
END;
If the procedure is in a different schema than the one the executing procedure is in, you need to prefix it with schema name.
PROCEDURE some_sp
AS
BEGIN
other_schema.some_other_sp('parm1', 10, 20.42);
END;
#Michael Lockwood - you don't need to use the keyword "CALL" anywhere. You just need to mention the procedure call directly.
That is
Begin
proc1(input1, input2);
end;
/
instead of
Begin
call proc1(input1, input2);
end;
/
To invoke the procedure from the SQLPlus command line, try one of these:
CALL test_sp_1();
EXEC test_sp_1
Calling one procedure from another procedure:
One for a normal procedure:
CREATE OR REPLACE SP_1() AS
BEGIN
/* BODY */
END SP_1;
Calling procedure SP_1 from SP_2:
CREATE OR REPLACE SP_2() AS
BEGIN
/* CALL PROCEDURE SP_1 */
SP_1();
END SP_2;
Call a procedure with REFCURSOR or output cursor:
CREATE OR REPLACE SP_1
(
oCurSp1 OUT SYS_REFCURSOR
) AS
BEGIN
/*BODY */
END SP_1;
Call the procedure SP_1 which will return the REFCURSOR as an output parameter
CREATE OR REPLACE SP_2
(
oCurSp2 OUT SYS_REFCURSOR
) AS `enter code here`
BEGIN
/* CALL PROCEDURE SP_1 WITH REF CURSOR AS OUTPUT PARAMETER */
SP_1(oCurSp2);
END SP_2;