Как напечатать курсор в блоке PL/SQL?

Я не могу печатать курсор, что я делаю не так?

DECLARE
  LEADEMAIL VARCHAR2(200);
  CLIENTID NUMBER;
  v_Return ON24MASTER.WEBCAST_REPORTS.ResultSetCursor;
BEGIN
  LEADEMAIL := '[email protected]';
  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;

Я получаю следующую ошибку:

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:

Большая часть кода была взята непосредственно из запуска функции от разработчика SQL.

Это функция пакета:

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

Кроме того, я не могу распечатать результат с помощью оператора select, потому что функция также имеет DML.


person esteban rincon    schedule 16.08.2018    source источник
comment
Я надеюсь, что это не настоящий адрес электронной почты. :-/   -  person Gary_W    schedule 16.08.2018
comment
Я изменил адрес электронной почты на поддельный.   -  person Gary_W    schedule 16.08.2018
comment
@Gary_W Все время думал об этом, но когда вставлял код... забыл ¬¬Спасибо, jeje   -  person esteban rincon    schedule 16.08.2018


Ответы (2)


Вы не можете напечатать такой курсор; ему пришлось бы неявно преобразовывать строки и столбцы в строки, а этого ожидать слишком много. Процедура dbms_output.put_line() принимает только строковый аргумент или любой другой аргумент, который можно неявно преобразовать в строку. Курсор не может.

Вам придется перебрать набор результатов курсора, выбирая подходящий тип записи; а затем вызовите dbms_output в этом цикле, который объединяет все значения столбца из набора результатов (отформатированные и, возможно, дополненные, если вы пытаетесь эмулировать выбор) в одну строку.

Не зная точно, как определяется ON24MASTER.WEBCAST_REPORTS.ResultSetCursor (предположительно TYPE ResultSetCursor IS REF CURSOR), или что возвращает запрос, который заполняет его в вашей процедуре - какие имена столбцов - трудно быть более конкретным.

Но поскольку вы пометили это для SQL Developer, вы можете использовать его встроенную обработку для переменных курсора ref, что удобно:

variable rc refcursor;

DECLARE
  LEADEMAIL VARCHAR2(200);
  CLIENTID NUMBER;
BEGIN
  LEADEMAIL := '[email protected]';
  CLIENTID := 22921;

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

END;
/

print rc

Перед блоком объявляется переменная связывания rc с помощью команды variable< /а>. Внутри блока, который используется вместо локального v_Return, поэтому его даже не нужно объявлять локально. (Обратите внимание на двоеточие перед :rc в назначении из функции - это обозначает переменную связывания). А затем после блокировки клиент позволяет вам print курсор ссылки. (Эти ссылки на документы предназначены для SQL*Plus, но они входят в число множество команд, поддерживаемых SQL Developer.)

С фиктивным пакетом:

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;
/

затем код, который я показал выше, запускается как скрипт, показывает это в окне вывода скрипта:

PL/SQL procedure successfully completed.


D
-
X
person Alex Poole    schedule 16.08.2018
comment
Не могу найти, где определяется ResultSetCursor. В упаковке его нет..где еще посмотреть? - person esteban rincon; 16.08.2018
comment
Что ж, я предполагаю, что это должно быть ref cursor, но вам все равно нужно знать, что возвращает запрос, чтобы использовать dbms_output. Это может помочь в качестве отправной точки. Возможно, вы даже сможете использовать механизм переменной/печати, если ваш клиент поддерживает это - я не могу вспомнить, работает ли он с любым курсором ref (я так думаю...). - person Alex Poole; 16.08.2018
comment
Я предполагаю, что использование set autoprint on; поможет и с переменной связывания. Жаль, что это отображается ТАК УЖАСНО, jeje - person esteban rincon; 16.08.2018
comment
@estebanrincon - вы можете использовать обычные инструменты форматирования, такие как set linesize и column x format a10 или что-то еще, и print уважает их. К сожалению, set sqlformat ansiconsole почему-то нет. - person Alex Poole; 17.08.2018

В Oracle 12c вы можете использовать DBMS_SQL.RETURN_RESULT. то есть,

DECLARE
  LEADEMAIL VARCHAR2(200);
  CLIENTID NUMBER;
  v_Return ON24MASTER.WEBCAST_REPORTS.ResultSetCursor;
BEGIN
  LEADEMAIL := '[email protected]';
  CLIENTID := 22921;

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

    DBMS_SQL.RETURN_RESULT(v_Return); 

END;

SQL*Developer распечатает результаты.

person Matthew McPeak    schedule 16.08.2018
comment
К сожалению работает 11g - person esteban rincon; 16.08.2018
comment
@Matthew Я получаю ORA-29481: Implicit results cannot be returned to client.ORA-06512: at "SYS.DBMS_SQL", line 2785. ORA-06512: at "SYS.DBMS_SQL", line 2779 , когда пробовал 12c в SQL Developer (Version 4.0.2.15 ). Является ли это причиной oraexcel.com/. - person SMPH; 16.12.2020
comment
@SMPH Вам необходимо перейти на более поздние версии SQL * Developer. В версии 4.0.x были встроены только драйверы JDBC 11.x, iirc. - person Matthew McPeak; 16.12.2020
comment
@MatthewMcPeak Какая лучшая альтернатива для 12C с вышеуказанной версией SQL Dev без определения всех столбцов? Потому что в моем случае слишком много столбцов. - person SMPH; 17.12.2020
comment
Вам не нужно обновлять Oracle. Вышеуказанная функция работает в 12c. Вам просто нужно использовать более современное клиентское программное обеспечение. Получите последнюю версию SQL*Developer и подключите ее к существующей базе данных Oracle, и все должно быть хорошо. - person Matthew McPeak; 17.12.2020