oracle-databaseplsqloracle-sqldeveloperref-cursor

How to print a cursor in a PL/SQL block?


I can't seem to print cursor, what am I doing wrong?

DECLARE
  LEADEMAIL VARCHAR2(200);
  CLIENTID NUMBER;
  v_Return ON24MASTER.WEBCAST_REPORTS.ResultSetCursor;
BEGIN
  LEADEMAIL := 'nunyo@business.com';
  CLIENTID := 22921;

  v_Return := WEBCAST_REPORTS.LEAD_BASIC_INFO(
    LEADEMAIL => LEADEMAIL,
    CLIENTID => CLIENTID
  );

    DBMS_OUTPUT.PUT_LINE('v_Return = ' || v_Return);
--    :v_Return := v_Return;

END;

I get the following error:

Error report -
ORA-06550: line 14, column 26:
PLS-00306: wrong number or types of arguments in call to '||'
ORA-06550: line 14, column 5:
PL/SQL: Statement ignored
06550. 00000 -  "line %s, column %s:\n%s"
*Cause:    Usually a PL/SQL compilation error.
*Action:

Most of the code was taken directly from running the function from SQL developer.

This is the package function:

  FUNCTION LEAD_BASIC_INFO(
    leadEmail VARCHAR2,
    clientId NUMBER
  ) RETURN ResultSetCursor IS
    resultSet ResultSetCursor;
    email VARCHAR2(1000);
    webcastEngagement NUMBER(10,1);
    videoEngagement NUMBER(10,1);
    documentEngagement NUMBER(10,1);
    totalEngagement NUMBER(10,1);
    --averageEngagement NUMBER(4,1);
    totalWebcastSeconds NUMBER(10);
    engagementMinutes NUMBER(10, 1);
    last30DaysEM NUMBER(10, 1);
    last60DaysEM NUMBER(10, 1);
    fromDate DATE;
    engagementPrediction NUMBER(10);
  BEGIN...

Also, I can't print the result using a select statement because the function has DML as well.


Solution

  • You can't print a cursor like that; it would have to implicitly convert the rows and columns to strings, and that's too much to expect. The dbms_output.put_line() procedure only accepts a string argument - or anything that can be implicitly converted to a string. A cursor cannot.

    You would have to loop over the cursor result set, fetching into a suitable record type; and then have a dbms_output call within that loop which concatenates all the column values from the result set (formatted and possibly padded if you're trying to emulate a select) into a single string.

    Without know exactly how ON24MASTER.WEBCAST_REPORTS.ResultSetCursor is defined (presumably TYPE ResultSetCursor IS REF CURSOR), or what the query that populates it within your procedure is returning - which column names - it's hard to be more specific.

    But since you've tagged this for SQL Developer you can use its built-in handling for ref cursor variables, which is handy:

    variable rc refcursor;
    
    DECLARE
      LEADEMAIL VARCHAR2(200);
      CLIENTID NUMBER;
    BEGIN
      LEADEMAIL := 'nunyo@business.com';
      CLIENTID := 22921;
    
      :rc := WEBCAST_REPORTS.LEAD_BASIC_INFO(
        LEADEMAIL => LEADEMAIL,
        CLIENTID => CLIENTID
      );
    
    END;
    /
    
    print rc
    

    Before the block a bind variable rc is declared with the variable command. Inside the block that is used instead of a local v_Return, so that doesn't even need to be declared locally. (Note the colon before :rc in the assignment from the function - that denotes a bind variable). And then after the block the client lets you print the ref cursor. (Those doc links are for SQL*Plus, but they are among the the many commands SQL Developer supports.)

    With a dummy package:

    create or replace package WEBCAST_REPORTS AS
      TYPE ResultSetCursor IS ref cursor;
      FUNCTION LEAD_BASIC_INFO(
        leadEmail VARCHAR2,
        clientId NUMBER
      ) RETURN ResultSetCursor;
    end WEBCAST_REPORTS;
    /
    
    create or replace package body WEBCAST_REPORTS AS
      FUNCTION LEAD_BASIC_INFO(
        leadEmail VARCHAR2,
        clientId NUMBER
      ) RETURN ResultSetCursor IS
        resultSet ResultSetCursor;
      BEGIN
        OPEN resultSet FOR select * from dual;
        RETURN resultSet;
      END LEAD_BASIC_INFO;
    end WEBCAST_REPORTS;
    /
    

    then the code I showed above, run as a script, shows this in the script output window:

    PL/SQL procedure successfully completed.
    
    
    D
    -
    X