【问题标题】:Passing TABLE type as parameter to PLSQL Procedure将 TABLE 类型作为参数传递给 PLSQL 过程
【发布时间】:2015-03-29 06:41:56
【问题描述】:

我有一个这样的 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”时参数的数量或类型错误。有什么想法吗?

【问题讨论】:

标签: oracle plsql


【解决方案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;

【讨论】:

    【解决方案2】:

    不要在本地代码中重新声明打包类型。您在匿名 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;
    

    【讨论】:

    • 太棒了。 PLSQL 相对较新。不过,这很有意义。谢谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-07-04
    • 1970-01-01
    • 2011-08-15
    • 2015-12-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多