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

发布于 2024-09-03 13:29:05 字数 2575 浏览 2 评论 0原文

在用户名“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);

Under the user name 'MY_ADMIN', I have successfully created a table called 'NOTIFICATIONS' and a view called 'V_NOTIFICATIONS'. On the 'V_NOTIFICATIONS' view I have successfully created a trigger and a package that takes what the user attempts to insert into the view and inserts it into the table. The 'V_NOTIFICATIONS' trigger and package also perform the update and delete functions on the table when the user attempts to perform the update and delete functions on the view.

I have done this with many views in the project I am currently working on, as many views sit over the top of many different tables, however when attempting to insert a record into this view I receive an 'ORA-01031: insufficient privileges' error.

I am able to insert directly into the table using the same code that is in the package, but not into the view. Any help on this would be greatly appreciated.
Here is the requested code:

VIEW: (When the UNION below is commented out, the package runs as expected)

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;

The trigger is setup just to pass information to this package to insert the row. Upon trying to run the following line of code I receive the ORA-01031 error:

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

栀梦 2024-09-10 13:29:05

插入视图失败,因为无法插入 DUAL。不只是你,任何人都可以。尝试

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

看看会发生什么。

分享并享受。

The INSERT into the view fails because you can't insert into DUAL. Not just you, but anybody. Try

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

to see what happens.

Share and enjoy.

沉默的熊 2024-09-10 13:29:05

“我可以使用包中的相同代码直接插入表中,但不能插入视图中。”

如果您直接调用该包(即不是通过触发器间接调用),它可以工作吗?

如果没有,那么您可以忽略事物的查看/触发方面并专注于包。一般来说,如果您可以直接运行 SQL,但不能通过包运行,这是因为您拥有一个授予您使用必要权限的角色。存储的 PL/SQL 没有角色权限。

如果该包确实有效,那么用户可能没有视图的插入权限。这可能有点奇怪,比如触发器没有包的权限,但这可能会导致编译错误,除非它使用动态 SQL。

包上的 INVOKER 权限也可能产生影响,因为这意味着它以触发器所有者而不是包所有者的权限运行。触发器所有者可能是视图的所有者,但这可能与表的所有者不同。

"I am able to insert directly into the table using the same code that is in the package, but not into the view."

If you call the package directly (ie not indirectly through a trigger), does it work ?

If it doesn't then you can ignore the view/trigger side of things and concentrate on the package. Generally if you can run the SQL directly but not through a package it is because you have a role granted to your use with the necessary privilege. Stored PL/SQL does not have role privileges.

If it the package does work, then probably the user doesn't have insert privilege on the view. It may be something odd like the trigger doesn't have privileges on the package but that would probably be a compilation error unless it used dynamic SQL.

INVOKER rights on the package may also have an effect, since that would mean that it runs with the privileges of the trigger owner rather than the package owner. The trigger owner is probably the owner of the view, but that may be different from the owner of the table(s).

夏日落 2024-09-10 13:29:05

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

  • 视图中的所有列必须映射到单个表的列。
  • 视图不能有集合运算符、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)

To expand a bit on MJB's comment to the original post, there are several requirements (search for "Notes on Updatable Views" at that link) to allow a view to be updatable. A few rules from that section:

  • All the columns in the view must map to a column of a single table.
  • The view cannot have a set operator, DISTINCT operator, aggregate or analytic function, GROUP BY, ORDER BY and similar clauses
  • If the view contains any joins, the DML must affect only one table

There is an ALL_UPDATABLE_COLUMNS data dictionary view that can list the columns of a view that is inherently updatable, that can be updated, inserted, or deleted.

@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)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文