Bri*_*ian 1 sql-server view sql-server-2014 set-returning-functions
我有一个 TVPmyTVP实现为select val.* from vw_MyView val. 前几天,我修改了vw_MyView,将: 替换
select Foo,Bar from DB为
select Foo, Bash, Bar from DB。
这有一个奇怪的副作用:调用select Bar from myTVP()返回一个名为Bar填充了内容的列Bash(尽管事实上Bar和Bash甚至没有相同的类型)。
展示问题的匿名计划:https://www.brentozar.com/pastetheplan/?id=ryJLJmqdl
请注意,Object2和Object1是相同的,但两个计划之间最左侧嵌套循环的输出列表完全不同。
笔记:
是的,这是预期的。使用的函数和视图SELECT *最终会存储与底层列相关的部分元数据本身,因此它们很容易感到困惑。我在 2009 年的以下帖子中讨论过这个问题:
在我最近的 GroupBy 演示中:
如何避免这个问题?
SELECT *在对象中使用。WITH SCHEMABINDING的副作用)。*Bar在这种特定情况下,您可以使用以下方法修复该对象,以便返回正确的数据:
EXEC sys.sp_refreshsqlmodule @name = N'dbo.myTVP';
Run Code Online (Sandbox Code Playgroud)顺便说一句,文档sys.sp_refreshsqlmodule描述了这个确切的场景:
更新当前数据库中指定的非架构绑定存储过程、用户定义函数、视图、DML 触发器、数据库级 DDL 触发器或服务器级 DDL 触发器的元数据。这些对象的持久元数据(例如参数的数据类型)可能会因其底层对象的更改而变得过时。
顺便说一句,您不应该使用FROM myTVP()而是始终指定模式,例如FROM dbo.myTVP()。我在一篇旧文章中也谈到过这一点。
| 归档时间: |
|
| 查看次数: |
387 次 |
| 最近记录: |