oracle “ORA-01031:插入视图时收到权限不足”错误

z18hc3ub  于 2023-10-16  发布在  Oracle
关注(0)|答案(3)|浏览(157)

在用户名“MY_ADMIN”下,我成功地创建了一个名为“NOTIFICATIONS”的表和一个名为“V_NOTIFICATIONS”的视图。在'V_NOTIFICATIONS'视图中,我成功地创建了一个触发器和一个包,它接受用户试图插入到视图中的内容并将其插入到表中。当用户尝试对视图执行更新和删除功能时,“V_NOTIFICATIONS”触发器和包也会对表执行更新和删除功能。
我已经在我目前正在处理的项目中对许多视图进行了此操作,因为许多视图位于许多不同表的顶部,但是当试图将记录插入此视图时,我收到了“ORA-01031:权限不足错误。
我能够使用包中的相同代码直接插入到表中,但不能插入到视图中。任何关于这方面的帮助将不胜感激。下面是请求的代码:
VIEW:(当下面的UNION被注解掉时,包将按预期运行)

CREATE OR REPLACE FORCE VIEW "MY_ADMIN"."V_NOTIFICATIONS" AS
  SELECT N_ID,
    NOTIFICATION_TYPE,
    CASE WHEN NOTIFICATION_DESC = 'C' THEN 'Copy' ELSE 'Send to' END NOTIFICATION_DESC,
    CASE WHEN CONTACT_TYPE = 'D' THEN 'Department' ELSE 'Contact' END CONTACT_TYPE,
    A.AU_USER_ID,
    A.CONTACT_NAME,
    D.DEPARTMENT_ID,
    D.DEPT_DESC
  FROM NOTIFICATIONS AN,
    (SELECT A1.AU_USER_ID,
            AU.FIRST_NAME || ' ' || AU.LAST_NAME CONTACT_NAME
       FROM APP_USERS_CONTACT_INFO A1,
            APPLICATION_USERS AU
      WHERE A1.AU_USER_ID = AU.USER_ID
    /*UNION
     SELECT 0,
            NULL
       FROM DUAL*/) A,
    (SELECT DEPARTMENT_ID, 
            DESCRIPTION DEPT_DESC
       FROM DEPARTMENTS
      UNION
     SELECT 0 DEPARTMENT_ID,
            NULL DEPT_DESC 
       FROM DUAL) D
  WHERE NVL(AN.AU_USER_ID,0)      = A.AU_USER_ID
    AND NVL(AN.D_DEPARTMENT_ID,0) = D.DEPARTMENT_ID;

Package :

CREATE OR REPLACE PACKAGE NOTIFICATIONS_PKG AS

   PROCEDURE INSERT_NOTIFICATION(P_N_ROW V_NOTIFICATIONS%ROWTYPE);

END NOTIFICATIONS_PKG;
/
CREATE OR REPLACE PACKAGE BODY NOTIFICATIONS_PKG AS

   PROCEDURE INSERT_NOTIFICATION(P_N_ROW V_NOTIFICATIONS%ROWTYPE) IS

    L_NOTIFICATION_DESC    VARCHAR2(1);
    L_CONTACT_TYPE         VARCHAR2(1);

   BEGIN

      CASE P_N_ROW.NOTIFICATION_DESC
        WHEN 'Copy' THEN
          L_NOTIFICATION_DESC := 'C';
        ELSE
          L_NOTIFICATION_DESC := 'S';
      END CASE;

      CASE P_N_ROW.CONTACT_TYPE
        WHEN 'Department' THEN
          L_CONTACT_TYPE := 'D';
        ELSE
          L_CONTACT_TYPE := 'C';
      END CASE;

      INSERT INTO NOTIFICATIONS VALUES (
      P_N_ROW.N_ID,
      P_N_ROW.NOTIFICATION_TYPE,
      L_NOTIFICATION_DESC,
      L_CONTACT_TYPE,
      NVL(P_N_ROW.AU_USER_ID, 0),
      NVL(P_N_ROW.DEPARTMENT_ID, 0),
      APP_GLOBAL_PKG.GET_AUDIT);

   END INSERT_AGREEMENT_NOTIFICATION;
END AGREEMENT_NOTIFICATIONS_PKG;

设置触发器只是为了将信息传递给这个包以插入行。在尝试运行以下代码行时,我收到ORA-01031错误:

INSERT INTO V_AGREEMENT_NOTIFICATIONS VALUES (5781, 'Collateral Request', 'Send to', 'Contact', 797, '797T', 0, null);
fumotvh3

fumotvh31#

插入视图失败,因为您无法插入DUAL。不只是你,还有其他人。尝试

INSERT INTO DUAL (DUMMY) VALUES ('1')

看看会发生什么
分享和享受。

eh57zj3b

eh57zj3b2#

我能够使用与程序包中相同的代码直接插入表,但不能插入视图。
如果你直接调用这个包(即不是通过触发器间接调用),它能工作吗?
如果没有,那么您可以忽略视图/触发器方面的事情,并专注于包。一般来说,如果你可以直接运行SQL,但不能通过包运行,这是因为你有一个角色授予你使用必要的特权。存储的PL/SQL没有角色权限。
如果包工作正常,那么用户可能没有视图的插入特权。这可能有些奇怪,比如触发器对包没有特权,但这可能是一个编译错误,除非它使用动态SQL。
包上的INVOKER权限也可能有影响,因为这意味着它以触发器所有者而不是包所有者的权限运行。触发器所有者可能是视图的所有者,但可能与表的所有者不同。

kxe2p93d

kxe2p93d3#

为了扩展MJB对原始帖子的评论,有几个要求(在该链接中搜索“可更新视图的注解”)允许视图可更新。这一节的一些规则:

  • 视图中的所有列都必须Map到单个表的一列。
  • 视图不能有集合运算符、DISTINCT运算符、聚合或分析函数、GROUP BYORDER BY和类似子句
  • 如果视图包含任何联接,则DML必须只影响一个表

有一个ALL_UPDATABLE_COLUMNS数据字典视图,它可以列出视图中固有的可更新列,这些列可以被更新、插入或删除。

@dev01> describe ALL_UPDATABLE_COLUMNS
 Name         Null?    Type
 ------------ --------- --------------
 OWNER         NOT NULL VARCHAR2(128)
 TABLE_NAME    NOT NULL VARCHAR2(128)
 COLUMN_NAME   NOT NULL VARCHAR2(128)
 UPDATABLE              VARCHAR2(3)
 INSERTABLE             VARCHAR2(3)
 DELETABLE              VARCHAR2(3)

相关问题