仅在第一次运行语句时引发NULL索引表键值错误

时间:2016-06-02 12:48:09

标签: oracle plsql

我对此代码描述的两种不同模式有一个观点:

CREATE OR REPLACE VIEW LINKTYPE AS
SELECT LINKTYPEID
,      nvl((select value from translation where translation2dimobject = 14 and objectid = linktypeid and columnid = 1 and localeid = SYS_CONTEXT('CRAMERSESSION', 'LOCALEID')), NAME) NAME
,      LINKTYPE2GRAPHICSBITMAP
,      LINKTYPE2BROWSERBITMAP
,      TABLENAME
,      nvl((select value from translation where translation2dimobject = 14 and objectid = linktypeid and columnid = 2 and localeid = SYS_CONTEXT('CRAMERSESSION', 'LOCALEID')), CLASS) CLASS
,      nvl((select value from translation where translation2dimobject = 14 and objectid = linktypeid and columnid = 3 and localeid = SYS_CONTEXT('CRAMERSESSION', 'LOCALEID')), DESCRIPTION) DESCRIPTION
,      RESOLUTIONBEHAVIOUR
,      LENGTHCALLOUT
,      ISVISIBLE
,      LABEL
from   LINKTYPE_M with read only;

然后我从两个模式中调用此函数:

FUNCTION getLinkTypeID (pis_link_type_name LINKTYPE.NAME%TYPE)
RETURN NUMBER IS

   ln_link_type_ID NUMBER;

BEGIN

BEGIN
   SELECT linktypeid
   INTO ln_link_type_ID
   FROM CRAMER.LINKTYPE lnt
   WHERE lnt.NAME = pis_link_type_name;

   EXCEPTION
      WHEN NO_DATA_FOUND THEN
         ln_link_type_ID := null;
END;

   RETURN ln_link_type_ID;

END getLinkTypeID;
像这样:

declare
ln_link_type_ID number;

    begin
      ln_link_type_ID := customisations.nr_links_validations.getLinkTypeID('test');
      dbms_output.put_line(ln_link_type_ID);
      end;

无论从其中一个模式给出函数的参数我得到了

  

NULL索引表键值

错误但仅在第一次运行时,从其他架构我没有遇到此问题。我需要提一下,模式有点不同,但具有上述视图,函数和函数调用的部分是相同的。 有没有人遇到过这种问题或者想知道为什么会出现这个错误?

堆栈跟踪显示从此处引发错误

FOR rec IN (SELECT DISTINCT NODETYPEID FROM LINKPORTVALIDATION) LOOP
      gr_nodetypes_vld(rec.NODETYPEID) := 1; --this line
   END LOOP;

和gr_nodetypes_vld在body部分声明,而不是在规范中声明:

TYPE gt_nodetypes_vld IS TABLE OF NUMBER INDEX BY BINARY_INTEGER;
gr_nodetypes_vld  gt_nodetypes_vld;

我认为这是初始化部分

BEGIN
   --First-time code. Executed once per session => Performance
   --Fill an array of all nodetypes tracked by the validation table.
   --All unique nodetypes in there will be checked against their link types.
   --All other nodetypes are not validated at all
   gr_nodetypes_vld.DELETE;
   FOR rec IN (SELECT DISTINCT NODETYPEID FROM LINKPORTVALIDATION) LOOP
      gr_nodetypes_vld(rec.NODETYPEID) := 1;
   END LOOP;

   gr_cardtypes_vld.DELETE;
   FOR rec IN (SELECT DISTINCT NODETYPEID||'.'||CARDTYPEID NODECARD_TYPE
               FROM LINKPORTVALIDATION
               WHERE CARDTYPEID IS NOT NULL
               ORDER BY 1) LOOP
      gr_cardtypes_vld(rec.NODECARD_TYPE) := 1;
   END LOOP;
END NR_LINKS_VALIDATIONS;

1 个答案:

答案 0 :(得分:2)

错误来自初始化部分,而不是您正在调用的函数。会话instantiates the package中的第一个调用,包括执行初始化部分;对于该会话中的后续调用,该包已经实例化,这解释了为什么您第一次只看到错误。

在您收到错误的架构中,您在LINKPORTVALIDATION表中有条目,其中NODETYPEID为null。当你循环它们时:

   FOR rec IN (SELECT DISTINCT NODETYPEID FROM LINKPORTVALIDATION) LOOP
      gr_nodetypes_vld(rec.NODETYPEID) := 1; --this line
   END LOOP;

...当rec. NODETYPEID为null时,你试图将gr_nodetypes_vld(null)设置为1,而这就是抛出你看到的异常的空索引。

如果你使用文字null

,它实际上并没有抱怨
DECLARE
  TYPE gt_nodetypes_vld IS TABLE OF NUMBER INDEX BY BINARY_INTEGER;
  gr_nodetypes_vld  gt_nodetypes_vld;
BEGIN
  gr_nodetypes_vld(null) := 1;
END;
/

PL/SQL procedure successfully completed.

但它使用一个null的二进制整数变量:

DECLARE
  TYPE gt_nodetypes_vld IS TABLE OF NUMBER INDEX BY BINARY_INTEGER;
  gr_nodetypes_vld  gt_nodetypes_vld;
  null_int binary_integer;
BEGIN
  gr_nodetypes_vld(null_int) := 1;
END;
/

ORA-06502: PL/SQL: numeric or value error: NULL index table key value
ORA-06512: at line 6

来自两个模式的调用看到查询该表的结果不同,因此它们的行为方式不同。