SQL SERVER修改函数名容易引发的问题分析

   2016-02-20 0
核心提示:这篇文章主要介绍了SQL SERVER修改函数名容易引发的问题分析的相关资料,需要的朋友可以参考下

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(N'dbo.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的定义

SQL SERVER修改函数名容易引发的问题分析

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

在SSMS上直接改名为dbo.ufn_test_2。

SQL SERVER修改函数名容易引发的问题分析

figure-2: 修改函数名

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

SQL SERVER修改函数名容易引发的问题分析

3. 解决与结论

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

SQL SERVER修改函数名容易引发的问题分析

结论:

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

(2)尽量使用SSMS的右键菜单修改或生成对象的定义。但如果函数或存储过程太多,会觉得sp_helptext和sys.all_sql_modules会更方便些,查询出来的结果要认真核对下对象名是否一致即可。这里提一下,sp_helptext有些限制,可以参考SQL中print、sp_helptext的限制与扩展

 
反对 0举报 0 评论 0
 

免责声明:本文仅代表作者个人观点,与乐学笔记(本网)无关。其原创性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容、文字的真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
    本网站有部分内容均转载自其它媒体,转载目的在于传递更多信息,并不代表本网赞同其观点和对其真实性负责,若因作品内容、知识产权、版权和其他问题,请及时提供相关证明等材料并与我们留言联系,本网站将在规定时间内给予删除等相关处理.

  • sql mysql和sqlserver存在就更新,不存在就插入
    转自:http://hi.baidu.com/tidy0608/item/ff930fe2436f2601560f1dd9sqlsever数据存在就更新,不存在就插入的两种方法两种经常使用的方法:1. Update, if @@ROWCOUNT = 0 then insertUPDATETable1 SETColumn1 = @newValue WHEREId = @idIF@@ROWCOU
    02-10
  • db2,oracle,mysql ,sqlserver限制返回的行数
    不同数据库限制返回的行数的关键字如下:①db2select * from table fetch first 10 rows only; ②oracleselect * from table where rownum=10; ③mysqlselect * from table limit 10; ④sqlServerselect top 10 * from table;
    02-10
  • C#操作SqlServer MySql Oracle通用帮助类Db_Helper_DG(默认支持数据库读写分离、查询结果实体映射ORM)
    C#操作SqlServer MySql Oracle通用帮助类Db_Hel
    【前言】  作为一款成熟的面向对象高级编程语言,C#在ADO.Net的支持上已然是做的很成熟,我们可以方便地调用ADO.Net操作各类关系型数据库,在使用了多年的Sql_Helper_DG后,由于项目需要,于是乎,就准备写一个Mysql_Helper在实现过程中,发现ADO.Net封装之
    02-10
  • oracle与mysql与sqlserver的分页 sql和oracle在分页上的区别
    oracle与mysql与sqlserver的分页 sql和oracle在
     假设当前是第PageNo页,每页有PageSize条记录,现在分别用Mysql、Oracle和SQL Server分页查询student表。1、Mysql的分页查询: 1 SELECT2 *3 FROM4 student5 LIMIT (PageNo - 1) * PageSize,PageSize;理解:(Limit n,m)  =从第n行开始取m条记录,n从0开始
    02-10
  • SqlServer/Oracle 通过一个sql判断新增/修改
    if (Config.DbInfo.DbType.Equals(DBType.SQLServer)){sql = " IF EXISTS (SELECT 1 FROM wifi.imsi_model_status WHEREdevice_id = @device_id and wireless='" + row[0].GetString() + "') UPDATE wifi.imsi_model_status SET model_status = @mo
    02-09
  • 数据库(MSSQLServer,Oracle,DB2,MySql)常见语句
    创建数据库表1 create table person2 (3 FName varchar(20),4 FAge int,5 FRemark varchar(20),6 primary key(FName)7 )View Code
    02-09
  • sqlserver,oracle,mysql等的driver驱动,url怎么
    oracledriver="oracle.jdbc.driver.OracleDriver"url="jdbc:oracle:thin:@localhost:1521:数据库名"sqlserverdriver="com.microsoft.jdbc.sqlserver.SQLServerDriver"url="jdbc:microsoft:sqlserver://localhost:1433;DatabaseName=数据库名"
    02-09
  • MySQL、SqlServer、Oracle三大主流数据库分页查
      在这里主要讲解一下MySQL、SQLServer2000(及SQLServer2005)和ORCALE三种数据库实现分页查询的方法。可能会有人说这些网上都有,但我的主要目的是把这些知识通过我实际的应用总结归纳一下,以方便大家查询使用。  下面就分别给大家介绍、讲解一下三种数
    02-09
  • 数据库(MSSQLServer,Oracle,DB2,MySql)常见语句
      上一篇文章http://www.cnblogs.com/valiant1882331/p/4056403.html写的太长了,所以就换了一篇,链接上一节继续字符串的拼接MySql中可以使用"+"来拼接两个字符串.select '12'+'33',FAge+'1' from t_employeeView Code
    02-09
  • 问题:sqlserver有没有类似Oracle的LISTAGG;结果: 灵活运用 SQL SERVER FOR XML PATH
    


		
灵活运用 SQL SERVER FOR XML P
    问题:sqlserver有没有类似Oracle的LISTAGG;结
            FOR XML PATH 有的人可能知道有的人可能不知道,其实它就是将查询结果集以XML形式展现,有了它我们可以简化我们的查询语句实现一些以前可能需要借助函数活存储过程来完成的工作。那么以一个实例为主.        一.FOR XML PATH 简单介绍
    02-09
点击排行