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 字段,name 是 sex 应该在的位置,等等。
我们检查了表格中的数据并且它是正确的,然后我们检查了视图,像这样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 混淆了数据的主要内容,如果未能解决你的问题,请参考以下文章