首页 > 解决方案 > Oracle 存储过程从本地调用 ok,但从 dblink 调用错误

问题描述

我有一个 Oracle 存储过程,它编译时没有错误,并以我预期的结果运行。这是我在本地数据库中的称呼:

variable v_emp_cur refcursor;
  exec my_schema.SP_READ_MEMBER('12345678', '', :v_emp_cur);
print v_emp_cur;

它打印的结果很好。但是,当我使用 dblink 从另一个数据库调用此 SP 时,如下所示:

variable v_emp_cur refcursor;
  exec my_schema.SP_READ_MEMBER@my_dblink('12345678', '', :v_emp_cur);
print v_emp_cur;

它返回此错误消息:

BEGIN my_schema.sp_read_member@my_dblink('12345678', '', :v_emp_cur); END;
Error at line 2
ORA-00604: error occurred at recursive SQL level 1
ORA-00900: invalid SQL statement

由于我的存储过程编译时没有错误,并从本地调用返回数据,我预计其中没有错误。但我不是 100% 确定,这是我的存储过程:

CREATE OR REPLACE procedure my_schema.SP_READ_MEMBER(keywordP in varchar2, birthdayP in varchar2, resultP out sys_refcursor)
is
v_prg_name varchar2(20) := 'SP_READ_MEMBER';
sys_sql    varchar2(1000);


begin
  Insertlog(SYSDATE, v_prg_name, '1.0 Start');
  sys_sql :=  sys_sql || 'select a.no, a.name, a.id_no, to_char(a.birthday, ''yyyy/MM/dd'') as birthday, ''REAL member'' as mtype, email, mobile from members  a where 1=1 ';
  if keywordP is not null then
    sys_sql :=  sys_sql || ' and (a.no=''' || keywordP || ''' or a.name=''' || keywordP || ''' or a.id_no=''' || keywordP || ''') ';
  end if;
  if birthdayP is not null then
    sys_sql :=  sys_sql || ' and a.birthday=to_date(''' || birthdayP || ''', ''yyyy/MM/dd'') ';
  end if;

  open resultP for sys_sql;
  Insertlog(SYSDATE, v_prg_name, '2.0 Finished w/o error');

  exception
  when others then
  declare
    error_time VARCHAR2(30) := RTRIM(TO_CHAR(SYSDATE, 'YYYY/MM/DD, HH24:MI:SS'));
    error_code NUMBER := SQLCODE;
    error_msg  VARCHAR2(300) := SQLERRM;
  begin
    rollback;
    DBMS_OUTPUT.PUT_LINE(error_time || ',' || TO_CHAR(error_code) || ',' || error_msg);
    Insertlog(SYSDATE, v_prg_name,  error_msg || ', 3.0 ERROR, sql:' || sys_sql);
  end;
end SP_READ_REP;
/

我该如何解决这个问题?

欢迎任何建议~

标签: oraclestored-proceduresdblink

解决方案


你遇到了限制。光标变量声明说:

在服务器到服务器远程过程调用 (RPC) 中使用游标变量会导致错误。但是,如果远程数据库是通过过程网关访问的非 Oracle 数据库,则可以在服务器到服务器 RPC 中使用游标变量。

解决方法可能是将过程移动到本地数据库并通过数据库链接获取数据。


推荐阅读