Oracle 如何在PL/SQL块中打印光标?

Oracle 如何在PL/SQL块中打印光标?,oracle,plsql,oracle-sqldeveloper,ref-cursor,Oracle,Plsql,Oracle Sqldeveloper,Ref Cursor,我似乎无法打印光标,我做错了什么 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( LEADEMAI

我似乎无法打印光标,我做错了什么

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;
我得到以下错误:

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:
大部分代码是直接从SQLDeveloper运行函数中获取的

这是软件包功能:

  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。

您不能这样打印光标;它必须隐式地将行和列转换为字符串,这是不可能的。
dbms\u output.put\u line()
过程只接受字符串参数或任何可以隐式转换为字符串的参数。光标不能移动

您必须在游标结果集上循环,获取合适的记录类型;然后在该循环中调用
dbms\u output
,将结果集中的所有列值(如果您试图模拟select,则格式化并可能填充)连接到单个字符串中

如果不知道24master.WEBCAST\u报告.ResultSetCursor是如何定义的(大概
类型ResultSetCursor是REF CURSOR
),或者在您的过程中填充它的查询返回什么-哪些列名-很难更具体

但是,由于您已经为SQL Developer标记了该变量,您可以使用其内置的ref cursor变量处理,这很方便:

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
在块之前,使用声明绑定变量
rc
。在用来代替本地
v_Return
的块中,甚至不需要在本地声明。(注意函数赋值中
:rc
前面的冒号-表示绑定变量)。然后在阻塞之后,客户端允许您使用ref游标。(这些文档链接是针对SQL*Plus的,但它们是最常用的链接之一。)

使用虚拟包:

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

你不能像那样打印光标;它必须隐式地将行和列转换为字符串,这是不可能的。
dbms\u output.put\u line()
过程只接受字符串参数或任何可以隐式转换为字符串的参数。光标不能移动

您必须在游标结果集上循环,获取合适的记录类型;然后在该循环中调用
dbms\u output
,将结果集中的所有列值(如果您试图模拟select,则格式化并可能填充)连接到单个字符串中

如果不知道24master.WEBCAST\u报告.ResultSetCursor是如何定义的(大概
类型ResultSetCursor是REF CURSOR
),或者在您的过程中填充它的查询返回什么-哪些列名-很难更具体

但是,由于您已经为SQL Developer标记了该变量,您可以使用其内置的ref cursor变量处理,这很方便:

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
在块之前,使用声明绑定变量
rc
。在用来代替本地
v_Return
的块中,甚至不需要在本地声明。(注意函数赋值中
:rc
前面的冒号-表示绑定变量)。然后在阻塞之后,客户端允许您使用ref游标。(这些文档链接是针对SQL*Plus的,但它们是最常用的链接之一。)

使用虚拟包:

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

在Oracle 12c中,您可以使用
DBMS\u SQL。返回\u结果
。即

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_SQL.RETURN_RESULT(v_Return); 

END;

SQL*Developer将打印结果。

在Oracle 12c中,您可以使用
DBMS\u SQL。返回\u结果
。即

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_SQL.RETURN_RESULT(v_Return); 

END;


SQL*开发者将打印结果。

无法真正找到
ResultSetCursor
的定义位置。它不在包裹里。。我还能去哪里看呢?好吧,我想那一定是一个
ref游标
,但是您仍然需要知道查询返回什么以使用
dbms\u输出
。作为一个起点。如果您的客户支持,您甚至可以使用变量/打印机制-我不记得这是否适用于任何引用游标(我想是的…)也可以使用bind变量实现这一功能。太糟糕了,它显示得太可怕了jeje@estebanrincon-您可以使用常规格式工具,如
设置行大小
列x格式a10
或其他任何工具,这些工具通过
打印
来实现。不幸的是,由于某些原因,
set-sqlformat-ansiconsole
不是。无法真正找到定义
ResultSetCursor
的位置。它不在包裹里。。我还能去哪里看呢?好吧,我想那一定是一个
ref游标
,但是您仍然需要知道查询返回什么以使用
dbms\u输出
。作为一个起点。如果您的客户支持,您甚至可以使用变量/打印机制-我不记得这是否适用于任何引用游标(我想是的…)也可以使用bind变量实现这一功能。太糟糕了,它显示得太可怕了jeje@estebanrincon-您可以使用常规格式工具,如
设置行大小
列x格式a10
或其他任何工具,这些工具通过
打印
来实现。不幸的是,
set-sqlformat-ansiconsole
不是出于某种原因。我希望这不是一个真实的电子邮件地址。:-/I将电子邮件地址更改为一个假地址。@Gary\u我一直都在想这个问题,但粘贴代码时。。。忘了-谢谢jejeI希望这不是一个真实的电子邮件地址。:-/我把电子邮件地址改成了一个假的。@Gary_W一直在我的脑海里想着它,但是当粘贴代码时。。。忘了,谢谢你,杰杰11g@Matthew我得到
ORA-29481:隐式结果无法返回到client.ORA-06512:at“SYS.DBMS_SQL”,第2785行。ORA-06512:“SYS.DBMS_SQL”,第2行