Oracle return the value of a variable - oracle

I am migrating Microsoft Sql Server Database to Oracle 19c, a query migrated is failing:
DECLARE cardnum varchar2(100);
BEGIN
MyProcedure('ES', cardnum );
SELECT cardnum;
END;
The error returned is:
PL/SQL: ORA-00923: FROM keyword not found where expected
I think that the error is in the line 4:
SELECT cardnum;
The procedure sets the value of the variable, therefore I need to return the value of the variable "cardnum".
What should i use instead of select clausule?
Note --> this query is used from net core with Dapper.
Thank you!

Well, you already have cardnum, procedure set it as its OUT parameter, you don't have to do anything about it.
SQL> create or replace procedure myprocedure(par_1 in varchar2, par_2 out varchar2) is
2 begin
3 par_2 := 'ABC';
4 end;
5 /
Procedure created.
SQL> declare
2 cardnum varchar2(100);
3 begin
4 myprocedure('ES', cardnum);
5
6 dbms_output.put_line('Cardnum = ' || cardnum);
7 end;
8 /
Cardnum = ABC
PL/SQL procedure successfully completed.
SQL>
If you want to select it, you can - but PL/SQL requires an INTO clause. For example:
SQL> declare
2 cardnum varchar2(100);
3 l_var varchar2(100);
4 begin
5 myprocedure('ES', cardnum);
6
7 select cardnum into l_var from dual;
8 end;
9 /
PL/SQL procedure successfully completed.
SQL>
It depends on what you actually want to do with cardnum ...

Related

PL/SQL Procedure SELECT Input- Error PLS-00306

Hello I'm a beginner at PL/SQL and some help would be appreciated.
So I have this procedure here and my goal is to have it so that when this procedure is executed that I can enter a 5 digit integer (a zipcode) and it will just select those values from the table and display just as if I've done a query like
SELECT * FROM customers WHERE customer_zipcode = "input zipcode".
create or replace PROCEDURE LIST_CUSTOMER_ZIPCODE(
p_zipcode IN customers.customer_zipcode%TYPE,
p_disp OUT SYS_REFCURSOR)
-- User input Variable, Display Variable
IS
BEGIN
OPEN p_disp for SELECT customer_first_name, customer_zipcode FROM customers
WHERE customer_zipcode=p_zipcode;
EXCEPTION
-- Input Sanitization
WHEN no_data_found THEN
dbms_output.put_line('-1');
END;
EXEC LIST_CUSTOMER_ZIPCODE(07080);
When I execute this command I just keep getting this error.
https://i.stack.imgur.com/nCI8T.png
If you are using SQL*Plus or SQL Developer then you can declare a bind variable and then call the procedure passing the variable and then print it:
SELECT * FROM customers WHERE customer_zipcode = "input zipcode".
create or replace PROCEDURE LIST_CUSTOMER_ZIPCODE(
p_zipcode IN customers.customer_zipcode%TYPE,
p_disp OUT SYS_REFCURSOR
)
IS
BEGIN
OPEN p_disp FOR
SELECT customer_first_name, customer_zipcode
FROM customers
WHERE customer_zipcode = p_zipcode;
EXCEPTION
-- Input Sanitization
WHEN no_data_found THEN
dbms_output.put_line('-1');
END;
/
VARIABLE cur SYS_REFCURSOR;
EXEC LIST_CUSTOMER_ZIPCODE('07080', :cur);
PRINT cur;
However, your exception handling block is never going to be called as the cursor can return zero rows without raising that exception so the procedure could be simplified to:
create or replace PROCEDURE LIST_CUSTOMER_ZIPCODE(
p_zipcode IN customers.customer_zipcode%TYPE,
p_disp OUT SYS_REFCURSOR
)
IS
BEGIN
OPEN p_disp FOR
SELECT customer_first_name, customer_zipcode
FROM customers
WHERE customer_zipcode = p_zipcode;
END;
/
You can't just execute such a procedure as it expects 2 parameters; one is IN, while another is OUT (ref cursor which contains result set).
I don't have your tables so I'll demonstrate it using Scott's sample schema by passing department number and returning list of employees working in that department.
Procedure:
SQL> set serveroutput on
SQL> create or replace procedure p_list
2 (p_deptno in dept.deptno%type,
3 p_disp out sys_refcursor
4 )
5 is
6 begin
7 open p_disp for select ename, job from emp
8 where deptno = p_deptno;
9 end;
10 /
Procedure created.
This is how you use it:
SQL> declare
2 l_list sys_refcursor;
3 l_ename emp.ename%type;
4 l_job emp.job%type;
5 begin
6 p_list(10, l_list); --> calling the procedure; use 2 parameters
7
8 loop
9 fetch l_list into l_ename, l_job;
10 exit when l_list%notfound;
11 dbms_output.put_line(l_ename ||' - '|| l_job);
12 end loop;
13 end;
14 /
CLARK - MANAGER
KING - PRESIDENT
MILLER - CLERK
PL/SQL procedure successfully completed.
SQL>
TRY EXEC LIST_CUSTOMER_ZIPCODE(:p_Zipcode);
If you put ':' before any string, It will become substitution string and you can type your input.

call pl/sql from another one in oracle database problem

i have 2 stored procedures 1 is called A with the following impl
PROCEDURE A(p_id IN NUMBER, lic_cat_2 OUT varchar2,lic_cat_1 OUT varchar2,traffic_code OUT varchar2,lic_type OUT varchar2,emp_num OUT varchar2)
// Some LOGIC
end A ;
and PROCEDURE B which is a wrapper to proc A but i need to get other value with a query
PROCEDURE B(ph_id IN NUMBER, lic_cat_2 OUT varchar2,lic_cat_1 OUT varchar2,traffic_code OUT varchar2,lic_type OUT varchar2,emp_num OUT varchar2)
declare number phone_id
begin
select into phone_id parent_id from per_phones where phone_id= p_id
exec A(phone_id,lic_cat_2 OUT varchar2,lic_cat_1 OUT varchar2,traffic_code OUT varchar2,lic_type OUT varchar2,emp_num OUT varchar2);
END B;
but it gives me PLS-00103: Encountered the symbol “CREATE”
You're calling the A procedure in a wrong manner:
omit EXEC, it is a SQL*Plus command
omit parameters' description (IN/OUT, datatype) - pass only values
omit DECLARE; you need it in triggers or anonymous PL/SQL blocks, but not in stored procedures
by the way, variable name comes first, datatype next (for phone_id)
I'd suggest you to prefix parameters and variables with p_ (or par_) and l_ respectively (or any other prefix you want) to distinguish them from column names. Otherwise, it is easy to get confused.
also, use table aliases in your queries for the same reason
So:
CREATE OR REPLACE PROCEDURE B (p_ph_id IN NUMBER,
p_lic_cat_2 OUT VARCHAR2,
p_lic_cat_1 OUT VARCHAR2,
p_traffic_code OUT VARCHAR2,
p_lic_type OUT VARCHAR2,
p_emp_num OUT VARCHAR2)
IS
l_phone_id NUMBER;
BEGIN
SELECT p.parent_id
INTO l_phone_id
FROM per_phones p
WHERE p.phone_id = p_ph_id;
A (l_phone_id,
p_lic_cat_2,
p_lic_cat_1,
p_traffic_code,
p_lic_type,
p_emp_num);
END B;
As I don't have your tables, for example (to show how to do it) I used Scott's sample schema:
SQL> create or replace procedure a (par_deptno in number, par_dname out varchar2)
2 is
3 begin
4 select dname into par_dname from dept where deptno = par_deptno;
5 end;
6 /
Procedure created.
SQL>
SQL> create or replace procedure b (par_empno in number, par_dname out varchar2) is
2 l_deptno emp.deptno%type;
3 begin
4 select deptno into l_deptno from emp where empno = par_empno;
5
6 a(l_deptno, par_dname);
7 end;
8 /
Procedure created.
SQL>
SQL> set serveroutput on
SQL> declare
2 l_dname dept.dname%type;
3 begin
4 b (7654, l_dname);
5 dbms_output.put_line('Dname = ' || l_dname);
6 end;
7 /
Dname = SALES
PL/SQL procedure successfully completed.
SQL>

Is it possible to take a stored procedure name as input parameter in another stored procedure and execute it?

I have a set of stored procedures with the same interface and one of these stored procedures will be passed to a runner stored procedure as an input parameter. How can I execute this stored procedure within the runner proc.
I tried this by using dynamic SQL. The code snippet I wrote for this:
v_proc_query := ':1(:2, :3)';
execute immediate v_proc_query using p_proc_name, p_param1, p_param2;
But the above statement give error: ORA-00900: invalid SQL statement
I'm using Oracle 12c.
What is the right approach to achieve the goal?
Something like this, perhaps?
SQL> set serveroutput on
SQL> create or replace procedure p_test (par_deptno in number)
2 is
3 l_cnt number;
4 begin
5 select count(*)
6 into l_cnt
7 from emp
8 where deptno = par_deptno;
9 dbms_output.put_line('count = ' || l_cnt);
10 end;
11 /
Procedure created.
SQL> create or replace procedure p_test_2 (par_proc_name in varchar2, par_deptno in number)
2 is
3 l_str varchar2(200);
4 begin
5 l_str := 'begin ' ||
6 dbms_assert.sql_object_name(par_proc_name) ||
7 '(' || par_deptno || ');' ||
8 'end;';
9 execute immediate l_str;
10 end;
11 /
Procedure created.
SQL> exec p_test_2('p_test', 10);
count = 3
PL/SQL procedure successfully completed.
SQL>

How to Escape dot(.) In a like expression in Oracle PL/SQL Statement

In a stored procedure I am filtering out list of employees whose role is SUPER.ADMIN
In such a case I used like expression as below
Emp.Role_nm Like ''''||p_rolenm||''''
p_rolenm I have mentioned in stored procedure as VARCHAR2
When ever I pass a value to p_rolenm as SUPER.ADMIN it's throwing error as identifier SUPER.ADMIN is not declared.
How I can escape . (Dot) in PL/SQL statements?
Why do you use that many single quotes? You don't need any (at least, I think so):
Sample data:
SQL> create table test (id number, role varchar2(20));
Table created.
SQL> insert into test
2 select 1, 'CLERK' from dual union all
3 select 2, 'SUPER.ADMIN' from dual;
2 rows created.
SQL> select * from test;
ID ROLE
---------- --------------------
1 CLERK
2 SUPER.ADMIN
SQL> set serveroutput on;
Procedure (anonymous, though, but that doesn't matter):
SQL> declare
2 p_rolenm varchar2(20) := 'SUPER.ADMIN';
3 l_id number;
4 begin
5 select id into l_id
6 from test
7 where role = p_rolenm;
8
9 dbms_output.put_line('l_id = ' || l_id);
10 end;
11 /
l_id = 2
PL/SQL procedure successfully completed.
SQL>
If you need like, then
SQL> declare
2 p_rolenm varchar2(20) := 'PER.ADM'; --> I changed this ...
3 l_id number;
4 begin
5 select id into l_id
6 from test
7 where role like '%' || p_rolenm || '%'; --> ... and this
8
9 dbms_output.put_line('l_id = ' || l_id);
10 end;
11 /
l_id = 2
PL/SQL procedure successfully completed.
SQL>
If you used dynamic SQL, then
SQL> declare
2 p_rolenm varchar2(20) := 'PER.ADM';
3 l_id number;
4 l_str varchar2(200); --> new variable for execute immediate
5 begin
6 l_str := q'[select id from test where role like '%' || :a || '%']';
7 execute immediate l_str into l_id using p_rolenm;
8
9 dbms_output.put_line('l_id = ' || l_id);
10 end;
11 /
l_id = 2
PL/SQL procedure successfully completed.
SQL>
Shortly, I don't understand what you are doing. Try to follow my examples. If it still doesn't work, post your SQL*Plus session.

Assigning output parameter from Stored Procedure in oracle

Please help me with the following scenario
I need to call a Stored Procedure inside another one. the inner SP would return a number value which I need to store it in a local variable.
rough code
AssignSpResult NUMBER;
AssignSpResult = SPtobecalled(Param1,Param2, OutParam);
This syntax is most probably wrong, so please help correct it
Here is an example of how it might be:
HR\XE> create or replace procedure Proc1(p_out out number)
2 is
3 begin
4 p_out := 123;
5* end;
HR\XE> /
Procedure created.
HR\XE> create or replace procedure Proc2
2 is
3 l_val number;
4 begin
5 Proc1(l_val);
6 dbms_output.put_line('Here is a value returned by Proc1: ' || to_char(l_val));
7 end;
8 /
Procedure created.
HR\XE> set serveroutput on;
HR\XE> exec Proc2;
Here is a value returned by Proc1: 123
PL/SQL procedure successfully completed
Depending on your needs it might be more convenient to use functions to return a result of a procedural processing of data. Here is an example:
HR\XE> create or replace function F1 return number
2 is
3 l_ret_value number;
4 begin
5 l_ret_value := 123;
6 return l_ret_value;
7 end;
HR\XE> /
Function created.
HR\XE> create or replace procedure Proc3
2 is
3 l_val number;
4 begin
5 l_val := F1;
6 dbms_output.put_line('Value returned by the F1 function: ' ||
To_Char(l_val));
7 -- Or
8 dbms_output.put_line('Value returned by the F1 function: ' || To_Char(F1));
9 end;
HR\XE> /
Procedure created.
HR\XE> set serveroutput on;
HR\XE> exec proc3;
Value returned by the F1 function: 123
Value returned by the F1 function: 123
PL/SQL procedure successfully completed.
HR\XE>
A stored procedure does not return a value it takes IN, OUT or IN OUT parameters. So probably your have to call:
SPtobecalled(Param1,Param2, AssignSpResult );

Resources