Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/oracle/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Oracle PL/SQL:如何声明会话变量?_Oracle_Plsql - Fatal编程技术网

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

Oracle PL/SQL:如何声明会话变量?,oracle,plsql,Oracle,Plsql,如何在PL/SQL中声明会话变量?该变量仅在会话期间保持不变,而不必将其存储在数据库中?您可以创建一个包级变量。这是一个简单的例子: 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 RE

如何在PL/SQL中声明会话变量?该变量仅在会话期间保持不变,而不必将其存储在数据库中?

您可以创建一个包级变量。这是一个简单的例子:

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
错误。每个数据库会话都有它自己的值。您可以尝试以下方法:

SELECT my_package.get_a FROM DUAL;

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

首先,创建一个上下文:

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_值可以更高级,这只是一个示例。 创建了上下文和包之后,就可以开始使用它们了。 使用过程调用设置上下文变量

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')

有关更多信息,请参见我喜欢使用简短但直观的语法,因此会创建一些
ctx
,这些包只提供一个函数来设置和获取一些全局“变量”
(仅对当前会话有效;在我的情况下,不需要将其作为用户创建的上下文变量实现,但可以在引擎盖下轻松地对其进行更改;例如,使用一些
foo varchar2
bar number
vars)

用法

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'
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;

包头

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'
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;
包体

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'
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\u enable
,否则,如果查询是可并行的,则会更有效


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

当我创建上下文时,它会说:ORA-28265:不允许以“sys_”开头的命名空间。我试着把它设置为变量。但是它设置变量名而不是值为什么使用
CURRENT_SCHEMA
动态构建上下文名?它需要全局唯一还是什么?我假设您需要一个过程来设置值?@jpmc26有一个setter是正常的。我认为可以将变量放入包中(而不是包体)以使其公开。