PL/SQL:如何声明会话变量?

use*_*871 17 oracle plsql

如何在PL/SQL中声明一个会话变量 - 一个只在会话期间持续存在的会话变量,而不必将其存储在数据库本身中?

use*_*850 14

您可以使用"用户创建的上下文"来存储会话中多个单元之间共享的数据.

首先,创建一个上下文:

CREATE CONTEXT SYS_CONTEXT ('userenv', 'current_schema')|| '_ctx' USING PKG_COMMON
Run Code Online (Sandbox Code Playgroud)

其次,创建一个管理您的上下文的包:

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;
Run Code Online (Sandbox Code Playgroud)

prc_set_context_value可以更高级,这只是一个例子.通过创建上下文和包,您可以开始使用它们.使用过程调用设置上下文变量

begin
  PKG_COMMON.prc_set_context_value('MyVariable', 9000)
end;
Run Code Online (Sandbox Code Playgroud)

并在任何地方使用它 - 任何程序,包,功能或事件视图.

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

有关更多信息,请访问http://www.psoug.org/reference/sys_context.html

  • 当我创建上下文时,它说:ORA-28265:不允许以'sys_'开头的NameSpace.我试着将它设置为变量.但它设置变量名而不是值 (2认同)

WW.*_*WW. 13

您创建一个包级别变量.这是一个最小的例子:

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;
/
Run Code Online (Sandbox Code Playgroud)

如果您这样做,您应该阅读(并正确处理)ORA-04068错误.每个数据库会话都有自己的a值.你可以尝试这个:

SELECT my_package.get_a FROM DUAL;
Run Code Online (Sandbox Code Playgroud)