SQL SERVER修改函數(shù)名容易引發(fā)的問題分析
1. 問題
今天遇到一個(gè)奇怪的問題:使用sp_helptext XXX查詢出來的函數(shù)定義名竟然跟函數(shù)名不同,而sp_helptext實(shí)際是查詢sys.all_sql_modules這個(gè)系統(tǒng)視圖的。直接查詢這個(gè)視圖的definition字段,發(fā)現(xiàn)跟sp_helptext是一樣的。難道是系統(tǒng)視圖也存在緩存之類的機(jī)制?或者是個(gè)BUG?對于第一個(gè)問題,當(dāng)時(shí)情況緊急,沒有時(shí)間去求證是否存在了。第二個(gè)問題,我想沒什么可能,SQL SERVER發(fā)展到今天(SQL 2016正式版準(zhǔn)備推出,我使用的環(huán)境則是SQL 2008 R2,打了SP3),已經(jīng)是很成熟的一個(gè)系統(tǒng),即使是出現(xiàn)BUG也不是我這種水平的人能發(fā)現(xiàn)的,肯定是哪我哪里弄錯了。于是求助于數(shù)據(jù)庫技術(shù)交流群,很快有大神回答了是改名的問題。我馬上就想起這個(gè)函數(shù)在一個(gè)多星期前,因?yàn)闇y試的需要,通過SSMS改了原函數(shù)名,而SQL SERVER不會因?yàn)楦拿ジ聅ys.all_sql_modules視圖的definition字段的!于是就造成了已經(jīng)編譯好的函數(shù)與sys.all_sql_modules系統(tǒng)視圖的函數(shù)定義出現(xiàn)了不一致的情況。
2. 重視與分析問題
做一個(gè)測試來重現(xiàn)下問題。首先,新建一個(gè)簡單的測試函數(shù)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: 創(chuàng)建函數(shù)dbo.ufn_test_1
這時(shí),使用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:查詢函數(shù)dbo.ufn_test_1的定義
figure-1: 查詢函數(shù)dbo.ufn_test_1的定義
在SSMS上直接改名為dbo.ufn_test_2。
figure-2: 修改函數(shù)名
再去查詢函數(shù)dbo.ufn_test_2的定義。這樣,就出現(xiàn)了已經(jīng)編譯好的函數(shù)跟在視圖中的函數(shù)定義出現(xiàn)了不一致的情況!如果通過sp_helptext和sys.all_sql_modules查詢出現(xiàn)的定義去更新生產(chǎn)服務(wù)器,就肯定會出現(xiàn)問題。
3. 解決與結(jié)論
解決方法也很簡單,把這個(gè)函數(shù)重建即可。如果使用SSMS的右鍵修改(Modify)或生成相關(guān)腳本(Script Function as)的菜單,則不會出現(xiàn)以上的問題。同樣的問題與解決方法,也適用于存儲過程。
結(jié)論:
(1)盡量不要修改對象名,確實(shí)要修改的話,就重建吧。如果是表并且包含的大量數(shù)據(jù)要重建的話,就比較麻煩了,即使是修改表名不會出現(xiàn)像函數(shù)、存儲過程的問題,但修改表名涉及應(yīng)用程序等問題。
(2)盡量使用SSMS的右鍵菜單修改或生成對象的定義。但如果函數(shù)或存儲過程太多,會覺得sp_helptext和sys.all_sql_modules會更方便些,查詢出來的結(jié)果要認(rèn)真核對下對象名是否一致即可。這里提一下,sp_helptext有些限制,可以參考SQL中print、sp_helptext的限制與擴(kuò)展。
相關(guān)文章
sqlserver 臨時(shí)表 Vs 表變量 詳細(xì)介紹
說臨時(shí)表和表變量,這是一個(gè)古老的話題,我們在網(wǎng)上也找到很多的資料闡述兩者的特征,優(yōu)點(diǎn)與缺點(diǎn)2011-11-11執(zhí)行一條sql語句update多條記錄實(shí)現(xiàn)思路
如果你想更新多行數(shù)據(jù),并且每行記錄的各字段值都是各不一樣,你會怎么辦呢?本文以一個(gè)示例向大家講解下如何實(shí)現(xiàn)如標(biāo)題所示的情況,有此需求的朋友可以了解下2013-08-08sql 多條件組合查詢,并根據(jù)指定類別找出所有最小子類別的SQL語句備忘
多條件組合查詢,并根據(jù)指定類別找出所有最小子類別的SQL語句備忘2009-06-06SQL Server SQL Agent服務(wù)使用教程小結(jié)
SQL Server SQL Agent服務(wù)使用教程小結(jié)...2007-03-03簡單觸發(fā)器的使用 獻(xiàn)給SQL初學(xué)者
簡單觸發(fā)器的使用 獻(xiàn)給SQL初學(xué)者,使用sqlserver的朋友可以參考下。2011-09-09當(dāng)恢復(fù)sqlserver bak文件時(shí),原始的用戶無法刪除的解決方法
當(dāng)你從現(xiàn)有的bak文件,恢復(fù)數(shù)據(jù)庫時(shí),如果數(shù)據(jù)庫本身帶有一個(gè)用戶:比如用戶叫:DemoUser.2010-06-06