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;

column1 のみが変更された場合でも、Oracle が常にORA-01031: 不十分な権限をスローする原因は何ですか。明らかな解決策は、クライアント アプリケーションを変更して、変更された列のみで 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;

ただし、これは効率的とは言えません。

ではOracleUPDATE列の実際の値が変わらなくても が実行されます。これは、行がロックされ、発火などを引き起こすことを意味します。

于 2010-01-26T15:24:03.500 に答える
1

ODAC コンポーネントまたはライブラリについてはわかりませんが、次のようなプロパティを設定できないでしょうか: update only:changed fieldsまたはall fields?

変更されていない場合でも、すべての列を含めるのは時間の無駄のようです。ほとんどのクライアント ライブラリがこのオプションを提供していると思います。

もちろん、sn TQuery-alike コンポーネントの SQL プロパティを設定した場合は、自分で SQL ステートメントを作成する必要があります (これも、変更された列のみに基づいて)。

于 2010-01-26T15:59:09.813 に答える