我正在做一些T-SQL编程,我在我的数据库上有一些Views定义。这些天数据模型仍在改变,我定义了一些表函数。有时我故意使用
select * from MYVIEW
在这样的表函数中返回所有列。如果视图更改(或表),则函数崩溃,我需要重新编译它。我知道这是一般的好事,所以它可以防止地狱错误,但仍然......
有没有办法编写这样的函数,所以每次我在基础表上改变某些东西时,不要“blow blow”?或许我做的事情完全错了......
感谢您的帮助
答案 0 :(得分:3)
gbn's answer是最好的 - 但是当你有SCHEMABINDING时,这通常会阻止你在没有先删除SCHEMABINDING然后在重新创建模块时替换它时进行底层更改。如果对象引用数据库外的对象,则不能使用SCHEMABINDING。
如果这个难度太大,你不希望或不能使用SCHEMABINDING,那么在你运行的某种常规过程中使用sp_refreshsqlmodule来检查你的SQL模块在实际使用之前是否有错误(它可以在任何非模式绑定视图,UDF,存储过程等上运行)是你的朋友。
您可以同时使用这两种技术 - 您不能(也没有必要)针对模式绑定对象运行sp_refreshsqlmodule。
例如,您只能在这些模块上运行它:SELECT *
FROM INFORMATION_SCHEMA.ROUTINES
WHERE (
OBJECTPROPERTY(OBJECT_ID(QUOTENAME(ROUTINE_SCHEMA) + '.' + QUOTENAME(ROUTINE_NAME)), N'IsSchemaBound') IS NULL
OR OBJECTPROPERTY(OBJECT_ID(QUOTENAME(ROUTINE_SCHEMA) + '.' + QUOTENAME(ROUTINE_NAME)),
N'IsSchemaBound') = 0
)
答案 1 :(得分:2)
将视图定义为“WITH SCHEMABINDING”
我会在这里向您推荐我的答案,其中涵盖类似的内容......
“select * from table” vs “select colA,colB,etc from table” interesting behaviour in SqlServer2005
在这种情况下,问题不是udf,而是在没有SCHEMABINDING的情况下视图的行为
编辑:Cade Roux的sp_refreshsqlmodule可能会起作用。我从来没有用过它。