从模式 A 中的存储过程调用模式 B 中的存储过程停止工作

Posted

技术标签:

【中文标题】从模式 A 中的存储过程调用模式 B 中的存储过程停止工作【英文标题】:Calling stored procedures in schema B from a stored procedure in schema A stopped working 【发布时间】:2020-06-09 14:02:46 【问题描述】:

解决一个突然停止工作的应用程序的问题。异常抱怨存储过程不可用。

我的结论是,由于某种原因,模式 NGM2 不再能够使用模式 NGM209 中的存储过程。

我想出了一个简单的例子来重现和说明问题。

在模式 NGM208 和 NGM209 中创建测试函数:

SQL> connect ngm208@DB
SQL> create or replace function test return varchar2 as begin return 'TEST208'; end;
SQL> grant execute on test to NGM2;

SQL> connect ngm209@DB
SQL> create or replace function test return varchar2 as begin return 'TEST209'; end;
SQL> grant execute on test to NGM2;

当连接到架构 NGM2 时,这两个函数在 SQL 中都可用。

SQL> select ngm208.test from dual;
TEST208

SQL> select ngm209.test from dual;
TEST209

现在让我们在模式 NGM2 中为这些函数创建存储过程。

SQL> create or replace function test208 return varchar2 as
  2     l_result varchar2(32767);
  3  begin
  4     select NGM208.test into l_result from dual;
  5     return l_result;
  6  end;
  7  /

Function created.

SQL> create or replace function test209 return varchar2 as
  2     l_result varchar2(32767);
  3  begin
  4     select NGM209.test into l_result from dual;
  5     return l_result;
  6  end;
  7  /

Warning: Function created with compilation errors.

SQL> show error
Errors for FUNCTION TEST209:

LINE/COL ERROR
-------- -----------------------------------------------------------------
4/18     PLS-00302: component 'TEST' must be declared

所以这就是问题所在。 NGM2 似乎无法从存储过程中找到模式 ngm209 中的存储过程。在 SQL 中,它按预期工作。

对此是否有合乎逻辑的解释,如果有,是什么原因,或者该数据库确实出了什么问题?

【问题讨论】:

无法在 19.5 中重现。您的 4 位 Oracle 版本是多少?是否启用了任何安全功能?似乎在存储过程中没有启用某种特权但是您已授予直接特权(我的意思是没有角色):所以这不是解释... 【参考方案1】:

您可能在架构NGM2 中有一个名为NGM209 的对象:

SQL> show user;
USER is "NGM2"
SQL> create sequence ngm209;

Sequence created.

SQL> @c
SQL> create or replace function test209 return varchar2 as
  2  l_result varchar2(32767);
  3  begin
  4   select NGM209.test into l_result from dual;
  5   return l_result;
  6  end;
  7  /

Warning: Function created with compilation errors.

SQL> show errors
Errors for FUNCTION TEST209:

LINE/COL ERROR
-------- -----------------------------------------------------------------
4/16     PLS-00302: component 'TEST' must be declared
SQL> 
SQL> drop sequence ngm209;

Sequence dropped.

SQL> @c
SQL> set echo on
SQL> create or replace function test209 return varchar2 as
  2  l_result varchar2(32767);
  3  begin
  4   select NGM209.test into l_result from dual;
  5   return l_result;
  6  end;
  7  /

Function created.

SQL> show errors
No errors.
SQL> 

【讨论】:

就是这样!有人添加了一个表 ngm209。以为我在看一个有这个问题的鬼魂。非常感谢。【参考方案2】:

对;有时事情会突然发生。如果您尝试通过创建 同义词 并在函数中处理它来欺骗 Oracle,会有所帮助吗?

create synonym syn_test_ngm209 for ngm209.test;

create or replace function test209 return varchar2 as
   l_result varchar2(32767);
begin
   l_result := syn_test_ngm209;   --> no need to SELECT FROM DUAL!
   return l_result;
end;
/

【讨论】:

以上是关于从模式 A 中的存储过程调用模式 B 中的存储过程停止工作的主要内容,如果未能解决你的问题,请参考以下文章

sqlserver 存储过程调用报错

为我的模式中的所有表自动生成 DML 存储过程的工具-MySQL

从SQL代理作业调用时,工作存储过程失败

MySQL-进阶18 存储过程- 创建语句-参数模式(in/out/inout-对应三个例子) -调用语法-delimiter 结束标记'$'

MySQL中的存储过程(详细篇)

使用游标在python中调用存储过程