【问题标题】:'ORA-00942: table or view does not exist' only when running within a Stored procedure'ORA-00942: 表或视图不存在' 仅在存储过程中运行时
【发布时间】:2015-06-15 16:39:59
【问题描述】:

这对于 PL-SQL 人员来说应该很容易。在将此问题标记为重复问题之前,请确保虽然错误消息可能很常见,但潜在问题与前一个问题相同。如果是这样,请提供指向已解决的确切逻辑重复问题的链接。我

当我登录到我的架构时,我执行以下 PL-SQL 代码:

DECLARE
  v_rpt_per_key NUMBER := 0;
BEGIN

  SELECT MAX(rpt_per_key)
  INTO v_rpt_per_key
  FROM rxfinods_sta.hd_invc_ln_item_dtl_stat;

  dbms_output.PUT_LINE('v_RPT_PER_KEY=' || v_rpt_per_key);

END;
/

查询成功执行,RPT_PER_KEY 的最大值被写入 Toad 的输出窗口。

但是,当我在一个过程中执行基本相同的代码时。

CREATE OR REPLACE PROCEDURE hd_purge_test
IS
  v_rpt_per_key NUMBER := 0;
  BEGIN

    SELECT MAX(stat.rpt_per_key)
    INTO v_rpt_per_key
    FROM rxfinods_sta.hd_invc_ln_item_dtl_stat stat;
    --HD_INVC_LN_ITEM_DTL_STAT        

    dbms_output.PUT_LINE('v_RPT_PER_KEY=' || v_rpt_per_key);

    EXCEPTION
    WHEN NO_DATA_FOUND THEN
      NULL;
    WHEN OTHERS THEN
    -- Consider logging the error and then re-raise
      RAISE;
  END hd_purge_test;

我收到表不存在的错误。

[Warning] ORA-24344: success with compilation error
14/21   PL/SQL: ORA-00942: table or view does not exist
9/4     PL/SQL: SQL Statement ignored
 (1: 0): Warning: compiled but with compilation errors

由于我能够在使用相同凭据时查询表,这证明我的 ID 有权从表中进行选择。我不应该有权从我在相同登录模式下创建的存储过程中查询表吗?是否需要执行一些额外的赠款?

注意:如果我从登录模式中的任何表中进行选择,则该过程编译成功。

【问题讨论】:

标签: oracle stored-procedures plsql ora-00942


【解决方案1】:

听起来像是通过角色授予选择权限的问题,而不是直接授予架构。见ORA-00942: table or view does not exist (works when a separate sql, but does not work inside a oracle function)

【讨论】:

  • 谢谢。为了澄清。根据引用的答案:“默认情况下,存储过程和 SQL 方法以其所有者的权限执行,而不是当前用户的权限。”当它说“他们的所有者的特权”时,所有者是什么?存储过程?我是在我的架构下创建的 proc 的所有者。另外,权利是授予我所属的角色还是直接授予我,这有什么关系呢?
  • 因为它很重要。通过角色授予 pl/sql 是不够的,您需要直接授予 martincarstenbach.wordpress.com/2010/05/27/…
【解决方案2】:

检查您的用户是否拥有访问表的直接授权,而不是“授权选择到 xxx_role”

【讨论】:

    【解决方案3】:

    您可以执行以下命令,然后再次编译您的程序吗:

    --GRANT ALL ON <YOUR TABLE NAME> TO <YOUR USER NAME>;
    
    GRANT ALL ON RXFINODS_STA.HD_INVC_LN_ITEM_DTL_STAT TO chadD;
    

    这将授予对象的完全权限。

    【讨论】:

      【解决方案4】:

      或者你可以这样做:

      CREATE OR REPLACE PROCEDURE hd_purge_test
      

      AUTHID CURRENT_USER

      IS
        v_rpt_per_key NUMBER := 0;
        BEGIN
      
          SELECT MAX(stat.rpt_per_key)
          INTO v_rpt_per_key
          FROM rxfinods_sta.hd_invc_ln_item_dtl_stat stat;
          --HD_INVC_LN_ITEM_DTL_STAT        
      
          dbms_output.PUT_LINE('v_RPT_PER_KEY=' || v_rpt_per_key);
      
          EXCEPTION
          WHEN NO_DATA_FOUND THEN
            NULL;
          WHEN OTHERS THEN
          -- Consider logging the error and then re-raise
            RAISE;
        END hd_purge_test;
      

      【讨论】:

      • 使用 AUTHID CURRENT_USER 有助于块了解您正在尝试通过过程访问同一个表
      猜你喜欢
      • 2019-01-22
      • 2015-11-09
      • 2011-12-10
      • 2015-01-30
      • 2016-08-23
      • 2020-10-16
      • 2018-02-05
      • 1970-01-01
      相关资源
      最近更新 更多