从另一个程序调用一个程序有些错误

时间:2012-07-03 09:46:07

标签: oracle stored-procedures plsql

由于要求,我必须从另一个存储过程中调用一个存储过程。

问题似乎在我正在使用的输出参数out_result_size附近。当我测试main_func时它工作正常,但是当我测试synonym_proc时,它说

  

synonym_proc无效

我最终必须使用JPA的synonym_proc

从Java调用@NamedNativeQuery
CREATE OR REPLACE PROCEDURE synonym_proc (
    result_cursor      OUT SYS_REFCURSOR,
    in_cp_id           IN NUMBER,
    in_cp_name         IN VARCHAR2 := NULL,
    in_country_name    IN VARCHAR2 := NULL,
    in_industry_name   IN VARCHAR2 := NULL,
    in_max_result_size IN NUMBER
) AS
    out_result_size NUMBER;
BEGIN
   result_cursor := someSchema.somePackage.main_func(in_cp_id,
              in_cp_name,
              in_country_name,
              in_industry_name,
              in_max_result_size,
              out_result_size);
END;

更新:抱歉没有提及我之前没有注意到的问题的变化。 main_func是一个函数(不是过程),它返回一个游标并驻留在某个模式中的某个包中。当我编译时,我得到以下编译错误:

  

错误:PLS-00201:标识符'SOMESCHEMA.SOMEPACKAGE'必须是   声明..语句被忽略。

更新2

SomeSchema定义

CREATE OR REPLACE PACKAGE someSchema."SomePackage"
is
...
function mainFunc
(
    in_cp_id                in gem.tcp_real_profile_main_approved.cp%type
    , in_cp_name            in gem.tcp_real_profile_main_approved.name%type
    , in_country_name       in gem.tcp_real_profile_main_approved.country_name%type
    , in_industry_name      in gem.tcp_real_profile_main_approved.industry_name%type
    , in_max_result_size    in number
    , out_result_size       out number
)
return search_result_type_cursor;

ADDED

type search_result_type_cursor
 is ref cursor
 return search_type;

是的,数据类型是正确的,因为我描述了函数(main_func)并交叉验证了数据类型。

3 个答案:

答案 0 :(得分:3)

根据评论,特别是您可以在其他模式中描述和测试过程,看起来这可能是一个权限问题。如果您通过角色授予了对其他模式中对象的权限,那么您将能够直接执行包过程,但角色aren't recognised inside named blocks。如果这是问题,那么您必须获得直接授予正在创建存储过程的用户的someSchema.somePackage的执行权限。

为了演示这个问题,我可以在我的SCOTT模式中创建一个包,并将执行权授予一个角色,并将该角色授予用户 - 这两个都是我为测试创建的。作为SYS

create role scott_tmp_role;
grant connect to someuser identified by <password>;
grant scott_tmp_role to someuser;
grant create procedure to someuser;

作为SCOTT

create package p42 as
    procedure proc;
end p42;
/

Package created.

create package body p42 as
    procedure proc is
    begin
        null;
    end proc;
end p42;
/

Package body created.

grant execute on p42 to scott_tmp_role;

Grant succeeded.

作为我的新SOMEUSER,请验证我的角色:

select * from session_roles;

ROLE
------------------------------
CONNECT
SCOTT_TMP_ROLE

我可以在匿名块中执行该过程:

begin
    scott.p42.proc;
end;
/

PL/SQL procedure successfully completed.

...但不在命名区块中:

create or replace procedure sp42 as
begin
    scott.p42.proc;
end;
/

Warning: Procedure created with compilation errors.

show errors

Errors for PROCEDURE SP42:

LINE/COL ERROR
-------- -----------------------------------------------------------------
3/2      PL/SQL: Statement ignored
3/2      PLS-00201: identifier 'SCOTT.P42' must be declared

如果SCOTT直接向我的新用户授予权限:

grant execute on p42 to someuser;

...然后命名块现在可以工作:

create or replace procedure sp42 as
begin
    scott.p42.proc;
end;
/

Procedure created.

如果你想知道你可能从哪里获得执行权限,你可以运行这样的查询,尽管可能有一个角色层次结构可供选择:

select grantee, privilege from all_tab_privs
where table_schema = 'SomeSchema'
and table_name = 'SomePackage';

答案 1 :(得分:1)

您无法指定过程或函数的参数大小。尝试删除尺寸,并按照Vincent的建议移动commit

CREATE OR REPLACE PROCEDURE synonym_proc(result_cursor      OUT SYS_REFCURSOR,
                                         in_cp_id           IN NUMBER,
                                         in_cp_name         IN VARCHAR2,
                                         in_country_name    IN VARCHAR2,
                                         in_industry_name   IN VARCHAR2,
                                         in_max_result_size IN NUMBER) AS
  out_result_size NUMBER;
BEGIN
  main_proc(result_cursor,
            in_cp_id,
            in_cp_name,
            in_country_name,
            in_industry_name,
            in_max_result_size,
            out_result_size);
  COMMIT;
END;

您应该收到类似PLS-00103: Encountered the symbol "(" when expecting one of the following: ...

的错误消息

答案 2 :(得分:0)

Oracle SP语法

CREATE OR REPLACE PROCEDURE procedure_name(--parameter list) AS
--Local Variables
BEGIN
--Body
END;

现在你犯了一个错误,而不是在END之前放置COMMIT,而是在END之后放置它。它应该是这样的

COMMIT;
END;