SQL Server, VIEW 混淆了数据

Posted

技术标签:

【中文标题】SQL Server, VIEW 混淆了数据【英文标题】:SQL Server, VIEW has mixed up data 【发布时间】:2017-09-12 16:21:09 【问题描述】:

我和我的团队正在使用 Microsoft SQL Server 2014 - 标准版(64 位)

我们像往常一样创建了一些视图,它们在我们编码和测试时正常工作。

然后突然,我们的一位 QA 注意到应用程序中的数据混淆了,例如 description 数据在 name 字段,namesex 应该在的位置,等等。

我们检查了表格中的数据并且它是正确的,然后我们检查了视图,像这样SELECT * FROM VIEW查询视图并意识到视图混淆了数据。 。下一个逻辑步骤是检查视图查询,令我们惊讶的是所有查询都是正确的。那么发生了什么?

嗯,这就是问题,如果视图中的查询是正确的并且长时间运行良好,为什么视图中的数据会损坏或混淆?

我们只是 ALTERED 视图,没有修改任何内容,从而解决了问题。

但是,我们需要知道数据损坏的原因,因为我们不想一直监控和更改视图。

按要求查看代码

ALTER VIEW [dbo].[pvvClient] AS 
SELECT *
FROM Table
INNER JOIN Table 2 ON.....

我首先想到的是表格发生了变化,并且引发了这种行为,你认为 SCHEMABINDING 可以帮助避免此类问题

【问题讨论】:

您的视图中是否包含 *?请粘贴视图的内容。我敢打赌,您错过了一些逗号,因此某些列被解释为其他列的别名。 表 pvtConsumidorFinanciero 是否包含与 select 子句中的其他字段/别名同名的任何字段? @DanBracuk 不,它没有,它甚至在我们的 EF 模型中被引用 避免使用.* 问问自己,数据库怎么知道返回*的顺序是什么?如果表被改变,它会改变吗?它会因环境而异吗?由于 * 现在可能是 5 列,以后可能是 6 列,对下游有什么影响? 当然,这里有一篇很棒的文章来讨论这个问题。 sqlblog.com/blogs/aaron_bertrand/archive/2009/10/10/… 众所周知,除非它在exists子句中,否则应避免使用select *。 【参考方案1】:

当您将 * 放在视图的列列表中并且基础表发生更改时,您的视图将不会自动更新以包含更改的列。事实上,如果您删除一列,您可能会在各列之间混淆数据。这已被多次讨论和记录。 Aaron Bertrand 有一篇很棒的文章涵盖了这个主题。

Bad habits to kick : using SELECT * / omitting the column list

故事的寓意,除非选择在 EXISTS 中,否则避免使用 select *。

【讨论】:

【参考方案2】:

在不更改任何代码的情况下简单地更改视图将修复它是没有意义的,但重要的一点是视图的这一部分...

select pvtConsumidorFinanciero.*

如果此表定义更改...即,如果添加更多列或删除一些列,则此视图中的列也会更改。这就是为什么在视图中永远不要选择 * 是一种很好的做法,尤其是在查询另一个视图时。

此外,此表可以与其他表具有相同的列名。

在您的应用程序中也可能发生的事情,您是select * from view。同样,如果 DBA 更改了视图,这可能会弄乱您的应用程序,因此我会避免它,而是按照您希望它们返回的顺序显式列出您想要返回的列。

【讨论】:

【参考方案3】:

我认为这也是答案的一部分:

当您创建视图时,最好使用 SCHEMABINDING,这样当您更改视图下的表格时,您也必须检查您的视图。

【讨论】:

以上是关于SQL Server, VIEW 混淆了数据的主要内容,如果未能解决你的问题,请参考以下文章

SQL Server 日志文件混淆

SQL Server 索引(index) 和 视图(view) 的简单介绍和操作

Nodejs 操作 Sql Server

sql server view账户查询出来的表不全

在 SQL Server 中编写 VIEW 时需要帮助

sql server 2008数据库提示错误create view必须是批处理中仅有的语句