我收到了实现列级权限的请求,例如:

GRANT UPDATE("column1") ON "TABLE" TO ROLE;

但我发现客户端应用程序(在Delphi ODAC中)总是发出SQL更新,如:

update TABLE set column1=:column1,column2=:column2,column3=:column3,...etc
where id_c=:id_c;

是什么导致Oracle总是抛出ORA-01031:权限不足,即使只更改了column1.显而易见的解决方案是更改客户端应用程序,以便它仅使用更改的列发出SQL更新,但它看起来像很多编码.

还有更优雅的解决方案吗?

编辑:我忘了提到我的Delphi源中有相当多的硬编码插入/更新查询.在这种情况下,ODAC无能为力.

解决方法

您可以在该视图上创建视图和INSTEAD OF UPDATE触发器:

CREATE VIEW myview ON mytable
AS
SELECT  *
FROM    table

CREATE TRIGGER trg_myview_iu
INSTEAD OF UPDATE
ON myview
FOR EACH ROW
BEGIN
        UPDATE  mytable
        SET     column1 = :NEW.column1
        WHERE   id_c = :NEW.id_c;
END;

如果只想在其值未更改时处理列,则必须编写几个UPDATE语句:

CREATE TRIGGER trg_myview_iu
INSTEAD OF UPDATE
ON myview
FOR EACH ROW
BEGIN
        IF :NEW.column1 <> :OLD.column1 THEN -- add `NULL` processing options if necessary
                UPDATE  mytable
                SET     column1 = :NEW.column1
                WHERE   id_c = :NEW.id_c;
        END IF;
        IF :NEW.column2 <> :OLD.column2 THEN
                UPDATE  mytable
                SET     column2 = :NEW.column2
                WHERE   id_c = :NEW.id_c;
        END IF;
        …
END;

但这远非效率.

在Oracle中,即使列的实际值没有改变,UPDATE也会执行.这意味着该行被锁定,触发火灾等.

dawei

【声明】:北京站长网内容转载自互联网,其相关言论仅代表作者个人观点绝非权威,不代表本站立场。如您发现内容存在版权问题,请提交相关链接至邮箱:bqsm@foxmail.com,我们将及时予以处理。