0

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

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

synonym_proc 无效

最终,我必须synonym_proc使用 JPA 从 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;

添加

type search_result_type_cursor
 is ref cursor
 return search_type;

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

4

3 回答 3

4

根据评论,特别是您可以在其他模式中描述和测试过程,看起来这可能是权限问题。如果您对其他模式中的对象的权限是通过角色授予的,那么您将能够直接执行包过程,但在命名块中无法识别角色。如果这是问题所在,那么您将必须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';
于 2012-07-04T08:06:36.077 回答
1

您不能指定过程或函数的参数大小。尝试删除尺寸,并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: ...

于 2012-07-03T10:48:54.130 回答
0

Oracle SP 的语法是

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

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

COMMIT;
END;
于 2012-07-03T10:08:20.933 回答