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

时间:2008-11-19 09:24:10

标签: oracle plsql

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

3 个答案:

答案 0 :(得分:14)

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

首先,创建一个上下文:

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

答案 1 :(得分: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;
/

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

SELECT my_package.get_a FROM DUAL;

答案 2 :(得分:0)

我喜欢使用但直观的语法,因此可以创建例如一些 import queryString from 'query-string' import { Redirect } from 'react-router-dom' export default function Items() { const queryValues = queryString.parse(this.props.location.search) const itemId = queryValues['item_id'] if (isNaN(itemId)) { return <Redirect to="/404.html" /> } return ... } 程序包,该程序包仅提供一个用于设置和获取某些全局“变量”的功能
(仅对当前会话有效;在我的情况下,无需将其实现为用户创建的上下文变量,但可以在后台轻松更改为该变量;例如,使用一些ctxfoo varchar2 vars)< / p>

用法

bar number

select ctx.foo from dual                                                 -- => null (init)
select ctx.foo('a') from dual                                            -- => 'a'
select ctx.foo('b') from dual ; select ctx.foo from dual                 -- => 'b', 'b'

程序包头

-- (optimizer should cause the subquerys unselected columns not to be executed:)
select 'ups' from (select ctx.foo('a') from dual) ; select ctx.foo from dual   -- => null

select ctx.bar(1.5) from dual ; select ctx.bar from dual                 -- => 1.5,  1.5
-- ...

程序包主体

create or replace package  ctx  as

  -- select ctx.foo from dual                                            -- => null (init)
  -- select ctx.foo('a') from dual                                       -- => 'a'
  -- select ctx.foo('b') from dual ; select ctx.foo from dual            -- => 'b', 'b'
  -- (optimizer should cause the subquerys unselected columns not to be executed:)
  -- select 'ups' from (select ctx.foo('a') from dual) ; select ctx.foo from dual
    -- => null
  -- parallel_enable for queries since it should not change inside of them
  function foo(  set varchar2 := null  ) return varchar2  parallel_enable;

  -- (samples like in foo above as executable test comments like in foo above skipped for 
  -- brevity)
  function bar(  set number := null  ) return  number  parallel_enable;

end;

如果您知道变量(create or replace package body ctx as foo_ varchar2(30); -- e.g. 'blabla' bar_ number; -- internal helper function for varchars function set_if_not_null( ref in out varchar2, val varchar2 ) return varchar2 as begin if val is not null then ref := val; end if; return ref ; end; -- internal helper function for numbers function set_if_not_null( ref in out number, val number ) return number as begin if val is not null then ref := val; end if; return ref ; end; -- (same test comments like in foo above skipped for brevity) function foo( set varchar2 := null ) return varchar2 parallel_enable as begin return set_if_not_null( foo_, set ) ; end; -- (same test comments like in foo above skipped for brevity) function bar( set number := null ) return number parallel_enable as begin return set_if_not_null( bar_, set ) ; end; end; )在单个查询中可能会发生变化,请删除foo ,否则,如果查询是可并行化的,则该性能会更高。

>

根据需要,当然可以添加一些parallel_enable以将其设置为null等。