我有两个模式,如下所示:
例如:
create table data.tblTest (TestKey int not null primary key);
create view ui.vwTest as select * from data.tblTest;现在,如果我以用户身份与Studio连接,那么一切都没问题:
select * from ui.vwTest; -- WORKS (this is correct)
select * from data.tblTest; -- ERROR (this is correct)
insert into ui.vwTest (TestKey) values (17); -- WORKS (this is correct)
insert into data.tblTest (TestKey) values (17); -- ERROR (this is correct)但是,如果我用.NET/C#编写了一个使用SqlCommandBuilder的程序:
SqlDataAdapter ada = new SqlDataAdapter('select * from ui.vwTest', conn);
SqlCommandBuilder b = new SqlCommandBuilder(mSQLAda);
ada.UpdateCommand = b.GetUpdateCommand();
ada.InsertCommand = b.GetInsertCommand();
ada.DeleteCommand = b.GetDeleteCommand();然后,在下面的==>中,插入不工作!
编辑
SqlCommandBuilder正在分析视图,而不是创建以下命令
INSERT INTO ui.vwTest ...它正在创造
INSERT INTO data.tblTest ...因此,实际上,SqlCommandBuilder试图变得“智能”,并访问视图的底层表,而不是访问视图。
问题:这种行为可以改变吗?
顺便说一句,为了更清楚地说明,我在这里做所有权链接。
我的用户有权查看模式ui中的视图,但他们无权使用模式data。但是,由于所有权问题,用户可以通过模式data中的视图间接访问表。
详细地说,用户附加到自定义角色(例如"role_user“),角色对模式具有权限,如下所示:
GRANT SELECT, UPDATE, INSERT, DELETE ON SCHEMA ui TO role_user ;但是这个角色对模式“数据”没有权限!
这个设置的好处是您可以应用行级安全性。使用视图中的where筛选器,您只能选择允许用户查看的记录。
如前所述,它在SQL窗口中工作得很好,但对SQLCommandBuilder却不起作用。SQLCommandBuilder分析视图,并尝试直接访问底层表,而不是访问视图。
7年前,有人问:https://stackoverflow.com/a/320684/2504785和他的解决方案是自己编写SQL命令。但有可能,现在还有另一个解决方案吗?不过,到目前为止我还没有发现.
/EDIT
发布于 2015-07-05 14:47:56
好的,现在的答案是:
SqlCommandBuilder试图变得“聪明”。如果您使用像SELECT * FROM vwTest这样的命令打开它,那么它将分析视图并为底层表创建命令,比如INSERT into tblTest .
所以问题是:SqlCommandBuilder为底层表创建命令,而不是为视图创建命令。
解决方案:
到目前为止,我没有办法改变SqlCommandBuilder的行为。
因此,我重写了所有的加载和更新,现在我正在手动完成所有工作。加载现在完全是用SqlDataReader进行的--没有加载到带有SqlDataAdapter的DataTable中。所有的更新都是通过创建和执行SqlCommand来完成的,没有SqlCommandBuilder。
这是一项很大的工作,但作为回报,这个应用程序现在是的快速。加载远比使用SqlCommandBuilder和SqlDataAdapter快得多。也许我会在某个时候做一个基准比较。但是,当一个负载5秒前,它现在是“立即”完成。
发布于 2015-06-14 08:39:06
请注意所有权链文档的这一部分:
当通过链访问对象时,Server首先将对象所有者与调用对象的所有者进行比较。这是链中的前一个环节。如果两个对象具有相同的所有者,则引用对象的权限为而不是计算。“
因此,为了使所有权链接正常工作,您的表和视图必须按照相同的原则为所拥有的。
可以通过在对象上执行ALTER AUTHORIZATION sql语句来更改视图的所有者或表的所有者。
请注意,此语句只更改所有者,而不更改对象所属的架构。在您的示例中,我建议将UI模式的所有者更改为Data模式的同一个所有者,同时保留使用UI模式的数据库原则的权限。
ALTER AUTHORIZATION ON SCHEMA::UI TO <owner_of_the_data_schema>;注意:<owner_of_the_data_schema>是我使用的占位符,因为我不知道所有者的名称。
这样,应用程序用户仍然只能访问ui模式中的任何内容,但是所有权链允许ui模式中的对象与data模式中的对象交互。
https://stackoverflow.com/questions/30749222
复制相似问题