列级特权与遗留应用程序

时间:2010-01-26 15:18:51

标签: oracle delphi privileges grant

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

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无能为力。

2 个答案:

答案 0 :(得分:3)

您可以在该视图上创建视图和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即使列的实际值没有变化也会执行。这意味着该行被锁定,触发火灾等。

答案 1 :(得分:1)

我不知道ODAC组件或库,但你不能设置一些属性,如:update onlychanged fieldsall fields

即使没有更改,这似乎也浪费时间来包含所有列。我认为大多数客户端库都提供此选项。

当然,如果你设置了类似sn TQuery的组件的一些SQL属性,你应该自己创建sql语句(也只基于更改的列)。