2010-05-11 17 views
1

Je veux exécuter un rapport de diagnostic sur notre serveur de base de données SQL Server 2008. Je suis en boucle à travers toutes les bases de données, puis pour chaque base de données, je veux regarder chaque table. Mais, quand je vais regarder chaque table (avec tbl_cursor), il prend toujours les tables dans la base de données 'master'.SQL Server: Pouvez-vous m'aider avec cette requête?

Je pense qu'il est à cause de ma sélection tbl_cursor:

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

Comment puis-je résoudre ce problème?


Voici le code complet:

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 
+4

@rib: il n'y a pas de "MS SQL". Le produit s'appelle "SQL Server". "MS SQL" peut être confondu avec "MySQL" trop facilement. –

Répondre

2

Le problème est dû au fait vous exécutez toujours la requête INFORMATION_SCHEMA.TABLES sous le contexte master db.

Vous devez convertir le bloc tbl_cursor en SQL dynamique afin de qualifier complètement la requête avec le nom de la base de données.

par exemple.

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

est essentiellement ce que vous devez exécuter pour ce curseur.

+0

Mise en œuvre: http://www.sommarskog.se/dynamic_sql.html#cursor0 –

2

Il est plus facile d'utiliser des variables de table afin que vous puissiez ajouter des lignes à @tablist en utilisant une autre instruction SQL dynamique

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

Vous devrez peut-être créer un SQL dynamique. car schéma_d'information récupère uniquement les objets de la base de données active en cours sur laquelle vous exécutez cette requête.

vous pouvez essayer sys.objects