从VB6执行包中包含的存储过程时ORA-00604 / ORA-00942错误的原因

时间:2014-08-26 13:58:20

标签: sql oracle stored-procedures vb6

我正在处理从VB6调用包中包含的存储过程的问题。

首先,作为对我的实现的测试,我创建了一个独立的存储过程。在确认正确的用户/角色被授予对该过程的执行权限之后,我能够成功运行该过程并显示返回的引用游标的内容。

然后我将此过程移动到oracle包中。

在授予(我相信的)对所需用户/角色的适当权限后,我能够从SQL Developer直接从SQLPlus执行此过程。但是,当我使用与执行独立过程相同的方法从VB6执行过程时,我收到以下错误:

Run-time error '-2147217900(80040e14)':

ORA-00604: error occurred at recursive SQL level 1
ORA-00942: table or view does not exist  

我很困惑这个错误意味着什么,因为我能够从SQL Developer和SQLPlus执行该过程。

错误的原因是什么,我在调试此错误时是否缺少任何步骤?

这里的参考是我的包头和我的包体的代码:

CREATE OR REPLACE PACKAGE random_package AUTHID CURRENT_USER AS

    --------------------------------------------------------
    -- procedure headers
    --------------------------------------------------------
    PROCEDURE random_procedure( 
        variable1 IN VARCHAR,
        variable2 IN VARCHAR,
        variable3 IN VARCHAR,
        variable4 IN VARCHAR,
        variable5 IN VARCHAR,
        variable6 IN VARCHAR,
        output_reference_cursor OUT SYS_REFCURSOR
    );

END random_package;

CREATE OR REPLACE PACKAGE BODY random_package AS

    --------------------------------------------------------
    -- constants
    --------------------------------------------------------

    --------------------------------------------------------
    -- procedure headers
    --------------------------------------------------------
    PROCEDURE random_procedure( 
        variable1 IN VARCHAR,
        variable2 IN VARCHAR,
        variable3 IN VARCHAR,
        variable4 IN VARCHAR,
        variable5 IN VARCHAR,
        variable6 IN VARCHAR,
        output_reference_cursor OUT SYS_REFCURSOR
    ) IS
    BEGIN
        OPEN output_reference_cursor FOR
            SELECT 
                i.prod_item_id, 
                i.prod_item_partnr, 
                i.prod_item_fname, 
                rh.random_quantity, 
                round(variable1 / rh.random_quantity * base_quantity, 0) as isuQty, 
                i.ITEM_UNIT_ID, 
                i.PROD_ITEM_CTRL
            FROM 
                vm_recipe_hdr rh, 
                vm_recipe r, 
                vm_prod_item i, 
                vm_prod_type t, 
                vmm_prodtype_scrn pts
            WHERE 
                rh.PROD_ITEM_ID = variable2
                AND rh.PROD_ITEM_ID = r.PROD_ITEM_ID
                AND i.prod_item_id = r.PROD_ITEM_ID_SUB 
                AND t.PROD_TYPE_ID = i.PROD_TYPE_ID 
                AND pts.PROD_TYPE_SCRN = t.PROD_TYPE_SCRN 
                AND pts.PRODTYPE_SCRN_SYS = variable3
                AND pts.PROD_TYPE_SCRN not in (variable4, variable5) 
                AND i.PROD_ITEM_CTRL = variable6
            ;

        EXCEPTION
            WHEN OTHERS THEN
                ROLLBACK;
    END random_procedure;

END random_package;

1 个答案:

答案 0 :(得分:1)

问题是AUTHID CURRENT_USER表示将使用当前用户凭证(在包中执行过程/函数的用户)执行包。但是,似乎包的创建者(以及内部使用的对象的所有者)与执行过程的用户不同。因此,引擎在当前用户的模式中搜索诸如vm_recipe_hdr, vm_recipe, etc的表,而不是在创建者的模式中。

我可以考虑解决问题的三种方法。

  1. 表的公共同义词。不是一个优雅的解决方案,隐藏了性能缺陷 - (例如,计划赢得了2个不同用户的共享(额外的硬解析))。
  2. 删除AUTHID CURRENT_USER - 默认情况下,Oracle使用创建者凭据执行子程序;因此,对象名称将在创建者模式中解析)
  3. 明确限定每个对象(例如,schema_name.vm_recipe_hdr