不使用BULK,但仍得到ORA-06502:PL / SQL:数字或值错误:批量绑定:截断了绑定

时间:2019-01-08 20:29:49

标签: oracle plsql

以下语句导致此错误消息:

ORA-06502: PL/SQL: numeric or value error: Bulk Bind: Truncated Bind

BEGIN
   FOR rec IN (SELECT
                  COALESCE (
                            (SELECT '123' FROM dual WHERE  1=0) ,
                            (SELECT '123' || '4' FROM dual)
                           )
                          FROM DUAL
              )
   LOOP
        NULL;
   END LOOP;
END;
/

显然没有以任何方式涉及批量声明。

当我将第一个123更改为1234时,错误消失了。似乎游标中的COALESCE弄乱了分配的字符串空间?

我的Oracle 12.2.0.1也会发生这种情况,https://livesql.oracle.com/中的Oracle 18也会发生这种情况(需要注册)

这是一个Oracle错误还是我忽略了某些东西。

更新

我已经通过Oracle创建了服务请求。他们可以重现问题并正在调查。

2 个答案:

答案 0 :(得分:1)

您可以使用NVL2代替COALESCE

BEGIN
   FOR rec IN (SELECT
                  NVL2 (
                            (SELECT '123' FROM dual WHERE  1=0) ,
                            (SELECT '123' || '4' FROM dual), null
                           )
                          FROM DUAL
              )
   LOOP
        NULL;
   END LOOP;
END;
/

编辑对于问题的根本原因

首先,Coalesce需要两个参数都属于同一数据类型。另外,表达式的数据类型是按顺序确定的。

在您的情况下,似乎您的第一个查询是三个字符长的SELECT '123' FROM dual WHERE 1=0),而第二个查询是4个字符长的并置连接(并置在这里起作用:我也正在尝试对此进行排序)。因此,oracle尝试将varchar2(4)数据类型(第二条语句)转换为varchar2(3)数据类型(第一条语句)。因此,发生ORA-6502

答案 1 :(得分:-1)

排序看起来像是因为第一次选择将导致NO_DATA_FOUND而不是真正的NULL,然后导致COALESCE无法工作,但是NVL会处理它,所以有点奇怪。

一种解决方法是将选择内容按照以下内容包装在NVL中...

BEGIN
   FOR rec IN (SELECT
                  NVL2 (
                            (NVL((SELECT '123' FROM dual WHERE  1=0), null)) ,
                            (SELECT '123' || '4' FROM dual), null
                           )
                          FROM DUAL
              )
   LOOP
        NULL;
   END LOOP;
END;
/