不确定是否是询问此类问题的正确地点,否则请接受我的歉意。
我刚刚在用户模式中创建了一个新序列,可以使用:
-> 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数据库。
任何想法都欢迎。
温馨提示
答案 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
,假设您希望它们能够直接增加它,不只是通过存储过程/触发器,它们不需要其他特权(除了在过程中执行)。