Simple Oracle Procedure Failing - oracle

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>

Related

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>

create a procedure to create a table in Pl/sql from a select statement

I have a select query
select s.site, s.date, s.loaction, s.modified, sysdate p_run_date
from table s
where s.site = 123 --p_site
and s.date >= sysdate -p_date.
i want to create a pl/sql procedure to create a table where p_date and p_site need to be input to the procedure
Why would you want to do that? We normally do NOT create tables dynamically (which is what you'd use in PL/SQL). That procedure would try to create a table with the same name every time you call it (but with different parameters) and fail because table with such a name already exists (as it was created the first time you ran the procedure). Therefore, having a one-time procedure is pretty much useless.
If it must be done, oh well ...
SQL> create or replace procedure p_test (par_deptno in number, par_job in varchar2)
2 is
3 l_str varchar2(200);
4 begin
5 l_str := 'create table my_test as ' ||
6 'select deptno, ename, job, sal ' ||
7 'from emp ' ||
8 'where deptno = ' || dbms_assert.enquote_literal(par_deptno) ||
9 ' and job = ' || dbms_assert.enquote_literal(par_job);
10 execute immediate l_str;
11 end;
12 /
Procedure created.
Testing:
SQL> exec p_test(10, 'CLERK');
PL/SQL procedure successfully completed.
SQL> select * from my_test;
DEPTNO ENAME JOB SAL
---------- ---------- --------- ----------
10 MILLER CLERK 1300
Let's try it again, with different parameters:
SQL> exec p_test(20, 'MANAGER');
BEGIN p_test(20, 'MANAGER'); END;
*
ERROR at line 1:
ORA-00955: name is already used by an existing object
ORA-06512: at "SCOTT.P_TEST", line 10
ORA-06512: at line 1
SQL>
As I said, it'll fail. What you're trying to do is just wrong. You'd rather create a view.

Oracle : How to drop procedures matched by the name mask

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.

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.

How to call a Stored procedure with aggregate result in output?

I have a simple select query that needs to be put into a stored procedure.
The query takes in 3 parameters and displays 2 columns as result, one of them being an aggregate.
CREATE OR REPLACE PROCEDURE "B_SP_GET_TOTAL_CLOCKED_IN_TIME"
(
cv_1 IN OUT TYPES.cursorType,
p_PARENT_CLIENT_ID IN NUMBER DEFAULT 10000,
p_START_TIME IN NVARCHAR2,
p_END_TIME IN NVARCHAR2
)
AS
v_sql VARCHAR2(4000);
BEGIN
v_sql := 'SELECT b.CLIENT_NAME, ROUND(SUM((a.ENDTIME-a.STARTTIME)*24*60),2) TOTAL_CLOCKIN_TIME
FROM TIMESHEET a
INNER JOIN CLIENTS b ON a.CLIENT_ID = b.CLIENT_ID
INNER JOIN CLOCKACTIONS c ON c.ID = a.CLOCKACTIONID
WHERE a.STARTTIME > p_START_TIME AND a.ENDTIME < p_END_TIME AND b.PARENT_CLIENT_ID = p_PARENT_CLIENT_ID
GROUP BY b.CLIENT_NAME';
OPEN cv_1 FOR v_sql;
END;
I executed the stored procedure and it got compiled, with no issues.
How do i check if its working properly? As in how do I test it now?
The statement I used to test the above procedure can be found below:
execute B_SP_GET_TOTAL_CLOCKED_IN_TIME(10000,'04-01-2015 00:00:00','05-01-2015 00:00:00');
This was the error I got:
Error starting at line : 1 in command - execute B_SP_GET_TOTAL_CLOCKED_IN_TIME(10000,'04-01-2015 00:00:00','05-01-2015 00:00:00')
Error report - ORA-06550: line 1, column 7:
PLS-00306: wrong number or types of arguments in call to 'B_SP_GET_TOTAL_CLOCKED_IN_TIME'
ORA-06550: line 1, column 7: PL/SQL: Statement ignored
06550. 00000 - "line %s, column %s:\n%s"
*Cause: Usually a PL/SQL compilation error.
*Action:
There is not need of (ab)using dynamic SQL. You could simple use OPEN FOR SELECT and use a SYS_REFCURSOR.
For example,
SQL> CREATE OR REPLACE
2 PROCEDURE p_get_emp(
3 p_deptno IN emp.deptno%TYPE,
4 p_ref OUT SYS_REFCURSOR)
5 AS
6 BEGIN
7 OPEN p_ref FOR
8 SELECT ename,
9 empno,
10 deptno
11 FROM emp
12 WHERE deptno = p_deptno
13 ORDER BY empno;
14 END p_get_emp;
15 /
Procedure created.
SQL>
SQL> sho err
No errors.
SQL>
Procedure created without any errors. Let's test it:
SQL> var p_ref refcursor
SQL>
SQL> EXEC p_get_emp (30, :p_ref);
PL/SQL procedure successfully completed.
SQL>
SQL> print p_ref
ENAME EMPNO DEPTNO
---------- ---------- ----------
ALLEN 7499 30
WARD 7521 30
MARTIN 7654 30
BLAKE 7698 30
TURNER 7844 30
JAMES 7900 30
6 rows selected.
SQL>

Resources