首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >SqlCommandBuilder()为底层表而不是视图创建insert/update

SqlCommandBuilder()为底层表而不是视图创建insert/update
EN

Stack Overflow用户
提问于 2015-06-10 06:59:22
回答 2查看 1.9K关注 0票数 3

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

  • 模式“数据”
  • 模式'ui‘->保存来自外部的可访问的视图;其思想是您可以在这些视图上选择/删除/更新/插入。因此,我正在执行所有权链接.

例如:

代码语言:javascript
复制
create table data.tblTest (TestKey int not null primary key);
create view ui.vwTest as select * from data.tblTest;

现在,如果我以用户身份与Studio连接,那么一切都没问题:

代码语言:javascript
复制
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的程序:

代码语言:javascript
复制
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正在分析视图,而不是创建以下命令

代码语言:javascript
复制
INSERT INTO ui.vwTest ...

它正在创造

代码语言:javascript
复制
INSERT INTO data.tblTest ...

因此,实际上,SqlCommandBuilder试图变得“智能”,并访问视图的底层表,而不是访问视图。

问题:这种行为可以改变吗?

顺便说一句,为了更清楚地说明,我在这里做所有权链接

我的用户有权查看模式ui中的视图,但他们无权使用模式data。但是,由于所有权问题,用户可以通过模式data中的视图间接访问表。

详细地说,用户附加到自定义角色(例如"role_user“),角色对模式具有权限,如下所示:

代码语言:javascript
复制
GRANT SELECT, UPDATE, INSERT, DELETE ON SCHEMA ui TO role_user ;

但是这个角色对模式“数据”没有权限!

这个设置的好处是您可以应用行级安全性。使用视图中的where筛选器,您只能选择允许用户查看的记录。

如前所述,它在SQL窗口中工作得很好,但对SQLCommandBuilder却不起作用。SQLCommandBuilder分析视图,并尝试直接访问底层表,而不是访问视图。

7年前,有人问:https://stackoverflow.com/a/320684/2504785和他的解决方案是自己编写SQL命令。但有可能,现在还有另一个解决方案吗?不过,到目前为止我还没有发现.

/EDIT

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-07-05 14:47:56

好的,现在的答案是:

SqlCommandBuilder试图变得“聪明”。如果您使用像SELECT * FROM vwTest这样的命令打开它,那么它将分析视图并为底层表创建命令,比如INSERT into tblTest .

所以问题是:SqlCommandBuilder为底层表创建命令,而不是为视图创建命令。

解决方案:

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

因此,我重写了所有的加载和更新,现在我正在手动完成所有工作。加载现在完全是用SqlDataReader进行的--没有加载到带有SqlDataAdapterDataTable中。所有的更新都是通过创建和执行SqlCommand来完成的,没有SqlCommandBuilder

这是一项很大的工作,但作为回报,这个应用程序现在是的快速。加载远比使用SqlCommandBuilderSqlDataAdapter快得多。也许我会在某个时候做一个基准比较。但是,当一个负载5秒前,它现在是“立即”完成。

票数 1
EN

Stack Overflow用户

发布于 2015-06-14 08:39:06

请注意所有权链文档的这一部分:

当通过链访问对象时,Server首先将对象所有者与调用对象的所有者进行比较。这是链中的前一个环节。如果两个对象具有相同的所有者,则引用对象的权限为而不是计算。“

因此,为了使所有权链接正常工作,您的表和视图必须按照相同的原则为所拥有的

可以通过在对象上执行ALTER AUTHORIZATION sql语句来更改视图的所有者或表的所有者。

请注意,此语句只更改所有者,而不更改对象所属的架构。在您的示例中,我建议将UI模式的所有者更改为Data模式的同一个所有者,同时保留使用UI模式的数据库原则的权限。

代码语言:javascript
复制
ALTER AUTHORIZATION ON SCHEMA::UI TO <owner_of_the_data_schema>;

注意:<owner_of_the_data_schema>是我使用的占位符,因为我不知道所有者的名称。

这样,应用程序用户仍然只能访问ui模式中的任何内容,但是所有权链允许ui模式中的对象与data模式中的对象交互。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30749222

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档