我收到了实现列级权限的请求,例如:
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 在这种情况下无法提供帮助。
最佳答案
您可以创建一个 View 并在该 View 上创建一个 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
也会执行。这意味着该行被锁定、触发等。
关于oracle - 列级权限与遗留应用程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2140313/