Oracle使用新序列

时间:2018-07-10 11:19:52

标签: oracle oracle11g

不确定是否是询问此类问题的正确地点,否则请接受我的歉意。

我刚刚在用户模式中创建了一个新序列,可以使用: -> Select Seq_Testing.Nextval Into Variable From Dual;

到目前为止,没有问题。但是,当我添加用户模式名称时,Oracle给了我一个错误。 -> Select User.Seq_Testing.Nextval Into Variable From Dual;

Oracle给我错误消息

  

PLS-00225:子程序或游标引用超出范围。

此外,在添加了赠款和公共同义词之后,我得到了相同的错误消息。

Grant Select On User.Seq_Testing To User;
Create Public Synonym Seq_Testing For User.Seq_Testing; 

作为记录,这是一个Oracle 11g数据库。

任何想法都欢迎。

温馨提示

1 个答案:

答案 0 :(得分:4)

您并没有真正添加用户/方案名称。 USER is a function

  

USER返回数据类型为VARCHAR2的会话用户(登录的用户)的名称。

因此您可以将其称为函数:

select user from dual;

USER                          
------------------------------
MY_SCHEMA

但是您不能使用函数在语句中提供the schema qualifier。如您所见,如果您这样做

Select User.Seq_Testing.Nextval Into Variable From Dual;

那么你就得到

  

PLS-00225:子程序或游标'USER'引用超出范围
  PL / SQL:ORA-02289:序列不存在
  PL / SQL:忽略了SQL语句

您可以使用动态SQL指定当前用户的架构:

execute immediate 'Select ' || User || '.Seq_Testing.Nextval From Dual' Into Variable ;

,然后它将在运行时在执行用户的模式中查找该名称的序列;如果不存在则会出错。如果您始终要使用同一个人拥有的相同序列,那么执行此操作的人(通常会更正常)将需要对模式名称进行硬编码:

Select my_schema.Seq_Testing.Nextval Into Variable From Dual;

或更简单地说:

Variable := my_schema.Seq_Testing.Nextval;

或者只是:

Variable := Seq_Testing.Nextval;

如您所见,您不需要在自己的模式中使用模式名称为对象添加前缀,这样做似乎没有太大好处。如果这是在存储过程或触发器中,则它将仍然在过程/触发器所有者的模式中寻找序列,而不是在调用用户的模式中寻找序列。而且,如果您确实确实希望为每个调用者提供一个单独的序列,则必须动态完成,否则他们也必须具有自己的过程。那将……虽然不寻常。

您的特权和公共同义词声明存在相同的问题,以为会出现不同的错误。您最多只需要一个公共同义词,就可以指定实际的架构名称,或者如果它是当前架构,则可以省略。

对于特权,您似乎试图向自己授予对象上的东西,这也没有意义-通常,您会Grant Select On Seq_Testing To some_other_user,假设您希望它们能够直接增加它,不只是通过存储过程/触发器,它们不需要其他特权(除了在过程中执行)。