SQL Server: Можете ли вы помочь мне с этим запросом? - PullRequest
1 голос
/ 11 мая 2010

Я хочу запустить диагностический отчет на нашем сервере баз данных SQL Server 2008.

Я перебираю все базы данных, а затем для каждой базы данных хочу посмотреть каждую таблицу. Но когда я смотрю на каждую таблицу (с tbl_cursor), она всегда берет таблицы в базе данных 'master'.

Я думаю, это из-за моего tbl_cursor выбора:

    SELECT table_name FROM information_schema.tables WHERE table_type = 'base table'

Как это исправить?


Вот весь код:

SET NOCOUNT ON

DECLARE @table_count INT
DECLARE @db_cursor VARCHAR(100)
DECLARE database_cursor CURSOR FOR
SELECT name FROM sys.databases where name<>N'master'
OPEN database_cursor
FETCH NEXT FROM database_cursor INTO @db_cursor
WHILE @@Fetch_status = 0
BEGIN

    PRINT @db_cursor    
    SET @table_count = 0

    DECLARE @table_cursor VARCHAR(100)
    DECLARE tbl_cursor CURSOR FOR
    SELECT table_name FROM information_schema.tables WHERE table_type = 'base table'
    OPEN tbl_cursor
    FETCH NEXT FROM tbl_cursor INTO @table_cursor
    WHILE @@Fetch_status = 0
    BEGIN

        DECLARE @table_cmd NVARCHAR(255)
        SET @table_cmd = N'IF NOT EXISTS( SELECT TOP(1) *  FROM ' + @table_cursor + ') PRINT N''     Table ''''' + @table_cursor + ''''' is empty'' '
        --PRINT @table_cmd --debug
        EXEC sp_executesql @table_cmd
        SET @table_count = @table_count + 1

    FETCH NEXT FROM tbl_cursor INTO @table_cursor
    END
    CLOSE tbl_cursor
    DEALLOCATE tbl_cursor

    PRINT @db_cursor + N' Total Tables : ' + CAST( @table_count as varchar(2) ) 
    PRINT N'' -- print another blank line   
    SET @table_count = 0    

FETCH NEXT FROM database_cursor INTO @db_cursor
END
CLOSE database_cursor
DEALLOCATE database_cursor




SET NOCOUNT OFF

Ответы [ 3 ]

2 голосов
/ 11 мая 2010

Проблема в том, что вы фактически всегда выполняете запрос INFORMATION_SCHEMA.TABLES в контексте master db.

Вам потребуется преобразовать блок tbl_cursor в динамический SQL, чтобы полностью квалифицировать запрос с именем БД.

, например

SELECT table_name FROM YourDatabase.INFORMATION_SCHEMA.TABLES WHERE....

по сути то, что вам нужно выполнить для этого курсора.

2 голосов
/ 11 мая 2010

Табличные переменные проще использовать, поэтому вы можете добавлять строки в @tablist с помощью другого динамического оператора SQL

SET NOCOUNT ON

DECLARE @table_count INT
DECLARE @dblist TABLE (DBName VARCHAR(100))
DECLARE @tablist TABLE (TableName VARCHAR(100))
DECLARE @dbname varchar(100), @tabname varchar(100)

INSERT @dblist 
SELECT name FROM sys.databases where name<>N'master'

SELECT TOP 1 @dbname = DBName FROM @dblist
WHILE @@ROWCOUNT <> 0
BEGIN

    INSERT @tablist (tableName)
    EXEC ('SELECT table_name FROM ' + @dbname + '.information_schema.tables WHERE table_type = ''base table'' ')

    SELECT TOP 1 @tabname = tableName FROM @tablist
    WHILE @@ROWCOUNT <> 0
    BEGIN

--do my stuff

        DELETE @tablist WHERE tableName =  @tabname
        SELECT TOP 1 @tabname = tableName FROM @tablist
    END

    DELETE @dblist WHERE DBName =  @dbname
    SELECT TOP 1 @dbname = DBName FROM @dblist
END
0 голосов
/ 11 мая 2010

Возможно, вам придется создать динамический SQL. потому что information_schema будет извлекать объекты только из текущей активной базы данных, для которой вы выполняете этот запрос.

вы можете попробовать sys.objects

...