从视图中选择会显示错误的列集

Joh*_*nes 3 sql-server view

我正在从 SQL Server 的视图中进行选择。如果我右键单击它并选择“选择前 n 行”,它会运行并显示 30 列。如果我在 ALTER 模式下打开视图(右键单击,脚本视图为等...),突出显示代码并运行它,我会得到 50 列。我应该得到 50 列,因为我刚刚添加了 20 个新列到提供视图的表中,并且在视图中我使用了“SELECT * FROM...”语句。

我已经刷新了 Views 文件夹,但这没有帮助。

任何人都知道为什么会出现差异,以及如何纠正它?

Aar*_*and 19

首先,停止SELECT *在您的视图中使用。我在这里谈了很多:

接下来,运行sp_refreshviewsp_refreshsqlmodule针对引用您已更改的表(或另一个视图!)的每个视图,例如:

EXEC sp_refreshview N'dbo.viewname';
Run Code Online (Sandbox Code Playgroud)

如果要生成刷新系统中所有视图的脚本:

DECLARE @sql NVARCHAR(MAX) = N'';

SELECT @sql += N'
  EXEC sp_refreshsqlmodule N''' 
  + QUOTENAME(s.name) + '.' + QUOTENAME(v.name) + ''';'
FROM sys.schemas AS s 
INNER JOIN sys.views AS v 
ON s.[schema_id] = v.[schema_id]; 

EXEC sp_executesql @sql;
Run Code Online (Sandbox Code Playgroud)

(如果存在循环依赖或乱序依赖,您可能需要运行它两次。)

但这是临时解决办法。每次更改可能包含引用它的视图的任何表时,您都必须重复此操作,然后找出涉及哪些视图。这不是处理模式设计的正确方法。在所有。我写了一个 DDL 触发器,它可以帮助您自动执行此操作,但这确实是错误的方法 - 停止SELECT *在您的视图中使用!

您可能还需要考虑添加WITH SCHEMABINDING到所有视图的定义中。这有两件事:

  1. 阻止您SELECT *在视图中使用。这是一件好事™。
  2. 防止您在不确切知道更改会影响哪些视图的情况下更改基础表。这也是一件好事™。