我有一张桌子,其中有不同的人属于不同的客户:
CREATE TABLE CLIENTS
(
CLIENT VARCHAR2(20),
FIRSTNAME VARCHAR2(20)
)
示例数据:
INSERT INTO CLIENTS (CLIENT, FIRSTNAME) VALUES ('A Corp.', 'Alice')
INSERT INTO CLIENTS (CLIENT, FIRSTNAME) VALUES ('B Corp.', 'Bob')
现在我想授予更改“公司”所有行名字的权限。对于人A和'B公司的行''对于人B.我认为通过为每个人创建一个视图是可能的。但是,如果不为每个人创建专门的授权视图,它是否也可能?
答案 0 :(得分:4)
如果您可以使用Oracle用户名或应用程序中的某些数据来识别用户,那么我认为您可以使用单个可更新视图,例如:
CREATE VIEW filtered_clients AS (
SELECT * FROM clients WHERE client LIKE USER || ' Corp.'
)
(其中“USER”是返回登录用户名的Oracle SQL函数。如果最终用户通过某个中间层共享数据库帐户,这将无法正常工作,但您可能会在最后通过 - 来自中间层的用户名,并改为使用它。)
为了避免硬编码用户名和客户端名称之间的关系,我建议添加另一个表来标识哪些用户可以管理哪些客户端。然后视图将是这样的:
CREATE VIEW filtered_clients AS (
SELECT * FROM clients WHERE client IN (
SELECT client FROM user_client_access WHERE username = USER
)
)
我相信这仍然可以更新。您可能希望阻止更新CLIENT
列;您可以通过在视图上指定WITH CHECK OPTION
或在基表上使用触发器来执行此操作。
如果您希望用户能够看到任何行,但只更新自己的行,那么查看方法就没有用了。相反,您可以在基表上只有一个触发器,在尝试更新时检查访问,如果用户尝试更新不同客户端的行,则会引发错误。
另一种方法是使用Oracle's Virtual Private Database feature,但这可能是矫枉过正的。 (也可能是一个额外费用的选项,我不确定。)