4

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

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

4

2 回答 2

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即使列的实际值没有改变,也会执行。这意味着该行被锁定,触发器触发等。

于 2010-01-26T15:24:03.500 回答
1

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

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

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

于 2010-01-26T15:59:09.813 回答