SQL Server: запрос SysProcesses и InputBuffer - PullRequest
0 голосов
/ 15 сентября 2011

Я пытаюсь получить данные входного буфера (DBCC INPUTBUFFER(@SPID)) для каждой записи, возвращаемой для базы данных при запросе таблицы SYSPROCESSES. Мне интересно услышать, есть ли лучший способ сделать это, но я также был бы признателен за исправление того, что у меня сейчас есть в учебных целях.

DECLARE @Max [int]
DECLARE @Min [int] = 1

SELECT @Max = COUNT(SPID)
FROM MASTER.DBO.SYSPROCESSES
WHERE DB_NAME(DBID) = 'Northwinds' AND DBID != 0

CREATE TABLE #Results (
    EventType [nvarchar](1024),
    Parameters [int],
    EventInfo [nvarchar](1024),
    SPID [int],
    STATUS [nvarchar](255),
    PROGRAM_NAME [nvarchar](1024),
    CMD [nvarchar](255),
    LOGINAME [nvarchar](255)
)

WHILE @Min <= @Max
BEGIN

    DECLARE @SPID [int]

    WITH SelectedRow AS (
        SELECT SPID, ROW_NUMBER() OVER (ORDER BY SPID) AS RowNumber
        FROM MASTER.DBO.SYSPROCESSES
        WHERE DB_NAME(DBID) = 'Northwinds' AND DBID != 0
    )

    SELECT @SPID = SPID
    FROM SelectedRow
    WHERE RowNumber = @Min

    DECLARE @InputBuffer TABLE (
        EventType [nvarchar](1024),
        Parameter [int],
        EventInfo [nvarchar](1024)
    )

    DECLARE @SysProcesses TABLE (
        SPID [int],
        STATUS [nvarchar](255),
        PROGRAM_NAME [nvarchar](1024),
        CMD [nvarchar](255),
        LOGINAME [nvarchar](255)
    )

    INSERT @InputBuffer 
        EXEC('DBCC INPUTBUFFER('+@SPID+')')

    INSERT @SysProcesses 
        SELECT SPID, STATUS, PROGRAM_NAME, CMD, LOGINAME
        FROM MASTER.DBO.SYSPROCESSES
        WHERE DB_NAME(DBID) = 'Northwinds' AND DBID != 0 AND SPID = @SPID

    INSERT INTO #TempResults(EventType, Parameters, EventInfo, SPID, STATUS, PROGRAM_NAME, CMD, LOGINAME)
        SELECT *
        FROM @InputBuffer, @SysProcesses

    SET @Min = (@Min + 1)
END

Теперь, когда я выполняю следующий запрос:

SELECT SPID
FROM MASTER.DBO.SYSPROCESSES
WHERE DB_NAME(DBID) = 'Northwinds' AND DBID != 0

возвращает 31 строку ...

Однако, когда я SELECT * FROM #TempResults после выполнения вышеупомянутого цикла, я возвращаю массовое количество дубликатов в временной таблице ... на сумму 10751.

Опять же, это в основном для обучения, но было бы довольно удобной функцией. Я ищу информацию о том, что мне не хватает, что приводит к возврату дубликатов записей, а также возможное лучшее решение.

Ответы [ 2 ]

0 голосов
/ 19 декабря 2016

Пожалуйста, обратитесь к запросу ниже для лучшего результата

DEclare @SPID [int]
DEclare @database_name [nvarchar](1024)
DEclare @hostname [nvarchar](1024)
DEclare @PROGRAM_NAME [nvarchar](1024)
DEclare @LOGINNAME [nvarchar](255)
DEclare @Inputbuffer [nvarchar] (4000)

CREATE TABLE #TempResults (
  SPID [int],
  database_name [nvarchar](1024),
  hostname [nvarchar](1024),
  PROGRAM_NAME [nvarchar](1024),
  LOGINAME [nvarchar](255),
  EventType [nvarchar](1024),
  Parameters [int],
  EventInfo [nvarchar](4000)
)


DECLARE db_cursor CURSOR FOR  
select spid,db_name(dbid), hostname,program_name,loginame from sys.sysprocesses where dbid in(11,10,13,14,15,16)  

OPEN db_cursor   
FETCH NEXT FROM db_cursor INTO @spid,@database_name,@hostname,@program_name,@loginname   

WHILE @@FETCH_STATUS = 0   
BEGIN   

     create table #InputBuffer1  (
    EventType [nvarchar](1024),
    Parameter [int],
    EventInfo [nvarchar](4000)
)

    INSERT into #InputBuffer1 
    EXEC('DBCC INPUTBUFFER('+@SPID+')')

create TABLE #SysProcesses  (
    SPID [int],
database_name [nvarchar](1024),
hostname [nvarchar](1024),
PROGRAM_NAME [nvarchar](1024),
LOGINAME [nvarchar](255)
)



INSERT INTO #SysProcesses(spid,database_name,hostname,program_name,LOGINAME) 
    SELECT  @spid,@database_name,@hostname,@program_name,@loginname

     insert into #TempResults
     select * from #SysProcesses,#InputBuffer1

    drop table #InputBuffer1
    drop table #SysProcesses


   FETCH NEXT FROM db_cursor INTO @spid,@database_name,@hostname,@program_name,@loginname  
END   

CLOSE db_cursor   
DEALLOCATE db_cursor

select *  from #TempResults
0 голосов
/ 15 сентября 2011

Вы делаете это:

INSERT #Results
SELECT * 
FROM @InputBuffer, @SysProcesses

Это фактически перекрестное соединение, поэтому, если в одной из таблиц будет более одной строки, в результате вы получите COUNT(left side) * COUNT(right side) строк.Возможно, вам следует использовать SELECT DISTINCT column list вместо этого или, как я предлагал в своем комментарии, прекратить циклически перебирать sysprocesses (устарело) и извлекать информацию из DBCC INPUTBUFFER - даже в образовательных целях, которые являются болезненными.

...