USE AdventureWorks2008R2;GOIF OBJECT_ID(N"dbo.ufn_test_1") IS NOT NULLBEGINDROP FUNCTION dbo.ufn_test_1;ENDGOCREATE FUNCTION dbo.ufn_test_1 ()RETURNS CHAR(1)ASBEGINRETURN ("F");ENDGOcode-1: 创建函数dbo.ufn_test_1
EXEC sp_helptext [dbo.ufn_test_1];GOSELECT OBJECT_ID("dbo.ufn_test_1") AS a, * FROM sys.all_sql_modulesWHERE [object_id] = OBJECT_ID("dbo.ufn_test_1");GOcode-2:查询函数dbo.ufn_test_1的定义
figure-1: 查询函数dbo.ufn_test_1的定义
在SSMS上直接改名为dbo.ufn_test_2。
figure-2: 修改函数名
再去查询函数dbo.ufn_test_2的定义。这样,就出现了已经编译好的函数跟在视图中的函数定义出现了不一致的情况!如果通过sp_helptext和sys.all_sql_modules查询出现的定义去更新生产服务器,就肯定会出现问题。
3. 解决与结论
解决方法也很简单,把这个函数重建即可。如果使用SSMS的右键修改(Modify)或生成相关脚本(Script Function as)的菜单,则不会出现以上的问题。同样的问题与解决方法,也适用于存储过程。
结论:
(1)尽量不要修改对象名,确实要修改的话,就重建吧。如果是表并且包含的大量数据要重建的话,就比较麻烦了,即使是修改表名不会出现像函数、存储过程的问题,但修改表名涉及应用程序等问题。
(2)尽量使用SSMS的右键菜单修改或生成对象的定义。但如果函数或存储过程太多,会觉得sp_helptext和sys.all_sql_modules会更方便些,查询出来的结果要认真核对下对象名是否一致即可。这里提一下,sp_helptext有些限制,可以参考SQL中print、sp_helptext的限制与扩展。