мы можем использовать default в переменной с вызовом функции в pl sql? - PullRequest
0 голосов
/ 10 апреля 2020

У меня есть пакет, внутри я объявляю 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 и заменить его значением функции.

Ответы [ 2 ]

1 голос
/ 10 апреля 2020

Все, что вам нужно, это

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>
0 голосов
/ 10 апреля 2020

fnc_suppress_in_pkg () может быть в пакете pkg_test. Он просто не может быть использован для назначения в spe c, он еще не существует. Похоже, что 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; 

IMHO >> Однако объявление переменной g_suppress_all_xlog - это spe c - плохая практика. Это делает его доступным для любого процесса в одном сеансе как для чтения (не так уж плохо), так и для записи (плохо). Лучше было бы объявить его в теле, чтобы к нему нельзя было получить прямой доступ. Я понимаю, что цель состоит в том, чтобы выбирать каждый раз, поэтому добавьте еще одну функцию, которая просто возвращает ее значение.

...