I am fairly new to PL/SQL but have been reading up on it and have used some templates, including some which I found from here.
What I want to do is to write an anonymous block to call some procedures which wrere written earlier in a sql developer project. I have attempted it but it isn't running properly. It returns an error of "Error starting at line : 2 in command " and then reports a "closed connection."
This is my attempt:
DECLARE
P_USER_NAME VARCHAR;
P_DEBUG_FLAG VARCHAR;
P_DEBUG_FIELD VARCHAR;
P_DEBUG_VALUE VARCHAR;
BEGIN
schema.package.procedure(
OutParam1, OutParam2, OutParam3, OutParam4);
dbms_output.put_line('OutParam1: ' || P_USER_NAME);
dbms_output.put_line('OutParam2: ' || P_DEBUG_FLAG);
dbms_output.put_line('OutParam3: ' || P_DEBUG_FIELD);
dbms_output.put_line('OutParam4: ' || P_DEBUG_VALUE);
END;
/
And these are the procedure I want to call:
PROCEDURE CLEAR_DEBUG (P_USER_NAME IN VARCHAR2);
PROCEDURE WRITE_DEBUG (P_USER_NAME IN VARCHAR2,
P_DEBUG_FLAG IN VARCHAR2,
P_DEBUG_FIELD IN VARCHAR2,
P_DEBUG_VALUE IN VARCHAR2);
PROCEDURE READ_DEBUG (P_USER_NAME IN VARCHAR2,
P_REF_CURSOR OUT SYS_REFCURSOR);
END P_DEBUG;
There are more errors in your code:
declare the variables properly - VARCHAR requires length constraint
OutParam1, OutParam2, OutParam3, OutParam4 are not declared - use the declared variables as arguments instead, beware of the variables passed as arguments must have the same data type
I expect you wanted to call P_DEBUG.WRITE_DEBUG(P_USER_NAME, P_DEBUG_FLAG, P_DEBUG_FIELD, P_DEBUG_VALUE);
Related
So I have this interesting situation. I have a PL/SQL procedure where I pass two IN parameters and two OUT parameters:
PROCEDURE p_merge_catalog(p_merge_from_code VARCHAR2,
p_merge_to_code VARCHAR2,
msg_type_out OUT VARCHAR2,
msg_out OUT VARCHAR2)
IS
.
.
My conundrum is I'm using a job submission/scheduler program to call the procedure that does not seem to deal with OUT variables. I'm not able to bind variables to the OUT parameters; it only passes values. Is there a way to call this procedure without specifying an OUT parameter? Or maybe trick it and use some kind of hidden variable?
Not very beautiful for two outs, but working ;)
CREATE OR REPLACE FUNCTION f_merge_catalog_wrapper (
p_merge_from_code VARCHAR2,
p_merge_to_code VARCHAR2)
RETURN emp%ROWTYPE
IS
msg_type_out VARCHAR2(2000);
msg_out VARCHAR2(2000);
BEGIN
p_merge_catalog(p_merge_from_code, p_merge_to_code, msg_type_out, msg_out);
return msg_type_out || '#' || msg_out;
END;
Didn't check for typos. But the mechanic should be clear :o).
If you don't need the output:
CREATE OR REPLACE PROCEDURE p_merge_catalog_wrapper (
p_merge_from_code VARCHAR2,
p_merge_to_code VARCHAR2)
RETURN emp%ROWTYPE
IS
msg_type_out VARCHAR2(2000);
msg_out VARCHAR2(2000);
BEGIN
p_merge_catalog(p_merge_from_code, p_merge_to_code, msg_type_out, msg_out);
END;
Is it possible to use bind variables,(declared and initialized outside pl/sql block) inside pl/sql stored procedure
I am just trying to print bind variable defined as shown below :
Bind variable declaration and initialization
var jdata varchar2(4000);
exec :jdata := ''{"PONumber":12,"Reference":"StackOver"}'';
pl/sql procedure
create or replace PROCEDURE generic_procedure( v_typename IN VARCHAR2,v_path IN VARCHAR2 DEFAULT '$') IS
BEGIN
dbms_output.put_line(:jdata);
END generic_procedure;
/
Error
fails at compilation:
SQL> show errors
Errors for PROCEDURE GENERIC_PROCEDURE:
ERROR: bad bind variable 'JDATA'
Here, I'm trying to call jdata inside generic_procedure(stored pl/sql procedure) . but it says JDATA as
bad bind variable
You could use a substitution variable:
define jdata='{"PONumber":12,"Reference":"StackOver"}';
create or replace PROCEDURE generic_procedure( v_typename IN VARCHAR2,
v_path IN VARCHAR2 DEFAULT '$') IS
BEGIN
dbms_output.put_line('&jdata');
END generic_procedure;
/
But you can also pass it as a parameter to the procedure. Which seems a bit cleaner to me. Since the procedure does not depend on some variable that has, or has not been, declared outside of it. It just works on the parameters alone.
create or replace PROCEDURE generic_procedure( v_data IN varchar2,
v_typename IN VARCHAR2,
v_path IN VARCHAR2 DEFAULT '$') IS
BEGIN
dbms_output.put_line(v_data);
END generic_procedure;
/
exec generic_procedure('&jdata','typename');
Here's some more about variables in sqlplus
AFAIK, don't think this is possible as the PL/SQL variables need to be defined in the scope of the package or procedure.
You can create a package to hold this variable and then set and use it's value in the procedure.
CREATE OR REPLACE PACKAGE P_test
is
jdata CONSTANT varchar2(4000):=''{"PONumber":12,"Reference":"StackOver"}'';
END P_test ;
create or replace PROCEDURE generic_procedure( v_typename IN VARCHAR2,v_path
IN VARCHAR2 DEFAULT '$') IS
BEGIN
dbms_output.put_line(P_test.jdata);
END generic_procedure;
Hope it helps
Vishad
How can I call a stored procedure within a procedure and print the output in same line.
For example my full name is 'Alex Bob' and I have created 2 procedure each for firstname(p1) and lastname(p2) like this:
-- Procedure 1:
CREATE OR REPLACE PROCEDURE p1(fn in out varchar)
IS
BEGIN
dbms_output.put_line(fn);
END;
-- Procedure 2:
CREATE OR REPLACE PROCEDURE p2(ln in out varchar)
IS
BEGIN
p1('Alex');
dbms_output.put_line(ln);
END;
-- Calling procedure
exec p2('Bob');
Now this will give me output like this:
Alex
Bob
But I want to print name together (in a single line) and for this I tried calling procedure within procedure by creating local variable and calling procedure & storing returned value in that variable. Here is my revised code:
CREATE OR REPLACE PROCEDURE p1(fn in varchar)
IS
BEGIN
declare
cn varchar;
cn := exec p2('Bob');
dbms_output.put_line(fn || cn);
END;
CREATE OR REPLACE PROCEDURE p2(ln in out varchar)
IS
BEGIN
ln := ln;
END;
exec p1('Alex');
but this doesn't work as expected. How can I achieve this ?
You can create a Private Procedure to achieve this. See below:
CREATE OR REPLACE PROCEDURE p1 (fn IN VARCHAR)
AS
v_nam varchar2(100):='Bob';
--private Procedure
PROCEDURE p2 (LN IN OUT VARCHAR)
IS
BEGIN
null;
END;
BEGIN
p2(lN => v_nam);
DBMS_OUTPUT.put_line (fn ||' '||v_nam);
END;
Execution:
SQL> exec p1('Alex');
Alex Bob
PL/SQL procedure successfully completed.
First of all, literals cannot be passed as in OUT parameters - only IN, simply because you cannot assign anything to a literal, can you? Now back to the problem at hand. If you need those two procedures be able to print on the same line, use dbms_output.put() in all procedures but the last one and in the last one call dbms_output.put_line(). here is an example:
CREATE OR REPLACE PROCEDURE p1(fn in varchar2)
IS
BEGIN
dbms_output.put(fn);
END;
/
-- Procedure 2:
CREATE OR REPLACE PROCEDURE p2(ln in varchar2)
IS
BEGIN
p1('Alex ');
dbms_output.put(ln);
END;
/
create or replace procedure p3(ln in varchar2)
is
begin
p2('Bob ');
dbms_output.put_line(ln);
end;
exec p3('is a nice guy')
Result:
Alex Bob is a nice guy
PL/SQL procedure successfully completed
Find out more
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.
Trying to set a local variable to parameter value that is passed to Oracle stored procedure However i am getting nottihgn..what am i doing wrong. When I test the package v_param is empty.
I am passing a long text
create or replace package MA_MAIN_SP_TESTCLOB IS
v_param clob;
procedure RUNALL( iOffice clob);
end MA_MAIN_SP_TESTCLOB;
create or replace package body MA_MAIN_SP_TESTCLOB IS
procedure RUNALL(iOffice clob) IS
BEGIN
v_param := iOffice;
--dbms_output.put_line('Parmeters are ' || v_param);
insert into ICCMSDW_CR.OfficeHolder(POFFICE)
values(v_param);
END RUNALL;
END MA_MAIN_SP_TESTCLOB;