programing

SQL Server:sp_who2의 필터 출력

mbctv 2023. 4. 6. 23:28
반응형

SQL Server:sp_who2의 필터 출력

SQL Server에서 sp_who2의 출력을 쉽게 필터링할 수 있는 방법이 있습니까?예를 들어 특정 데이터베이스에 대한 행만 표시하려고 합니다.

이런 걸 시도해 볼 수도 있어

DECLARE @Table TABLE(
        SPID INT,
        Status VARCHAR(MAX),
        LOGIN VARCHAR(MAX),
        HostName VARCHAR(MAX),
        BlkBy VARCHAR(MAX),
        DBName VARCHAR(MAX),
        Command VARCHAR(MAX),
        CPUTime INT,
        DiskIO INT,
        LastBatch VARCHAR(MAX),
        ProgramName VARCHAR(MAX),
        SPID_1 INT,
        REQUESTID INT
)

INSERT INTO @Table EXEC sp_who2

SELECT  *
FROM    @Table
WHERE ....

그리고 당신이 원하는 것을 걸러라.

결과를 임시 테이블에 저장할 수 있지만, 직접 소스로 이동하는 것이 좋습니다.master.dbo.sysprocesses.

다음은 과 거의 동일한 결과를 반환하는 쿼리입니다.

SELECT  spid,
        sp.[status],
        loginame [Login],
        hostname, 
        blocked BlkBy,
        sd.name DBName, 
        cmd Command,
        cpu CPUTime,
        physical_io DiskIO,
        last_batch LastBatch,
        [program_name] ProgramName   
FROM master.dbo.sysprocesses sp 
JOIN master.dbo.sysdatabases sd ON sp.dbid = sd.dbid
ORDER BY spid 

이제 쉽게 추가할 수 있습니다.ORDER BY또는WHERE의미 있는 출력을 얻고 싶은 절.


SSMS(++)Ctrl에서 Activity Monitor를 사용하는 것도 고려할 수 있습니다.

한 가지 방법은 임시 테이블을 작성하는 것입니다.

CREATE TABLE #sp_who2 
(
   SPID INT,  
   Status VARCHAR(1000) NULL,  
   Login SYSNAME NULL,  
   HostName SYSNAME NULL,  
   BlkBy SYSNAME NULL,  
   DBName SYSNAME NULL,  
   Command VARCHAR(1000) NULL,  
   CPUTime INT NULL,  
   DiskIO INT NULL,  
   LastBatch VARCHAR(1000) NULL,  
   ProgramName VARCHAR(1000) NULL,  
   SPID2 INT
) 
GO

INSERT INTO #sp_who2
EXEC sp_who2
GO

SELECT *
FROM #sp_who2
WHERE Login = 'bla'
GO

DROP TABLE #sp_who2
GO

http://web.archive.org/web/20080218124946/http 기반://sqlserver2005.databases.aspfaq.com/how-do-i-mimic-sp-who2.html

다음 스크립트를 작성했습니다.
DMV를 사용한 데이터베이스로의 액티브한 접속 검출을 해결합니다.이것은 sql 2005, 2008 및 2008R2에서 동작합니다.

다음 스크립트에서는 sys.dm_exec_displays, sys.dm_exec_displays, sys.dm_exec_connections, sys.dm_tran_displays를 사용합니다.

Declare @dbName varchar(1000)
set @dbName='abc'

;WITH DBConn(SPID,[Status],[Login],HostName,DBName,Command,LastBatch,ProgramName)
As
(
SELECT 
    SPID = s.session_id,
    Status = UPPER(COALESCE
        (
            r.status,
            ot.task_state,
            s.status, 
        '')),
    [Login] = s.login_name,
    HostName = COALESCE
        (
            s.[host_name],
            '  .'
        ),
    DBName = COALESCE
        (
            DB_NAME(COALESCE
            (
                r.database_id,
                t.database_id
            )),
            ''
        ),
    Command = COALESCE
        (
            r.Command,
            r.wait_type,
            wt.wait_type,
            r.last_wait_type,
            ''
        ),
    LastBatch = COALESCE
        (
            r.start_time,
            s.last_request_start_time
        ),
    ProgramName = COALESCE
        (
            s.program_name, 
            ''
        )
FROM
    sys.dm_exec_sessions s
LEFT OUTER JOIN
    sys.dm_exec_requests r
ON
    s.session_id = r.session_id
LEFT OUTER JOIN
    sys.dm_exec_connections c
ON
    s.session_id = c.session_id
LEFT OUTER JOIN
(
    SELECT 
        request_session_id,
        database_id = MAX(resource_database_id)
    FROM
        sys.dm_tran_locks
    GROUP BY
        request_session_id
) t
ON
    s.session_id = t.request_session_id
LEFT OUTER JOIN
    sys.dm_os_waiting_tasks wt
ON 
    s.session_id = wt.session_id
LEFT OUTER JOIN
    sys.dm_os_tasks ot
ON 
    s.session_id = ot.session_id
LEFT OUTER JOIN
(
    SELECT
        ot.session_id,
        CPU_Time = MAX(usermode_time)
    FROM
        sys.dm_os_tasks ot
    INNER JOIN
        sys.dm_os_workers ow
    ON
        ot.worker_address = ow.worker_address
    INNER JOIN
        sys.dm_os_threads oth
    ON
        ow.thread_address = oth.thread_address
    GROUP BY
        ot.session_id
) tt
ON
    s.session_id = tt.session_id
WHERE
    COALESCE
    (
        r.command,
        r.wait_type,
        wt.wait_type,
        r.last_wait_type,
        'a'
    ) >= COALESCE
    (
        '', 
        'a'
    )
)

Select * from DBConn
where DBName like '%'+@dbName+'%'

Astander의 답변이 약간 개선되었습니다.기준을 최우선으로 하여 일상적으로 쉽게 재사용할 수 있도록 하고 싶습니다.

DECLARE @Spid INT, @Status VARCHAR(MAX), @Login VARCHAR(MAX), @HostName VARCHAR(MAX), @BlkBy VARCHAR(MAX), @DBName VARCHAR(MAX), @Command VARCHAR(MAX), @CPUTime INT, @DiskIO INT, @LastBatch VARCHAR(MAX), @ProgramName VARCHAR(MAX), @SPID_1 INT, @REQUESTID INT

    --SET @SPID = 10
    --SET @Status = 'BACKGROUND'
    --SET @LOGIN = 'sa'
    --SET @HostName = 'MSSQL-1'
    --SET @BlkBy = 0
    --SET @DBName = 'master'
    --SET @Command = 'SELECT INTO'
    --SET @CPUTime = 1000
    --SET @DiskIO = 1000
    --SET @LastBatch = '10/24 10:00:00'
    --SET @ProgramName = 'Microsoft SQL Server Management Studio - Query'
    --SET @SPID_1 = 10
    --SET @REQUESTID = 0

    SET NOCOUNT ON 
    DECLARE @Table TABLE(
            SPID INT,
            Status VARCHAR(MAX),
            LOGIN VARCHAR(MAX),
            HostName VARCHAR(MAX),
            BlkBy VARCHAR(MAX),
            DBName VARCHAR(MAX),
            Command VARCHAR(MAX),
            CPUTime INT,
            DiskIO INT,
            LastBatch VARCHAR(MAX),
            ProgramName VARCHAR(MAX),
            SPID_1 INT,
            REQUESTID INT
    )
    INSERT INTO @Table EXEC sp_who2
    SET NOCOUNT OFF
    SELECT  *
    FROM    @Table
    WHERE
    (@Spid IS NULL OR SPID = @Spid)
    AND (@Status IS NULL OR Status = @Status)
    AND (@Login IS NULL OR Login = @Login)
    AND (@HostName IS NULL OR HostName = @HostName)
    AND (@BlkBy IS NULL OR BlkBy = @BlkBy)
    AND (@DBName IS NULL OR DBName = @DBName)
    AND (@Command IS NULL OR Command = @Command)
    AND (@CPUTime IS NULL OR CPUTime >= @CPUTime)
    AND (@DiskIO IS NULL OR DiskIO >= @DiskIO)
    AND (@LastBatch IS NULL OR LastBatch >= @LastBatch)
    AND (@ProgramName IS NULL OR ProgramName = @ProgramName)
    AND (@SPID_1 IS NULL OR SPID_1 = @SPID_1)
    AND (@REQUESTID IS NULL OR REQUESTID = @REQUESTID)

KyleMit의 답변과 마찬가지로 SP_WHO2에서 사용하는 테이블을 직접 선택할 수 있지만 dbo.sysprocesses 테이블만 있으면 된다고 생각합니다.

누군가가 이 SP를 열면 SP의 기능을 이해할 수 있습니다.SP_WHO2와 유사한 출력을 얻기 위해 이 방법을 선택하는 것이 가장 좋습니다.

select convert(char(5),sp.spid) as SPID
        ,  CASE lower(sp.status)
                 When 'sleeping' Then lower(sp.status)
                 Else  upper(sp.status)
              END as Status
        , convert(sysname, rtrim(sp.loginame)) as LOGIN
        , CASE sp.hostname
                 When Null  Then '  .'
                 When ' ' Then '  .'
                 Else    rtrim(sp.hostname)
              END as HostName
        , CASE isnull(convert(char(5),sp.blocked),'0')
                 When '0' Then '  .'
                 Else isnull(convert(char(5),sp.blocked),'0')
              END as BlkBy
        , case when sp.dbid = 0 then null when sp.dbid <> 0 then db_name(sp.dbid) end as DBName
        , sp.cmd as Command
        , sp.cpu as CPUTime
        , sp.physical_io as DiskIO
        , sp.last_batch as LastBatch
        , sp.program_name as ProgramName 
        from master.dbo.sysprocesses sp (nolock)
  ;

이 선택 항목에서 필요한 필드를 선택하고 원하는 순서를 지정할 수 있습니다.

sp_who3 사용자 스토어드 프로시저는 꽤 많이 있습니다.Adam Machanic은 AFAIK를 정말 잘했다고 확신합니다.

Adam은 이것을 Who Is Active라고 부릅니다.http://whoisactive.com

첫 번째 최선의 답변의 연장...마스터 데이터베이스에 저장 프로시저를 작성했습니다.이 프로시저는 파라미터를 에 전달할 수 있습니다.예를 들어 데이터베이스 이름:

USE master
GO

CREATE PROCEDURE sp_who_db
(
    @sDBName varchar(200)   = null,
    @sStatus varchar(200)   = null,
    @sCommand varchar(200)  = null,
    @nCPUTime int           = null
)
AS
DECLARE @Table TABLE
(
    SPID INT,
    Status VARCHAR(MAX),
    LOGIN VARCHAR(MAX),
    HostName VARCHAR(MAX),
    BlkBy VARCHAR(MAX),
    DBName VARCHAR(MAX),
    Command VARCHAR(MAX),
    CPUTime INT,
    DiskIO INT,
    LastBatch VARCHAR(MAX),
    ProgramName VARCHAR(MAX),
    SPID_1 INT,
    REQUESTID INT
)

INSERT INTO @Table EXEC sp_who2

SELECT  *
    FROM    @Table
    WHERE   (@sDBName IS NULL OR DBName = @sDBName)
    AND     (@sStatus IS NULL OR Status = @sStatus)
    AND     (@sCommand IS NULL OR Command = @sCommand)
    AND     (@nCPUTime IS NULL OR CPUTime > @nCPUTime)
GO 

특정 데이터에 대한 모든 연결을 끊기 위해 파라미터 또는 킬 파라미터에 의한 순서를 추가하도록 확장할 수 있습니다.

네, sp_who2의 출력을 테이블에 캡처한 후 테이블에서 선택합니다만, 이 방법은 좋지 않습니다.첫째, sp_who2는 그 인기에도 불구하고 문서화되어 있지 않은 프로시저이기 때문에 문서화되어 있지 않은 프로시저에 의존해서는 안 됩니다.둘째, sp_who2가 할 수 있는 모든 것 및 기타 많은 것을 sys.dm_exec_who2 및 기타 DMV에서 얻을 수 있으며 show는 필터, 순서, 결합 및 쿼리 가능한 행 집합과 함께 제공되는 기타 모든 goodies를 사용할 수 있습니다.

매우 간단한 방법은 EXCEL에 ODBC 링크를 만들고 거기에서 SP_WHO2를 실행하는 것입니다.

원하는 시간에 리프레쉬 할 수 있고, 엑셀이기 때문에 모든 것을 쉽게 조작할 수 있습니다!

차단 프로세스뿐만 아니라 차단 프로세스도 얻기 위해 개선했습니다.

DECLARE @Table TABLE
    (
    SPID INT, Status VARCHAR(MAX), LOGIN VARCHAR(MAX), HostName VARCHAR(MAX), BlkBy VARCHAR(MAX), DBName VARCHAR(MAX), Command VARCHAR(MAX), CPUTime INT, DiskIO INT, LastBatch VARCHAR(MAX), ProgramName VARCHAR(MAX), SPID_1 INT, REQUESTID INT
    )

INSERT INTO @Table EXEC sp_who2

SELECT  *
FROM    @Table
WHERE
    BlkBy not like '  .'
    or
    SPID in (SELECT  BlkBy from @Table where BlkBy not like '  .')

delete from @Table

앞으로 제 것을 사용하기 위해 여기에 글을 씁니다.Temp 테이블을 드롭하지 않으면 두 번 사용할 수 없기 때문에 sp_who2를 사용하여 temp 테이블 대신 테이블 변수에 삽입합니다.그리고 차단과 차단이 같은 줄에 표시됩니다.

--blocked: waiting becaused blocked by blocker
--blocker: caused blocking
declare @sp_who2 table(
    SPID int,
    Status varchar(max),
    Login varchar(max),
    HostName varchar(max),
    BlkBy varchar(max),
    DBName varchar(max),
    Command varchar(max),
    CPUTime int,
    DiskIO int,
    LastBatch varchar(max),
    ProgramName varchar(max),
    SPID_2 int,
    REQUESTID int
)
insert into @sp_who2 exec sp_who2
select  w.SPID blocked_spid, w.BlkBy blocker_spid, tblocked.text blocked_text, tblocker.text blocker_text
from    @sp_who2 w
        inner join sys.sysprocesses pblocked on w.SPID = pblocked.spid
        cross apply sys.dm_exec_sql_text(pblocked.sql_handle) tblocked
        inner join sys.sysprocesses pblocker on case when w.BlkBy = '  .' then 0 else cast(w.BlkBy as int) end = pblocker.spid
        cross apply sys.dm_exec_sql_text(pblocker.sql_handle) tblocker
where   pblocked.Status = 'SUSPENDED'

이 솔루션은 다음과 같습니다.http://blogs.technet.com/b/wardpond/archive/2005/08/01/the-openrowset-trick-accessing-stored-procedure-output-in-a-select-statement.aspx

select * from openrowset ('SQLOLEDB', '192.168.x.x\DATA'; 'user'; 'password', 'sp_who') 

언급URL : https://stackoverflow.com/questions/2234691/sql-server-filter-output-of-sp-who2

반응형