在SQL Server中,咱們常常遇到一些需求,須要去搜索存儲過程(Procedure)、函數(Function)等對象是否包含某個對象或涉及某個對象,例如,我須要查找那些存儲過程、函數是否調用了連接服務器(LINKED SERVER),咱們若是從sys.sql_modules去搜索的話,若是有多個用戶數據庫,須要切換數據庫,執行屢次SQL語句。這些都是很是麻煩的事情。本着「模塊化定製腳本,減小重複工做量」的原則。寫了一個腳本find_prc_from_src_txt.sql, 之後在根據不一樣的需求逐步完善!sql
--==================================================================================================================
-- ScriptName : find_prc_from_src_txt.sql
-- Author : 瀟湘隱者
-- CreateDate : 2019-10-22
-- Description : 在SQL Server實例中經過條件搜索全部數據庫的存儲過程、函數、視圖,找出這些對象
-- Note :
/*******************************************************************************************************************
Parameters : 參數說明
********************************************************************************************************************
@src_text : 你要搜索的條件,例如,想找出那些存儲過程有調用某個連接服務器:@src_text=xxxx
********************************************************************************************************************
Notice : 因爲效率問題,有時候會被阻塞,在tempdb等待LCK_M_SCH_S
********************************************************************************************************************
Modified Date Modified User Version Modified Reason
********************************************************************************************************************
2019-10-22 瀟湘隱者 V01.00.00 新建該腳本。
*******************************************************************************************************************/
--==================================================================================================================
DECLARE @cmdText NVARCHAR(MAX);
DECLARE @database_name NVARCHAR(64);
DECLARE @src_text NVARCHAR(128);
SET @src_text='xxxx' --根據實際狀況輸入查詢、搜索條件
IF OBJECT_ID('TempDB.dbo.#databases') IS NOT NULL
DROP TABLE dbo.#databases;
CREATE TABLE #databases
(
database_id INT,
database_name sysname
);
INSERT INTO #databases
SELECT database_id ,
name
FROM sys.databases
WHERE name NOT IN ('model') AND state = 0; --state_desc=ONLINE
IF OBJECT_ID('TempDB.dbo.#sql_modules') IS NOT NULL
DROP TABLE #sql_modules;
/**********************************************************************************************************
此處若是用這種寫法,就會報下面錯誤,因此用下面這種寫法。
SELECT '' AS database_name, t.* INTO #sql_modules
FROM sys.sql_modules t WITH(NOLOCK) WHERE 1=0;
------------------------------------------------------------------------———----------------------------
Msg 8152, Level 16, State 2, Line 2
將截斷字符串或二進制數據。
**********************************************************************************************************/
SELECT 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' AS database_name
, t.* INTO #sql_modules
FROM sys.sql_modules t WITH(NOLOCK) WHERE 1=0;
WHILE 1= 1
BEGIN
SELECT TOP 1 @database_name= database_name
FROM #databases
ORDER BY database_id;
IF @@ROWCOUNT =0
BREAK;
SET @cmdText = N'USE ' + QUOTENAME(@database_name) + N';' +CHAR(10)
//**********************************************************************************************************
SELECT @cmdText += N'INSERT INTO ##sql_modules
SELECT *
FROM sys.sql_modules W
WHERE definition LIKE ''%@p_src_text%'';' + CHAR(10);
EXEC SP_EXECUTESQL @cmdText, N'@p_src_text NVARCHAR(128)',@p_src_text=@src_text;
此種方式不生效。這裏棄用這種動態SQL執行方式
***********************************************************************************************************/
SELECT @cmdText += N'INSERT INTO #sql_modules
SELECT @p_database_name
, t.*
FROM sys.sql_modules t WITH(NOLOCK)
WHERE definition LIKE ''%' +@src_text +'%'';' + CHAR(10);
EXEC SP_EXECUTESQL @cmdText,N'@p_database_name NVARCHAR(64)',@p_database_name=@database_name;
DELETE FROM #databases WHERE database_name=@database_name;
END
SELECT * FROM tempdb.dbo.#sql_modules;
IF OBJECT_ID('TempDB.dbo.#databases') IS NOT NULL
DROP TABLE dbo.#databases;
IF OBJECT_ID('TempDB.dbo.#sql_modules') IS NOT NULL
DROP TABLE #sql_modules;