본문 바로가기

DB

[MSSQL 2000]실행중인 프로세스만 조회하기(커서 사용,실행중 쿼리문 포함)

쿼리는 길지만 상당히 핵심 부분은 상당히 간단한 쿼리다.
sysprocesses 테이블에서 정보 가져오는 부분이 핵심인데 sp_who 쿼리를 조금 변형한 것에 불과하다.
여기에 기존 sp_who에서는 명령이 update중인지 insert중인지 그런 형식으로만 보여주기에,
실제로 해당 프로세스에 보냈던 명령을 같이 보여주기 위해서 dbcc inputbuffer()하고 연결시켜주는 부분을 추가하였다.
그러나 이 부분을 추가하기 위해서 어쩔 수 없이 cursor를 쓰게 되었다.
역시 cursor가 들어가면 괜히 쿼리가 길어지고 복잡해보인다..ㅋ

----------------------------------------------------------------
--현재 돌고 있는 놈들의 리스트를 뽑아낸다.
--RUNNABLE	현재 돌고있는 놈
--SUSPENDED	현재 뒤에서 몰래 돌고있는 놈
----------------------------------------------------------------
IF  EXISTS (SELECT * FROM sysobjects WHERE id = OBJECT_ID(N'#RUNNING') AND type in (N'U'))
	DROP TABLE #RUNNING
SELECT	SPID
	,ECID=MAX(ECID)
	,ECID_CNT=COUNT(*)
	,TRAN_CNT=SUM(OPEN_TRAN)
	,STATUS=RTRIM(MAX(STATUS))
	,LOGINAME=RTRIM(LOGINAME)
	,HOSTNAME=RTRIM(HOSTNAME)
	,BLK=
	CASE
		WHEN BLOCKED = 0 OR (BLOCKED > 0 AND SPID = BLOCKED) THEN '0'
		ELSE CONVERT(VARCHAR(5),BLOCKED)
	END
	,DBNAME=
	CASE
		WHEN DBID = 0 THEN NULL
		WHEN DBID <> 0 THEN DB_NAME(DBID)
	END
	,CMD
	,EXCUTE_TIME=LAST_BATCH
	,DBCC_CMD = CONVERT(NVARCHAR(4000),'')
	,PROGRAM_NAME
INTO	#RUNNING
FROM	MASTER.DBO.SYSPROCESSES WITH (NOLOCK)
WHERE	SPID > 50
	AND SPID <> @@SPID --자신의 SPID는 조회할 필요가 없다.
	AND UPPER(CMD) <> 'AWAITING COMMAND'
GROUP BY
	SPID
	,RTRIM(LOGINAME)
	,RTRIM(HOSTNAME)
	,CASE
		WHEN BLOCKED = 0 OR (BLOCKED > 0 AND SPID = BLOCKED) THEN '0'
		ELSE CONVERT(VARCHAR(5),BLOCKED)
	END

	,CASE
		WHEN DBID = 0 THEN NULL
		WHEN DBID <> 0 THEN DB_NAME(DBID)
	END
	,CMD
	,LAST_BATCH
	,PROGRAM_NAME


--커서에 넣고 각 SPID에 해당하는 명령어를 DBCC INPUTBUFFER로 뽑아낸다.
DECLARE CURSOR1 CURSOR FAST_FORWARD
FOR
	SELECT	DISTINCT SPID
	FROM	#RUNNING
	ORDER BY SPID

--DBCC INPUTBUFFER로 뽑은 데이터를 테이블에 넣으려면 이 방법밖에 없는거 같다.
IF  EXISTS (SELECT * FROM sysobjects WHERE id = OBJECT_ID(N'#DBCC') AND type in (N'U'))
	DROP TABLE #DBCC
CREATE TABLE #DBCC(
EVENTTYPE nvarchar(30) Collate Korean_Wansung_CI_AS,
PARAMETERS INT,
EVENTINFO NVARCHAR(3970) Collate Korean_Wansung_CI_AS
)

DECLARE @SPID INT
DECLARE @STR_SPID VARCHAR(20)
DECLARE @EVENTINFO NVARCHAR(4000)
OPEN CURSOR1
FETCH NEXT FROM CURSOR1 INTO @SPID

WHILE (@@FETCH_STATUS=0)
BEGIN
	SET @STR_SPID=CONVERT(VARCHAR(20),@SPID)
	INSERT INTO #DBCC (EVENTTYPE,PARAMETERS,EVENTINFO)
	EXEC ('dbcc inputbuffer('+@STR_SPID+')')
	
	SELECT TOP 1 @EVENTINFO=EVENTINFO FROM #DBCC
	
	UPDATE #RUNNING
	SET DBCC_CMD=@EVENTINFO
	WHERE SPID=@SPID
	
	TRUNCATE TABLE #DBCC
	FETCH NEXT FROM CURSOR1 INTO @SPID
END

CLOSE CURSOR1
DEALLOCATE CURSOR1


INSERT INTO TB_SISREPORT_SYSPROCESSES
SELECT	GETDATE()
	,*
FROM	#RUNNING
ORDER BY SPID