88 votes

Comment trouver les noms des colonnes pour toutes les tables dans toutes les bases de données de SQL Server ?

Je veux trouver tous les noms de colonnes dans toutes les tables. dans toutes les bases de données . Existe-t-il une requête qui puisse faire cela pour moi ?

1 votes

J'ai mis à jour ma réponse, elle fonctionnera pour toutes les bases de données sous SQL Server 2000.

121voto

KM. Points 51800

Essayez ceci :

select 
    o.name,c.name 
    from sys.columns            c
        inner join sys.objects  o on c.object_id=o.object_id
    order by o.name,c.column_id

Avec les noms de colonnes qui en résultent, ce serait :

select 
     o.name as [Table], c.name as [Column]
     from sys.columns            c
         inner join sys.objects  o on c.object_id=o.object_id
     --where c.name = 'column you want to find'
     order by o.name,c.name

Ou pour plus de détails :

SELECT
    s.name as ColumnName
        ,sh.name+'.'+o.name AS ObjectName
        ,o.type_desc AS ObjectType
        ,CASE
             WHEN t.name IN ('char','varchar') THEN t.name+'('+CASE WHEN s.max_length<0 then 'MAX' ELSE CONVERT(varchar(10),s.max_length) END+')'
             WHEN t.name IN ('nvarchar','nchar') THEN t.name+'('+CASE WHEN s.max_length<0 then 'MAX' ELSE CONVERT(varchar(10),s.max_length/2) END+')'
            WHEN t.name IN ('numeric') THEN t.name+'('+CONVERT(varchar(10),s.precision)+','+CONVERT(varchar(10),s.scale)+')'
             ELSE t.name
         END AS DataType

        ,CASE
             WHEN s.is_nullable=1 THEN 'NULL'
            ELSE 'NOT NULL'
        END AS Nullable
        ,CASE
             WHEN ic.column_id IS NULL THEN ''
             ELSE ' identity('+ISNULL(CONVERT(varchar(10),ic.seed_value),'')+','+ISNULL(CONVERT(varchar(10),ic.increment_value),'')+')='+ISNULL(CONVERT(varchar(10),ic.last_value),'null')
         END
        +CASE
             WHEN sc.column_id IS NULL THEN ''
             ELSE ' computed('+ISNULL(sc.definition,'')+')'
         END
        +CASE
             WHEN cc.object_id IS NULL THEN ''
             ELSE ' check('+ISNULL(cc.definition,'')+')'
         END
            AS MiscInfo
    FROM sys.columns                           s
        INNER JOIN sys.types                   t ON s.system_type_id=t.user_type_id and t.is_user_defined=0
        INNER JOIN sys.objects                 o ON s.object_id=o.object_id
        INNER JOIN sys.schemas                sh on o.schema_id=sh.schema_id
        LEFT OUTER JOIN sys.identity_columns  ic ON s.object_id=ic.object_id AND s.column_id=ic.column_id
        LEFT OUTER JOIN sys.computed_columns  sc ON s.object_id=sc.object_id AND s.column_id=sc.column_id
        LEFT OUTER JOIN sys.check_constraints cc ON s.object_id=cc.parent_object_id AND s.column_id=cc.parent_column_id
    ORDER BY sh.name+'.'+o.name,s.column_id

EDIT
Voici un exemple de base pour obtenir toutes les colonnes dans toutes les bases de données :

DECLARE @SQL varchar(max)
SET @SQL=''
SELECT @SQL=@SQL+'UNION
select 
'''+d.name+'.''+sh.name+''.''+o.name,c.name,c.column_id
from '+d.name+'.sys.columns            c
    inner join '+d.name+'.sys.objects  o on c.object_id=o.object_id
    INNER JOIN '+d.name+'.sys.schemas  sh on o.schema_id=sh.schema_id
'
FROM sys.databases d
SELECT @SQL=RIGHT(@SQL,LEN(@SQL)-5)+'order by 1,3'
--print @SQL
EXEC (@SQL)

EDIT Version SQL Server 2000

DECLARE @SQL varchar(8000)
SET @SQL=''
SELECT @SQL=@SQL+'UNION
select 
'''+d.name+'.''+sh.name+''.''+o.name,c.name,c.colid
from '+d.name+'..syscolumns            c
    inner join sysobjects  o on c.id=o.id
    INNER JOIN sysusers  sh on o.uid=sh.uid
'
FROM master.dbo.sysdatabases d
SELECT @SQL=RIGHT(@SQL,LEN(@SQL)-5)+'order by 1,3'
--print @SQL
EXEC (@SQL)

EDIT
Sur la base de certains commentaires, voici une version qui utilise sp_MSforeachdb :

sp_MSforeachdb 'select 
    ''?'' AS DatabaseName, o.name AS TableName,c.name AS ColumnName
    from sys.columns            c
        inner join ?.sys.objects  o on c.object_id=o.object_id
    --WHERE ''?'' NOT IN (''master'',''msdb'',''tempdb'',''model'')
    order by o.name,c.column_id'

1 votes

Fonctionne sur la base de données actuelle, pas sur toutes les bases de données.

2 votes

Pouvez-vous porter cet exemple pour SQL Server 2000 ? Dans SQL Server 2000, il n'y a pas de sys objet. Le remplacement des sys.colums con syscolumns de l'aide ?

2 votes

Vous pouvez également essayer d'exécuter la requête originale avec sp_MSforeachdb

36voto

Jeremy Points 2193

Pourquoi ne pas utiliser

Select * From INFORMATION_SCHEMA.COLUMNS

Vous pouvez le rendre spécifique à la DB avec

Select * From DBNAME.INFORMATION_SCHEMA.COLUMNS

0 votes

L'une des raisons est que vous voulez le faire à partir d'une fonction qui ne connaît pas à l'avance le nom de la base de données.

1 votes

@ZachSmith 7 ans après la réponse originale ? sympa ! De plus, les fonctions n'existaient pas dans SQL 2000, donc même si vous aviez un point, il n'est pas valide pour cette question.

2 votes

Les questions sont donc intemporelles puisqu'il s'agit d'un résultat Google de premier ordre. Par ailleurs. Je ne savais pas que.

28voto

Mehran Points 79
SELECT * 
FROM information_schema.columns 
WHERE column_name = 'My_Column'

Vous devez définir le nom de votre base de données actuelle avec USE [db_name] avant cette requête.

9 votes

La question porte spécifiquement sur toutes les bases de données et non pas un seul.

3voto

majestzim Points 13

Normalement, j'essaie de faire tout ce que je peux pour éviter l'utilisation de curseurs, mais la requête suivante vous donnera tout ce dont vous avez besoin :

--Declare/Set required variables
DECLARE @vchDynamicDatabaseName AS VARCHAR(MAX),
        @vchDynamicQuery As VARCHAR(MAX),
        @DatabasesCursor CURSOR

SET @DatabasesCursor = Cursor FOR

--Select * useful databases on the server
SELECT name 
FROM sys.databases 
WHERE database_id > 4 
ORDER by name

--Open the Cursor based on the previous select
OPEN @DatabasesCursor
FETCH NEXT FROM @DatabasesCursor INTO @vchDynamicDatabaseName
WHILE @@FETCH_STATUS = 0
   BEGIN

   --Insert the select statement into @DynamicQuery 
   --This query will select the Database name, all tables/views and their columns (in a comma delimited field)
   SET @vchDynamicQuery =
   ('SELECT ''' + @vchDynamicDatabaseName + ''' AS ''Database_Name'',
          B.table_name AS ''Table Name'',
         STUFF((SELECT '', '' + A.column_name
               FROM ' + @vchDynamicDatabaseName + '.INFORMATION_SCHEMA.COLUMNS A
               WHERE A.Table_name = B.Table_Name
               FOR XML PATH(''''),TYPE).value(''(./text())[1]'',''NVARCHAR(MAX)'')
               , 1, 2, '''') AS ''Columns''
   FROM ' + @vchDynamicDatabaseName + '.INFORMATION_SCHEMA.COLUMNS B
   WHERE B.TABLE_NAME LIKE ''%%''
         AND B.COLUMN_NAME LIKE ''%%''
   GROUP BY B.Table_Name
   Order BY 1 ASC')

   --Print @vchDynamicQuery
   EXEC(@vchDynamicQuery)

   FETCH NEXT FROM @DatabasesCursor INTO @vchDynamicDatabaseName
END
CLOSE @DatabasesCursor
DEALLOCATE @DatabasesCursor
GO

J'ai ajouté une clause where dans la requête principale (ex : B.TABLE_NAME LIKE ''%%%'' AND B.COLUMN_NAME LIKE ''%%%'') afin que vous puissiez rechercher des tables et/ou des colonnes spécifiques si vous le souhaitez.

2voto

Ardalan Shahgholi Points 1437

L'utilisateur @KM dit la meilleure réponse.

J'utilise ceci :

Declare @Table_Name VarChar(100) ,@Column_Name VarChar(100)
Set @Table_Name = ''
Set @Column_Name = ''

Select 
RowNumber = Row_Number() Over( PARTITION BY T.[Name] Order By T.[Name],C.column_id  ),
SCHEMA_NAME( T.schema_id ) As SchemaName ,  
T.[Name] As Table_Name ,
C.[Name] As Field_Name , 
sysType.name ,
C.max_length , C.is_nullable , C.is_identity , C.scale , C.precision  
From Sys.Tables As T
Left Join Sys.Columns As C On ( T.[Object_Id] = C.[Object_Id] )
Left Join sys.types As sysType On ( C.user_type_id = sysType.user_type_id )
Where ( Type = 'U' )
    And ( C.Name Like '%' + @Column_Name + '%' )  
    And ( T.Name Like '%' + @Table_Name + '%' )

1 votes

C'est la seule qui n'explose pas sur mon serveur (probablement à cause de noms de bases de données bizarres avec des espaces pour des trucs propriétaires).

0 votes

C'est très bien, mais existe-t-il un moyen d'obtenir le nom de la base de données, similaire à l'obtention du SCHEMA_NAME ?

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X