PL/SQL: Как объявить переменные сеанса?

Как объявить переменную сеанса в PL/SQL, которая будет сохраняться только на время сеанса, без необходимости хранить ее в самой базе данных?

Ответы

Ответ 1

Вы создаете переменную уровня пакета. Это минимальный пример:

CREATE OR REPLACE PACKAGE my_package
AS
    FUNCTION get_a RETURN NUMBER;
END my_package;
/

CREATE OR REPLACE PACKAGE BODY my_package
AS
    a  NUMBER(20);

    FUNCTION get_a
    RETURN NUMBER
    IS
    BEGIN
      RETURN a;
    END get_a;
END my_package;
/

Если вы это сделаете, вы должны прочитать (и правильно обработать) ошибки ORA-04068. Каждый сеанс базы данных будет иметь собственное значение для a. Вы можете попробовать:

SELECT my_package.get_a FROM DUAL;

Ответ 2

Вы можете использовать "созданный пользователем контекст" для хранения данных, разделяемых несколькими блоками в сеансе.

Сначала создайте контекст:

CREATE CONTEXT SYS_CONTEXT ('userenv', 'current_schema')|| '_ctx' USING PKG_COMMON

Во-вторых, создайте пакет, который будет управлять вашим контекстом:

CREATE OR REPLACE PACKAGE PKG_COMMON
IS
   common_ctx_name   CONSTANT VARCHAR2 (60)
                 := SYS_CONTEXT ('userenv', 'current_schema')
                    || '_ctx';

   FUNCTION fcn_get_context_name RETURN VARCHAR2;
   PROCEDURE prc_set_context_value (var_name VARCHAR2, var_value NUMBER);
END;

CREATE OR REPLACE PACKAGE BODY PKG_COMMON
IS
   FUNCTION fcn_get_context_name
      RETURN VARCHAR2
   IS
   BEGIN
      RETURN common_ctx_name;
   END;

   PROCEDURE prc_set_context_value (var_name VARCHAR2, var_value NUMBER)
   IS
   BEGIN
      DBMS_SESSION.set_context (common_ctx_name, var_name, var_value);
   END;
END;

Prc_set_context_value может быть более продвинутым, это просто пример. С контекстом и созданным пакетом вы можете начать их использовать. Задайте переменную контекста, используя вызов процедуры

begin
  PKG_COMMON.prc_set_context_value('MyVariable', 9000)
end;

и использовать его в любом месте - любую процедуру, пакет, функцию или событие.

CREATE VIEW V_TEST AS
  SELECT ID, LOGIN, NAME 
    FROM USERS 
   WHERE ROLE_ID =  SYS_CONTEXT(PKG_COMMON.FCN_GET_CONTEXT_NAME, 'MyVariable')

Для получения дополнительной информации см. http://www.psoug.org/reference/sys_context.html