将TABLE类型作为参数传递给PLSQL过程

时间:2015-01-29 21:25:20

标签: oracle plsql

我有一个像这样的plsql块,基本上在集合中设置一堆标志来运行包中的过程:

declare

  TYPE tRunFlagRec IS RECORD(tRunFlag BOOLEAN);
  TYPE tRunFlagTab IS TABLE OF tRunFlagRec INDEX BY VARCHAR2(64);
  vValidationsTab tRunFlagTab;

begin

  vValidationsTab('some_validation_1').tRunFlag := true;
  vValidationsTab('some_validation_2').tRunFlag := true;
  vValidationsTab('some_validation_3').tRunFlag := true;
  vValidationsTab('some_validation_4').tRunFlag := true;

  owner.validation_pkg.main(pRunFlags => vValidationsTab);

end;

一个带有一些if语句的过程,它根据收到的标志调用其他过程:

  --declared in package
  TYPE tRunFlagRec IS RECORD(tRunFlag BOOLEAN);
  TYPE tRunFlagTab IS TABLE OF tRunFlagRec INDEX BY VARCHAR2(64);
  vValidationsTab tRunFlagTab;

PROCEDURE MAIN(pRunFlags in tRunFlagTab) IS

    vSome_validation_1_FLAG  BOOLEAN := pRunFlags('FLAG_1').tRunFlag;
    vSome_validation_2_FLAG  BOOLEAN := pRunFlags('FLAG_2').tRunFlag;
    vSome_validation_3_FLAG  BOOLEAN := pRunFlags('FLAG_3').tRunFlag;
    vSome_validation_4_FLAG  BOOLEAN := pRunFlags('FLAG_4').tRunFlag;

  BEGIN
    DBMS_OUTPUT.PUT_LINE('Checking for 1');
    IF vSome_validation_1_FLAG THEN
      GET_SOME_VALIDATION_1();
    ELSE
      DBMS_OUTPUT.PUT_LINE('Run Flag set to False. Skipping...');
    END IF;
    DBMS_OUTPUT.PUT_LINE('Checking for 2');
    IF vSome_validation_2_FLAG THEN
      GET_SOME_VALIDATION_2();
    ELSE
      DBMS_OUTPUT.PUT_LINE('Run Flag set to False. Skipping...');
    END IF;
    DBMS_OUTPUT.PUT_LINE('Checking for 3');
    IF vSome_validation_3_FLAG THEN
      GET_SOME_VALIDATION_3();
    ELSE
      DBMS_OUTPUT.PUT_LINE('Run Flag set to False. Skipping...');
    END IF;
    DBMS_OUTPUT.PUT_LINE('Checking for 4');
    IF vSome_validation_4_FLAG THEN
      GET_SOME_VALIDATION_4();
    ELSE
      DBMS_OUTPUT.PUT_LINE('Run Flag set to False. Skipping...');
    END IF;
  END;

我收到错误:PLS-00306:调用'MAIN'时参数的数量或类型错误。有什么想法吗?

2 个答案:

答案 0 :(得分:3)

不要在本地代码中重新声明打包类型。您在匿名PL / SQL块中声明的tRunFlagRectRunFlagTab类型与在包中声明的类似名称的类型不同,因此您无法互换使用它们。只需在匿名PL / SQL块中使用打包类型

declare
  vValidationsTab owner.validation_pkg.tRunFlagTab;
begin
  vValidationsTab('some_validation_1').tRunFlag := true;
  vValidationsTab('some_validation_2').tRunFlag := true;
  vValidationsTab('some_validation_3').tRunFlag := true;
  vValidationsTab('some_validation_4').tRunFlag := true;

  owner.validation_pkg.main(pRunFlags => vValidationsTab);
end;

答案 1 :(得分:1)

步骤1 - 创建包,以便声明对于调用者和被调用者都是一致的

CREATE OR REPLACE PACKAGE declare_here
IS
   TYPE trunflagrec IS RECORD (
      trunflag   BOOLEAN
   );

   TYPE trunflagtab IS TABLE OF trunflagrec
      INDEX BY VARCHAR2 (64);
END;

第2步 - 这是您放置逻辑的地方,我已对某些行进行了评论,但您可以在代码中取消注释,它们是直截了当的

CREATE OR REPLACE PROCEDURE main (prunflags IN declare_here.trunflagtab)
IS
   vsome_validation_1_flag   BOOLEAN := prunflags ('some_validation_1').trunflag;
   vsome_validation_2_flag   BOOLEAN := prunflags ('some_validation_2').trunflag;
   vsome_validation_3_flag   BOOLEAN := prunflags ('some_validation_3').trunflag;
   vsome_validation_4_flag   BOOLEAN := prunflags ('some_validation_4').trunflag;
BEGIN
   DBMS_OUTPUT.put_line ('Checking for 1');

   IF vsome_validation_1_flag
   THEN
      --get_some_validation_1 ();
      DBMS_OUTPUT.put_line ('get_some_validation_1');
   ELSE
      DBMS_OUTPUT.put_line ('Run Flag set to False. Skipping...');
   END IF;

   DBMS_OUTPUT.put_line ('Checking for 2');

   IF vsome_validation_2_flag
   THEN
      --get_some_validation_2 ();
      DBMS_OUTPUT.put_line ('get_some_validation_2');
   ELSE
      DBMS_OUTPUT.put_line ('Run Flag set to False. Skipping...');
   END IF;

   DBMS_OUTPUT.put_line ('Checking for 3');

   IF vsome_validation_3_flag
   THEN
      --get_some_validation_3 ();
      DBMS_OUTPUT.put_line ('get_some_validation_3');
   ELSE
      DBMS_OUTPUT.put_line ('Run Flag set to False. Skipping...');
   END IF;

   DBMS_OUTPUT.put_line ('Checking for 4');

   IF vsome_validation_4_flag
   THEN
      --get_some_validation_4 ();
      DBMS_OUTPUT.put_line ('get_some_validation_4');
   ELSE
      DBMS_OUTPUT.put_line ('Run Flag set to False. Skipping...');
   END IF;
END;

步骤3 - 调用步骤2中创建的程序

DECLARE
   vvalidationstab   declare_here.trunflagtab;
BEGIN
   vvalidationstab ('some_validation_1').trunflag := TRUE;
   vvalidationstab ('some_validation_2').trunflag := TRUE;
   vvalidationstab ('some_validation_3').trunflag := TRUE;
   vvalidationstab ('some_validation_4').trunflag := TRUE;
   main (prunflags => vvalidationstab);
END;