【问题标题】:Database VIEW does not reflect the data in the underying TABLE数据库 VIEW 不反映底层 TABLE 中的数据
【发布时间】:2010-11-04 01:32:14
【问题描述】:

输入:

客户声称应用程序 (.NET) 在查询某些数据时返回的数据与客户直接查看数据表时不同。

我知道可能有各种原因,而且在完全不同的地方。我的目的不是在这里解决它,而是询问有经验的 DBA 和 DB 开发人员是否:

VIEW 是否可以显示与底层 TABLE(s) 不匹配的数据?

  • 可能的原因/原因是什么?
  • 视图上的 UPDATE 语句是否会导致未来的 SELECT 返回“更新的”数据,而表确实没有?

可能的原因(带问号的请评论):

  1. 原因是有两个独立的交易,这可以解释客户的困惑。
  2. 基础表已更改,但视图未刷新(使用 sp_refreshview)
  3. 不同的用户正在连接并且由于权限的原因可以看到不同的数据?
  4. 程序员错误:错误的表/列、错误的过滤器(此处为一体式)
  5. 发生损坏:DBCC CHECKDB 应该有帮助
  6. SELECT ... FOR UPDATE 会导致这个???
  7. ? __

真正发生的事情(答案):

某些表格中的列位置已更改:显然,客户将完整的数据库访问权限授予顾问以进行数据库使用分析。那位好人在使用SELECT * ... 子句时更改了列的顺序,以查看表开头的几个审计字段。

使用dbGhost 将数据库架构与问题出现前几天备份的架构进行比较,发现列位置差异。

接下来发生的与编程无关,更多的是政治问题。

因此,sp_refreshview 是解决方案。我只是多走了一步才能找到问题的根源。谢谢大家。

【问题讨论】:

  • 感谢您的想法。明天将在现场 - 这次将更新问题。
  • Re #2:不是“更新”,而是“改变”。具体来说,列定义已更改(更改、添加、删除、重新排序等)。
  • @RBarryYoung:谢谢 - 已修复。

标签: sql sql-server schema


【解决方案1】:

如果基础表已更改且 sp_refreshview 尚未针对视图运行,则有可能,因此如果将这些列添加到表中,视图将缺少列。

要了解我的意思,请阅读how to make sure that the view will have the underlying table changes by using sp_refreshview

【讨论】:

  • 对此+1,当您更改表结构时,您必须刷新视图,否则会发生奇怪的事情。
【解决方案2】:

当然还有其他的:

1) Derived attributes are pulling from wrong tables in the view
2) The view is using incorrect tables
3) incorrect or missing joins in the view

举几个例子

【讨论】:

  • @birdlips。对不起。不是在寻找程序员的错误。寻找可能由于其他因素(当然也包括人为因素)导致这种不一致的情况
【解决方案3】:

是的,有点。

可能的原因:

  1. 视图需要刷新或重新编译。当源列定义更改并且视图(或它所依赖的东西)使用“*”时会发生这种情况,这可能很讨厌。调用 sp_RefreshView。也可能由于它调用的视图或函数(数据源)而发生。

  2. The View 正在寻找与他们/您的想法不同的东西。他们正在查看错误的表格或视图。

  3. 视图正在以一种意想不到的方式转换数据。它工作正常,只是不像他们预期的那样。

  4. 视图返回的数据子集与预期不同。同样,它工作正常,只是不像他们想的那样。

  5. 他们正在查看错误的数据库/服务器或使用登录/用户身份导致视图更改其显示的内容。特别邪恶,因为与 Management Studio 不同,大多数客户端程序不会告诉您它们指向的数据库/服务器。

【讨论】:

  • 大声笑,无法告诉你我们有多少错误,因为有人在寻找仅在产品上的 QA 信息。
  • 嘿。是的,我花了很多时间(虽然有利可图)带领客户浏览类似案例。有一半的时候,直接问是行不通的:“你确定你在 Prod 上吗?是的。” +2 小时:“你确定吗?是的。” +3hrs:“所以你确定?..”(愤怒随之而来)。所以现在我用诸如“查询窗口状态栏左侧第三个单元格中的内容是什么?.. QA?那是你的 QA 数据库吗?”之类的问题来掩饰它。 (随之而来的愤怒要少得多......)
  • 第一点很好。它确实对我有帮助,我们需要刷新视图,以便在其任何基表发生更改时查看更改
【解决方案4】:

几种可能性:

  • 您的 .NET 应用程序可能没有指向您或他们认为它指向的位置。比如错误指向了测试服务器

  • 如果视图在浮点数或数值上具有索引,则由于四舍五入,该值可能与基础查询不同

  • ANSI_NULLS 设置特定于创建时的视图。如果它与在基础表上进行选择期间的设置不同,则可能会导致某些类型的查询出现差异

  • 基础表结构已更改且视图未刷新(尤其是使用“SELECT *”时会出现问题)

如果我想到其他帖子,我会编辑这篇文章。

编辑:以下是 ANSI_NULLS 设置如何影响结果的示例:

SET ANSI_NULLS ON

DECLARE
     @i     INT,
     @j     INT

SET @i = NULL
SET @j = 1

SELECT
     CASE WHEN @i <> @j THEN 'Not Equal' ELSE 'Equal' END

SET ANSI_NULLS OFF

SELECT
     CASE WHEN @i <> @j THEN 'Not Equal' ELSE 'Equal' END

您应该收到的结果是:

Equal

Not Equal

【讨论】:

  • @Tom。您能否发表更多评论或添加指向 ANSI_NULLS 相关原因的链接。谢谢。
  • 我在上面的帖子中包含了一个示例(cmets 中的代码不太好)
【解决方案5】:

假设视图实际上没有转换数据,从技术上讲,如果发生损坏是可能的。视图从一个索引检索数据,“表”从另一个索引(即从集群)检索数据,两者不同步。 DBCC CHECKDB 应该可以揭示问题。

但人为错误的可能性更大,即。他们正在查看与视图不同的表或不同的记录。

【讨论】:

    【解决方案6】:

    您可以创建带有锁定提示的视图,这意味着您可能会遇到脏读。或者,当他们直接访问表时,他们可能正在使用锁定提示,这可能会给他们带来脏读。

    用户似乎不理解的另一种可能性是数据是流动的。您在视图中 3:00 读取的数据可能与您在 3:30 直接查看表格时看到的数据不同,因为在此期间发生了变化。

    【讨论】:

      猜你喜欢
      • 2023-03-22
      • 2023-01-04
      • 2023-04-07
      • 1970-01-01
      • 2013-04-22
      • 1970-01-01
      • 1970-01-01
      • 2019-07-26
      • 1970-01-01
      相关资源
      最近更新 更多