我有两个模式,如下所示:


模式“数据”->保存表,没有人可以从外部访问它们
模式'ui'->保存可从外部访问的视图;想法是您可以在这些视图上选择/删除/更新/插入。因此,我正在进行所有权链接。


例如:

create table data.tblTest (TestKey int not null primary key);
create view ui.vwTest as select * from data.tblTest;


现在,如果我以用户身份连接到SQL 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)


但是,如果我在使用SqlCommandBuilder的.NET / C#中编写程序:

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中的视图,但无权访问架构数据。但是,由于所有权变更,用户可以通过模式数据中的视图间接访问表。

详细地,将用户附加到自定义角色,例如,用户角色。 “ 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命令。
但是可能存在另一个解决方案?但是,到目前为止我没有发现...

[/编辑]

最佳答案

好吧,现在的答案是:

SqlCommandBuilder试图成为“智能”。如果使用SELECT * FROM vwTest之类的命令打开它,则它将分析视图并为基础表创建命令,例如INSERT into tblTest ...

因此问题是:SqlCommandBuilder为基础表而不是为视图创建命令。

解:

到目前为止,我发现没有办法更改SqlCommandBuilder的行为。

因此,我重写了所有的加载和更新,并且现在我手动进行所有操作。现在仅使用SqlDataReader进行加载-无需使用DataTable加载到SqlDataAdapter中。并且所有更新都是通过创建和执行SqlCommand来完成的,而没有SqlCommandBuilder

这是很多工作,但是作为奖励,该应用程序现在运行很快。加载速度远快于SqlCommandBuilderSqlDataAdapter。我可能会在某个时候进行基准比较。但是,当负载花了5秒钟之前,现在“立即”完成。

09-11 20:20