PL/SQL 和 SQL Developer 的结果不同

Posted

技术标签:

【中文标题】PL/SQL 和 SQL Developer 的结果不同【英文标题】:PL/SQL and SQL Developer different results from each other 【发布时间】:2020-05-14 13:47:05 【问题描述】:

我在版本 7 和版本 14 中使用 PL/SQL 执行查询,使用我创建的函数,两者都给我带来一些结果,其余的都带来 0。 但是,当在 Oracle SQL Developer 中执行相同的查询时,该查询会正确地得出所有结果。

我也通过 PL / SQL 和 Oracle SQL Developer 执行了该过程,但是没有一个给我带来正确的结果,所有的行都保留为“0”。 我根本找不到问题所在,即使在 Google 上也是如此。

基本上,该函数将行数乘以以“ID_”开头的列,如下所示。

功能:

CREATE OR REPLACE FUNCTION DS_FUNCESP.FNBIGB_CheckDataCells
(pOwn IN VARCHAR2, 
 pTab IN VARCHAR2)
RETURN NUMBER 
IS

 v_Qtd NUMBER;
 v_str VARCHAR2(2000);
 
BEGIN
   v_Qtd := 1;
   v_str := ' SELECT
                SUM((SELECT COUNT(1) AS QTY_ROWS FROM ' || pOwn || '.' || pTab || ' d WHERE d.LINORIGEM <> ''CARGA MANUAL'')) AS QTY_DATA
              FROM DW_FUNCESP.D_BI_COLUMNS a
                LEFT JOIN
                  DW_FUNCESP.D_BI_TABLES b
                  ON a.ID_TABLE  = b.ID_TABLE
                  AND a.ID_OWNER = b.ID_OWNER
                LEFT JOIN DW_FUNCESP.D_BI_OWNERS c
                  ON a.ID_OWNER  = c.ID_OWNER
              WHERE b.NM_TABLE = ''' || pTab || '''
              AND a.IN_PRIMARYKEY       = ''NAO''
              AND SUBSTR(a.NM_COLUMN,1,3) = ''ID_'' ';

   DBMS_OUTPUT.put_line(v_str);
   EXECUTE IMMEDIATE v_str into v_Qtd ;

   return (v_Qtd);
  
EXCEPTION WHEN OTHERS THEN
       RETURN 0;
       
END FNBIGB_CheckDataCells;

选择语句:

SELECT
  c.NM_OWNER ,
  b.NM_TABLE ,
  DS_FUNCESP.FNBIGB_CHECKDATACELLS(c.NM_OWNER, b.NM_TABLE) AS QTY_DATA
FROM DW_FUNCESP.D_BI_TABLES b
  LEFT JOIN DW_FUNCESP.D_BI_OWNERS c
    ON b.ID_OWNER = c.ID_OWNER;

PL/SQL 的结果:

Oracle SQL Developer 的结果:

很明显,我们可以从任何一行看到不同之处,正确的是 Oracle SQL Developer。所以我想知道问题出在哪里,如何解决,因为无论我在哪里运行,程序都会在所有行中添加“0”。

【问题讨论】:

你的代码中有一个很好的bug EXCEPTION WHEN OTHERS THEN RETURN 0;阅读WHEN OTHERS - A Bug 太好了,我不知道,它甚至没有显示错误。第一个错误是因为有些表不再存在。所以,我用的是WHEN OTHERS THEN IF SQLCODE != -942 THEN RAISE; END IF;RAISEEXCEPTION中是什么意思? 对于 SQL Developer 是如何设法“克服”这些错误而 PL / SQL 却没有,这让人们更加困惑。 @GuilhermeMatheus 阅读docs.oracle.com/database/121/LNPLS/errors.htm#LNPLS007 SQL Developer 没有克服那个异常,你的代码做到了。一个 PLSQL 块包含 3 个不同的部分:声明、执行、异常。当异常发生时,控制立即传递给异常处理程序。一个 WHEN 之后没有加注,它告诉 PLSQL 忽略它。 A WHEN OTHERS 表示所有可能的例外情况。在您的情况下,返回 0,这正是 PLSQL 所做的。我建议您花一些时间阅读文档。一个很好的起点2day devalopers guide。 【参考方案1】:

从WHEN OTHERS - A Bug 阅读这些示例,感谢@Lalit Kumar B,我改变了:

EXCEPTION WHEN OTHERS THEN
       RETURN 0;

收件人:

EXCEPTION 
   WHEN OTHERS THEN
        DBMS_OUTPUT.PUT_LINE('SQLCODE: '||SQLCODE);
        DBMS_OUTPUT.PUT_LINE('Message: '||SQLERRM);
        RAISE;

为了找出问题所在,感谢您,我发现它试图从不再存在的表中计数。

所以我使用下面的错误处理,来自@Jeffrey Kemp

EXCEPTION
   WHEN OTHERS THEN
      IF SQLCODE != -942 THEN
         RAISE;
      END IF;

另外,感谢@Belayer,我的代码是问题所在,同意这一点。此外,在这两个软件上执行,让我更加困惑。我肯定还会阅读该文档。

【讨论】:

以上是关于PL/SQL 和 SQL Developer 的结果不同的主要内容,如果未能解决你的问题,请参考以下文章

pl sql developer怎么执行sql

pl sql developer怎么执行sql

PL/SQL 和 SQL Developer 的结果不同

pl/sql developer中文乱码,为啥呢?怎么解决?Oracle问题

为啥 ActiveRecord SQL 和 PL/SQL Developer SQL 之间存在差异?

PL/SQL Developer 替代方案 [关闭]