A system stored procedure is a proc that is stored in the master database that you can run in the context of other databases on the instance. For example, sp_msforeachtable is an example of a system stored procedure. You can run this procedure in any database on the instance and it will loop through the tables in the database and issue a command against each.
As an example, here is a stored procedure I wrote when SQL Server 2005 first came out. This procedure uses a dynamic management view to recurse through any blocking connections and indicates the connection that is doing the blocking along w/ the blocking statement. Making this a system stored procedure allows you to have the procedure in a centralized location, but with the advantage of being able to run it from any database on the instance.
USE [master]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
/*********************************************************************************************
* Procedure Name: dbo.sp_Blocking
* Author: Tim Chapman
***********************************************************************************************/
CREATE PROCEDURE [dbo].[sp_Blocking]
AS
BEGIN
IF OBJECT_ID('tempdb..#Processes') IS NOT NULL
DROP TABLE #Processes
SELECT
s.spid, BlockingSPID = s.blocked, DatabaseName = DB_NAME(s.dbid),
s.program_name, s.loginame, ObjectName = OBJECT_NAME(objectid, s.dbid),
Definition = CAST(text AS VARCHAR(MAX)), StatementBeginTime = last_batch
INTO #Processes
FROM
sys.sysprocesses s
CROSS APPLY sys.dm_exec_sql_text (sql_handle)
WHERE
s.spid > 50;
WITH Blocking
(
SPID, BlockingSPID, BlockingObject, BlockingStatement, RowNo, LevelRow,
StatementBeginTime, BlockingStatementBeginTime
)
AS
(
--//BASE CASE FOR QUERY
SELECT
s.SPID , s.BlockingSPID, s.ObjectName, s.Definition, ROW_NUMBER() OVER(ORDER BY s.SPID), 0 AS LevelRow,
s1.StatementBeginTime, s.StatementBeginTime
FROM
#Processes s
JOIN #Processes s1 ON s.SPID = s1.BlockingSPID
WHERE
s.BlockingSPID = 0
UNION ALL
--//RECURSIVE CASE
SELECT
r.SPID, r.BlockingSPID, r.ObjectName, r.Definition, d.RowNo, d.LevelRow + 1,
d.BlockingStatementBeginTime, r.StatementBeginTime
FROM
#Processes r
JOIN Blocking d ON r.BlockingSPID = d.SPID
WHERE
r.BlockingSPID > 0
)
SELECT
SPID,
BlockingSPID,
BlockingObject,
RowNo,
LevelRow,
BlockingStatementBeginTime,
StatementBeginTime,
PotentialBlockingDurationS = ABS(DATEDIFF(ms, StatementBeginTime, BlockingStatementBeginTime))/1000.0
FROM Blocking
ORDER BY
RowNo, LevelRow
END
Once my procedure has been created in the master database, I can use a system stored procedure to mark the procedure as a system stored procedure. :)
EXECUTE sp_ms_marksystemobject 'sp_Blocking'
From there, I can run the following in any database and it will produce any blocking procedures.
EXECUTE sp_Blocking
Posted
10/29/2009 7:28 PM
by
TimChapman