0

我有一个包裹,里面我声明 g_suppress_all_xlog BOOLEAN := fnc_Suppress() DEFAULT NULL;

FUNCTION fnc_suppress
   RETURN BOOLEAN
IS
   v_ret       BOOLEAN := FALSE;                                  -- assume NO
   v_suppress  VARCHAR2 (3);
BEGIN
   SELECT VALUE
     INTO v_suppress
     FROM server_config
    WHERE name = 'Suppress_All_Xlog';

   IF (v_suppress = 'YES')
   THEN
      v_ret := TRUE;
   END IF;

   RETURN v_ret;
EXCEPTION
   WHEN OTHERS
   THEN
      prc_exception ();
END fnc_suppress;

我收到错误,如何默认为 null 并替换为函数值。

4

2 回答 2

1

所有你需要的是

g_suppress_all_xlog BOOLEAN := fnc_Suppress();

不要将其设置为NULL显式;如果你什么都不说,NULL无论如何都会这样。

SQL> create or replace package pkg_Test as
  2    procedure p_test;
  3    g_suppress_all_xlog boolean;
  4  end;
  5  /

Package created.

SQL> create or replace package body pkg_Test as
  2    procedure p_test is
  3    begin
  4      dbms_output.put_line('Variable''s value = ' ||
  5        case when g_suppress_all_xlog then 'true'
  6             when not g_suppress_all_xlog then 'false'
  7             else 'null'
  8        end);
  9    end;
 10  end;
 11  /

Package body created.

SQL> exec pkg_test.p_test;
Variable's value = null

PL/SQL procedure successfully completed.

SQL>

fnc_suppress不能是您声明此函数的同一包的一部分,因此 - 它必须是独立函数或另一个包的一部分。

SQL> create or replace package pkg_Test as
  2    function fnc_suppress_in_pkg return boolean;
  3    procedure p_test;
  4    g_suppress_all_xlog boolean := fnc_suppress_in_pkg();
  5  end;
  6  /

Warning: Package created with compilation errors.

SQL> show err
Errors for PACKAGE PKG_TEST:

LINE/COL ERROR
-------- -----------------------------------------------------------------
4/23     PL/SQL: Declaration ignored
4/23     PLS-00492: variable or constant initialization may not refer to
         functions declared in the same package

SQL>

最后:

SQL> create or replace function fnc_suppress return boolean
  2    is
  3  begin
  4    return true;
  5  end;
  6  /

Function created.

SQL> create or replace package pkg_Test as
  2    procedure p_test;
  3    g_suppress_all_xlog boolean := fnc_suppress;
  4  end;
  5  /

Package created.

SQL> create or replace package body pkg_Test as
  2    procedure p_test is
  3    begin
  4      dbms_output.put_line(case when g_suppress_all_xlog then 'true' else 'false' end);
  5    end;
  6  end;
  7  /

Package body created.

SQL> exec pkg_test.p_test;
true

PL/SQL procedure successfully completed.

SQL>
于 2020-04-10T07:56:40.080 回答
0

fnc_suppress_in_pkg() 可以在包 pkg_test 中。它只是不能用于规范中的分配,它还不存在。似乎 OP 想要在执行任何函数/过程之前初始化变量 g_suppress_all_xlog。这可以通过包体的初始化部分来完成。(注意:我的游乐场有一个可用的表 config_settings 表,所以我用它代替了 server_config)

create or replace package pkg_test as
    g_suppress_all_xlog boolean;

    procedure prc_exception;
    function fnc_suppress return boolean;
    -- Other procedure/functions declared here. 
end  pkg_test;      

create or replace package body pkg_test as
   procedure prc_exception is
   begin 
       null;
   end prc_exception;

   function fnc_suppress 
      return boolean
   is
      v_suppress  varchar2 (3);
   begin
      select setting
        into v_suppress
        from config_settings
       where name = 'Suppress_All_Xlog';

      return (v_suppress = 'YES');
   exception
      when others
      then
         prc_exception ();
   end fnc_suppress;

   -- Other procedure/functions defined here. 

begin   -- this the package initialization. It executes 1 time when the package is first loaded.
  g_suppress_all_xlog := fnc_suppress;
end pkg_test; 


--  Test with direct reference to g_suppress_all_xlog 
    insert into config_settings(name,setting ) values('Suppress_All_Xlog', 'YES');
    declare
       setting varchar2(30); 
    begin
       if pkg_test.g_suppress_all_xlog 
          then dbms_output.put_line('Xlog being suppressed');
          else dbms_output.put_line('Xlog being written');
       end if;
    end; 

恕我直言>>但是,声明变量 g_suppress_all_xlog 是规范是不好的做法。这使得它可以被同一会话中的任何进程读取(不是那么糟糕)和写入(糟糕)。更好的过程是在正文中声明它,这样就不能直接访问它。我理解它的目的是每次都必须选择,所以添加另一个函数来简单地返回它的值。

于 2020-04-10T18:05:09.177 回答