代码之家  ›  专栏  ›  技术社区  ›  Juraj

列级特权与传统应用程序

  •  4
  • Juraj  · 技术社区  · 15 年前

    我收到一个实现列级特权的请求,例如:

    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;
    

    是什么让甲骨文总是 ORA-01031:权限不足 ,即使只更改了第1列。显而易见的解决方案是更改客户机应用程序,使其只使用已更改的列发出SQL更新,但看起来需要进行大量编码。

    有没有更优雅的解决方案?

    编辑:我忘记提到在我的Delphi源代码中有大量的硬编码插入/更新查询。在这种情况下,ODAC无能为力。

    2 回复  |  直到 15 年前
        1
  •  3
  •   Quassnoi    15 年前

    您可以创建视图和 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 , the 更新 即使列的实际值不变也执行。这意味着该行被锁定,引发火灾等。

        2
  •  1
  •   Edelcom    15 年前

    我不知道ODAC组件或库,但您不能设置如下属性: update only : changed fields all fields ?

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

    当然,如果您已经设置了sn tquery-liked组件的一些SQL属性,那么您应该自己创建SQL语句(也只基于已更改的列)。

    推荐文章