Oracle : How to drop procedures matched by the name mask - oracle

I have created two procedures like :
CREATE OR REPLACE procedure PARTNER_OWNER.test_1
as begin
dbms_output.put_line('Hello World 1 !');
end;
and
CREATE OR REPLACE procedure PARTNER_OWNER.test_2
as begin
dbms_output.put_line('Hello World 2 !');
end;
Now I need to drop the procedures at the same time (something like ):
drop procedure PARTNER_OWNER.test_*;
Is there a way to do that?

I would use a select statement to generate the drop statements and then run them.
select 'DROP PROCEDURE PARTNER_OWNER.'||object_name||';'
from dba_objects
where object_name like 'TEST_%' and
owner = 'PARTNER_OWNER';
Bobby

One option is to use dynamic SQL. Here's an example:
SQL> create or replace procedure test_1
2 as begin
3 dbms_output.put_line('Hello World 1 !');
4 end;
5 /
Procedure created.
SQL> create or replace procedure test_2
2 as begin
3 dbms_output.put_line('Hello World 2 !');
4 end;
5 /
Procedure created.
SQL> exec test_1;
Hello World 1 !
PL/SQL procedure successfully completed.
SQL> exec test_2;
Hello World 2 !
PL/SQL procedure successfully completed.
Now, drop them:
SQL> begin
2 for cur_r in (select object_name from user_objects
3 where object_type = 'PROCEDURE'
4 and object_name like 'TEST%')
5 loop
6 execute immediate 'drop procedure ' || cur_r.object_name;
7 end loop;
8 end;
9 /
PL/SQL procedure successfully completed.
The result:
SQL> exec test_1;
BEGIN test_1; END;
*
ERROR at line 1:
ORA-06550: line 1, column 7:
PLS-00201: identifier 'TEST_1' must be declared
ORA-06550: line 1, column 7:
PL/SQL: Statement ignored
SQL> exec test_2;
BEGIN test_2; END;
*
ERROR at line 1:
ORA-06550: line 1, column 7:
PLS-00201: identifier 'TEST_2' must be declared
ORA-06550: line 1, column 7:
PL/SQL: Statement ignored
Alternatively, instead of using an anonymous PL/SQL block, you can rewrite it to a procedure and reuse it later. As it accepts a parameter, you can drop any procedure. Pay attention to LIKE (so that you wouldn't drop a procedure you didn't really want to).
SQL> create or replace procedure p_drop_prc(par_procedure_name in varchar2)
2 is
3 begin
4 for cur_r in (select object_name from user_objects
5 where `enter code here`object_type = 'PROCEDURE'
6 and object_name like upper(par_procedure_name) ||'%')
7 loop
8 execute immediate 'drop procedure ' || cur_r.object_name;
9 end loop;
10 end;
11 /
Procedure created.
SQL> exec p_drop_prc('test');
PL/SQL procedure successfully completed.
SQL> exec test_1;
BEGIN test_1; END;
*
ERROR at line 1:
ORA-06550: line 1, column 7:
PLS-00201: identifier 'TEST_1' must be declared
ORA-06550: line 1, column 7:
PL/SQL: Statement ignored
SQL>
Also, you could add another parameter - object type - so that you could drop any object, not just a procedure.
Obviously, quite a few options; pick the one you find the most appropriate.

Related

ORACLE PL/SQL : How to pass an exception into a procedure

Is there a way to pass exception into a procedure to call "raise" after doing some actions to process exception. So that the outer code block will get the exact exception that was raised
Something like this:
begin
...
exception
when others then
error_handler( err );
end;
procedure error_handler ( err ) is
begin
/*
here some code to handle and log the exception...
*/
raise err;
end;
Or the only way is to pass SQLCODE and SQLERRM into the procedure and later call raise_application_error( SQLCODE, SQLERRM )?
If I understood you correctly, this is what you're asking.
Sample log table:
SQL> create table err_log
2 (program varchar2(30),
3 datum date,
4 sqlcode number
5 );
Table created.
Logging procedure should be an autonomous transaction so that you could commit in it, without affecting main transaction.
SQL> create or replace procedure error_handler
2 (p_program in varchar2, p_sqlcode in number)
3 is
4 pragma autonomous_transaction;
5 begin
6 insert into err_log (program, datum, sqlcode)
7 values (p_program, sysdate, p_sqlcode);
8 commit;
9 end;
10 /
Procedure created.
Another procedure (whose execution you're logging); it'll raise division by zero. See lines #8 and #9 which call the logging procedure and then just re-raise the error:
SQL> create or replace procedure p_test is
2 l_program varchar2(30) := 'P_TEST';
3 l_value number;
4 begin
5 l_value := 1 / 0;
6 exception
7 when others then
8 error_handler(l_program, sqlcode);
9 raise;
10 end p_test;
11 /
Procedure created.
OK, everything is set. Let's try it:
SQL> exec p_test;
BEGIN p_test; END;
*
ERROR at line 1:
ORA-01476: divisor is equal to zero --> this is result of RAISE in line #9
ORA-06512: at "SCOTT.P_TEST", line 9
ORA-06512: at "SCOTT.P_TEST", line 5
ORA-06512: at line 1
Log table contents:
SQL> select * from err_log;
PROGRAM DATUM SQLCODE
------------------------------ ------------------- ----------
P_TEST 01.11.2022 11:13:31 -1476
SQL>
You asked, literally:
How to pass an exception into a procedure?
You can't, as far as I can tell:
SQL> create or replace procedure error_handler_text
2 (p_err in exception) --> if this is what you asked
3 is
4 begin
5 null;
6 end;
7 /
Warning: Procedure created with compilation errors.
SQL> show err
Errors for PROCEDURE ERROR_HANDLER_TEXT:
LINE/COL ERROR
-------- -----------------------------------------------------------------
2/13 PLS-00103: Encountered the symbol "EXCEPTION" when expecting one
of the following:
out <an identifier> <a double-quoted delimited-identifier>
table columns long double ref char standard time timestamp
interval date binary national character nchar
The symbol "<an identifier> was inserted before "EXCEPTION" to
continue.
SQL>

Oracle return the value of a variable

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 ...

How to run select statement after stored procedure run ORACLE

I am new to Oracle, trying to run select statement after my stored procedure and failing. Here I am trying to return rows or any dummy data after my store procedure is executed, because my end process needs a return data for sure to make it consider as successful run. Is there any way I can trick it here is what I tried and failed.
EX:
BEGIN
note.name;
END;
/
SELECT * from hello.table where rownum=1;
Error:
ERROR [HY000] [Microsoft][ODBC Oracle Wire Protocol driver][Oracle]ORA-06550: line 4, column 1:
PLS-00103: Encountered the symbol "/"
Activity ID: xxxxxx-xxx-xxx-xxx-xxxxxx
Show return a single row after completion of stored procedure
Code you posted looks OK. Demo:
SQL> create or replace procedure p_test as
2 begin
3 null;
4 end;
5 /
Procedure created.
SQL> begin
2 p_test;
3 end;
4 /
PL/SQL procedure successfully completed.
SQL> select * from dept where rownum = 1;
DEPTNO DNAME LOC
---------- -------------- -------------
10 ACCOUNTING NEW YORK
SQL>
Therefore, what exactly is your problem? What result do you expect?
If "at once" (as you commented) means that everything should be part of a PL/SQL block, then you'd declare a variable which is capable of holding the whole row, and then just select into it. rownum = 1 condition prevents too_many_rows error.
SQL> set serveroutput on
SQL>
SQL> declare
2 l_dept dept%rowtype;
3 begin
4 p_test;
5 select * into l_dept from dept where rownum = 1;
6 dbms_output.put_line(l_dept.deptno ||', '|| l_dept.dname ||', '|| l_dept.loc);
7 end;
8 /
10, ACCOUNTING, NEW YORK
PL/SQL procedure successfully completed.
SQL>

Simple Oracle Procedure Failing

I have a very simple test proc:
create or replace PROCEDURE TestSproc
(userName in VARCHAR2, p_Test OUT SYS_REFCURSOR)IS
BEGIN
OPEN p_Test FOR
SELECT * FROM Test_Table
WHERE name = userName ;
END TestSproc;
When I run the proc (ctrl f10) in sqldeveloper on the proc page I get the result I would expect. But when I try to call the proc with the below query I get the error:
Error starting at line : 1 in command - begin DB.TestSproc('Phil'); end;
Error report - ORA-06550: line 2, column 1:
PLS-00306: wrong number or types of arguments in call to 'TestSproc'
ORA-06550: line 2, column 1: PL/SQL: Statement ignored
06550. 00000 - "line %s, column %s:\n%s"
*Cause: Usually a PL/SQL compilation error.
*Action:
begin
DB.TestSproc('Phil');
end;
Can anyone please point me in the correct direction.
EDIT
In SQL Server I would simply do:
USE DB;
GO
EXEC dbo.TestSproc#Name= 'Phil';
Assuming you are using Oracle 12c with a 12c client:
create or replace procedure testsproc
( username in varchar2 )
as
resultset sys_refcursor;
begin
open resultset for
select * from test_table
where name = username;
dbms_sql.return_result(resultset);
end testsproc;
Then call it with
exec testsproc('Phil')
or
call testsproc('Phil');
or
begin
testsproc('Phil');
end;
depending on what you are calling it from.
Further reading
You have to put the output somewhere, so - declare an appropriate variable:
SQL> create or replace procedure p_test (par_deptno in number, p_emps out sys_refcursor) is
2 begin
3 open p_emps for
4 select deptno, empno, ename
5 from emp
6 where deptno = par_deptno;
7 end;
8 /
Procedure created.
SQL>
SQL> var l_out refcursor
SQL>
SQL> begin
2 p_test(10, :l_out);
3 end;
4 /
PL/SQL procedure successfully completed.
SQL>
SQL> print :l_out;
DEPTNO EMPNO ENAME
---------- ---------- ----------
10 7839 KING
10 7782 CLARK
10 7934 MILLER
SQL>

call procedure inside sqlplus

I am working with a sqlplus code and plsql, my procedure in plsql works fine but when i execute procedure inside sql plus I encounter some error report.
heres my code:
set serveroutput on;
DECLARE
ENDDATE DATE;
BEGIN
SELECT SOME_DATE INTO ENDDATE FROM HEADER WHERE ID=1182446;
IF ENDDATE >= TO_DATE('18-MAY-13') THEN
EXECUTE SOMEPROCEDURE(1182446);
END IF;
END;
Error report -
ORA-06550: line 8, column 8:
PLS-00103: Encountered the symbol "SOMEPROCEDURE" when expecting one of the following:
:= . ( # % ;
The symbol ":=" was substituted for "SOMEPROCEDURE" to continue.
06550. 00000 - "line %s, column %s:\n%s"
*Cause: Usually a PL/SQL compilation error.
*Action:
IF ENDDATE >= TO_DATE('18-MAY-13') THEN
EXECUTE SOMEPROCEDURE(1182446);
END IF;
Since you are calling the procedure in an anonymous PL/SQL block, EXECUTE command is not required, since it is a SQL*Plus command and not PL/SQL.
You could simply call the procedure as:
IF ENDDATE >= TO_DATE('18-MAY-13') THEN
SOMEPROCEDURE(1182446);
END IF;
If you want to execute the procedure alone in SQL*Plus, then you could use the EXECUTE or EXEC command.
For example,
In SQL*Plus:
SQL> CREATE OR REPLACE
2 PROCEDURE get_emp(
3 emp_no IN emp.empno%type,
4 dept_no OUT emp.deptno%type )
5 AS
6 BEGIN
7 SELECT deptno INTO dept_no FROM emp WHERE empno = emp_no;
8 END;
9 /
Procedure created.
SQL> var dno number
SQL> var eno number
SQL> exec :eno := 7369
PL/SQL procedure successfully completed.
SQL> EXEC get_emp(:eno, :dno);
PL/SQL procedure successfully completed.
SQL> print dno
DNO
----------
20
SQL>
If you want to call the procedure inside another PL/SQL block, then you could do it as:
Anonymous PL/SQL block:
SQL> set serveroutput on
SQL> DECLARE
2 dt DATE;
3 dept_no NUMBER;
4 BEGIN
5 SELECT hiredate INTO dt FROM emp WHERE empno = 7369;
6 IF dt < SYSDATE THEN
7 get_emp(7369, dept_no);
8 DBMS_OUTPUT.PUT_LINE('Department number is '||dept_no);
9 END IF;
10 END;
11 /
Department number is 20
PL/SQL procedure successfully completed.

Resources