Search code examples
oracle-databasestored-proceduresplsqlaggregatesys-refcursor

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:

Solution

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