我們正在從SQL Server 2005升級到2008年。幾乎2005實例中的每個數據庫都設置爲2000兼容模式,但我們跳到2008年。我們的測試已完成,但我們學到的是我們需要加快速度。我正在尋找驗證T-SQL存儲過程的可靠方法。有人得到一個?
我發現了一些存儲過程,從缺少的表中選擇數據或嘗試不存在的ORDER BY列。
包裝SQL以在SET PARSEONLY ON中創建過程並在try/catch中捕獲錯誤只捕獲ORDER BY中的無效列。它沒有找到過程從缺少的表中選擇數據的錯誤。然而,SSMS 2008的intellisense會發現問題,但我仍然可以繼續,並在沒有抱怨的情況下成功運行該過程的ALTER腳本。
那麼,爲什麼我甚至可以逃脫創建一個運行失敗的過程呢?有什麼工具可以做得比我嘗試的更好嗎?
我發現的第一個工具並不是非常有用:DbValidator from CodeProject,但發現的問題比我在SqlServerCentral上找到的腳本更少,它找到了無效的列引用。
-------------------------------------------------------------------------
-- Check Syntax of Database Objects
-- Copyrighted work. Free to use as a tool to check your own code or in
-- any software not sold. All other uses require written permission.
-------------------------------------------------------------------------
-- Turn on ParseOnly so that we don't actually execute anything.
SET PARSEONLY ON
GO
-- Create a table to iterate through
declare @ObjectList table (ID_NUM int NOT NULL IDENTITY (1, 1), OBJ_NAME varchar(255), OBJ_TYPE char(2))
-- Get a list of most of the scriptable objects in the DB.
insert into @ObjectList (OBJ_NAME, OBJ_TYPE)
SELECT name, type
FROM sysobjects WHERE type in ('P', 'FN', 'IF', 'TF', 'TR', 'V')
order by type, name
-- Var to hold the SQL that we will be syntax checking
declare @SQLToCheckSyntaxFor varchar(max)
-- Var to hold the name of the object we are currently checking
declare @ObjectName varchar(255)
-- Var to hold the type of the object we are currently checking
declare @ObjectType char(2)
-- Var to indicate our current location in iterating through the list of objects
declare @IDNum int
-- Var to indicate the max number of objects we need to iterate through
declare @MaxIDNum int
-- Set the inital value and max value
select @IDNum = Min(ID_NUM), @MaxIDNum = Max(ID_NUM)
from @ObjectList
-- Begin iteration
while @IDNum <= @MaxIDNum
begin
-- Load per iteration values here
select @ObjectName = OBJ_NAME, @ObjectType = OBJ_TYPE
from @ObjectList
where ID_NUM = @IDNum
-- Get the text of the db Object (ie create script for the sproc)
SELECT @SQLToCheckSyntaxFor = OBJECT_DEFINITION(OBJECT_ID(@ObjectName, @ObjectType))
begin try
-- Run the create script (remember that PARSEONLY has been turned on)
EXECUTE(@SQLToCheckSyntaxFor)
end try
begin catch
-- See if the object name is the same in the script and the catalog (kind of a special error)
if (ERROR_PROCEDURE() <> @ObjectName)
begin
print 'Error in ' + @ObjectName
print ' The Name in the script is ' + ERROR_PROCEDURE()+ '. (They don''t match)'
end
-- If the error is just that this already exists then we don't want to report that.
else if (ERROR_MESSAGE() <> 'There is already an object named ''' + ERROR_PROCEDURE() + ''' in the database.')
begin
-- Report the error that we got.
print 'Error in ' + ERROR_PROCEDURE()
print ' ERROR TEXT: ' + ERROR_MESSAGE()
end
end catch
-- Setup to iterate to the next item in the table
select @IDNum = case
when Min(ID_NUM) is NULL then @IDNum + 1
else Min(ID_NUM)
end
from @ObjectList
where ID_NUM > @IDNum
end
-- Turn the ParseOnly back off.
SET PARSEONLY OFF
GO
有什麼建議嗎?
也許通過運行您的自動迴歸測試,您會發現哪些內容已損壞並能夠在存儲過程級別上進行跟蹤。 – 2010-05-06 22:11:41
您也可以嘗試SET NOEXEC ON,並執行每個存儲的程序,但我發現它也沒有得到很多錯誤。 EXEC sys.sp_refreshsqlmodule部分成功捕獲一些錯誤。我發現的唯一可靠的方法是運行一個工具來實際執行每個存儲過程,表值函數爲每個參數傳遞NULL,然後回滾並記錄任何失敗。 (並從每個視圖中進行選擇)顯然,這取決於您的程序耗時多久,以及它們的確切性質如何。 – 2010-05-06 22:35:21
@John - 哈!自動迴歸測試...不適用於這些數據庫。我們一直在努力清理這位客戶的混亂近兩年了!但我同意,這將是一條路,但我們沒有時間去開發測試。 – 2010-05-06 23:58:52