码迷,mamicode.com
首页 > 数据库 > 详细

SQL SERVER修改函数名引起的问题

时间:2016-02-01 23:46:43      阅读:239      评论:0      收藏:0      [点我收藏+]

标签:

1. 问题

今天遇到一个奇怪的问题:使用sp_helptext XXX查询出来的函数定义名竟然跟函数名不同,而sp_helptext实际是查询sys.all_sql_modules这个系统视图的。直接查询这个视图的definition字段,发现跟sp_helptext是一样的。难道是系统视图也存在缓存之类的机制?或者是个BUG?对于第一个问题,当时情况紧急,没有时间去求证是否存在了。第二个问题,我想没什么可能,SQL SERVER发展到今天(SQL 2016正式版准备推出,我使用的环境则是SQL 2008 R2,打了SP3),已经是很成熟的一个系统,即使是出现BUG也不是我这种水平的人能发现的,肯定是哪我哪里弄错了。于是求助于数据库技术交流群,很快有大神回答了是改名的问题。我马上就想起这个函数在一个多星期前,因为测试的需要,通过SSMS改了原函数名,而SQL SERVER不会因为改名去更新sys.all_sql_modules视图的definition字段的!于是就造成了已经编译好的函数与sys.all_sql_modules系统视图的函数定义出现了不一致的情况。

 

2. 重视与分析问题

做一个测试来重现下问题。首先,新建一个简单的测试函数dbo.ufn_test_1

USE AdventureWorks2008R2;
GO
IF OBJECT_ID(Ndbo.ufn_test_1) IS NOT NULL
BEGIN
    DROP FUNCTION dbo.ufn_test_1;
END
GO
CREATE FUNCTION dbo.ufn_test_1 ()
RETURNS CHAR(1)
AS
BEGIN
    RETURN (F);
END
GO

code-1: 创建函数dbo.ufn_test_1

 

这时,使用sp_helptext和sys.all_sql_modules查询,一切正常。

EXEC sp_helptext [dbo.ufn_test_1];
GO
SELECT OBJECT_ID(dbo.ufn_test_1) AS a, *  
FROM   sys.all_sql_modules
WHERE [object_id] = OBJECT_ID(dbo.ufn_test_1);
GO

code-2:查询函数dbo.ufn_test_1的定义

 

技术分享

figure-1: 查询函数dbo.ufn_test_1的定义

 

在SSMS上直接改名为dbo.ufn_test_2

技术分享

figure-2: 修改函数名

 

再去查询函数dbo.ufn_test_2的定义。这样,就出现了已经编译好的函数跟在视图中的函数定义出现了不一致的情况!如果通过sp_helptextsys.all_sql_modules查询出现的定义去更新生产服务器,就肯定会出现问题。

技术分享

 

3. 解决与结论

解决方法也很简单,把这个函数重建即可。如果使用SSMS的右键修改(Modify)或生成相关脚本(Script Function as)的菜单,则不会出现以上的问题。同样的问题,也适用于存储过程。

技术分享

 

 

结论:

(1)尽量不要修改对象名,确实要修改的话,就重建吧。如果是表并且包含的大量数据要重建的话,就比较麻烦了,即使是修改表名不会出现像函数、存储过程的问题,但修改表名涉及应用程序等问题。

(2)尽量使用SSMS的右键菜单修改或生成对象的定义。但如果函数或存储过程太多,会觉得sp_helptextsys.all_sql_modules会更方便些,查询出来的结果要认真核对下对象名是否一致即可。这里提一下,sp_helptext有些限制,可以参考我的另一篇博客关于sp_helptext的扩展。(http://www.cnblogs.com/fishparadise/p/4797539.html

 

SQL SERVER修改函数名引起的问题

标签:

原文地址:http://www.cnblogs.com/fishparadise/p/5175083.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!