How to find column names for all tables in all databases in SQL Server
我想在所有数据库的所有表中查找所有列名。有什么问题可以帮我解决吗?数据库是Microsoft SQL Server 2000。
试试这个:
1 2 3 4 5 | 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 |
对于生成的列名,这将是:
1 2 3 4 5 6 | 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 |
号
或者更详细地说:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | 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 |
编辑下面是获取所有数据库中所有列的基本示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 | 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) |
。
编辑SQL Server 2000版本
1 2 3 4 5 6 7 8 9 10 11 12 13 | 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) |
编辑根据一些评论,这里有一个使用
1 2 3 4 5 6 | 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 2 3 | SELECT * FROM information_schema.columns WHERE column_name = 'My_Column' |
。
在此查询之前,必须使用
为什么不使用
1 | SELECT * FROM INFORMATION_SCHEMA.COLUMNS |
。
你可以用特定的
1 | SELECT * FROM DBNAME.INFORMATION_SCHEMA.COLUMNS |
更好的方法
1 2 3 4 5 6 7 8 9 10 | sp_MSForEachDB @command1='USE ?; SELECT Table_Catalog ,Table_Schema ,Table_Name ,Column_Name ,Data_Type ,Character_Maximum_Length FROM INFORMATION_SCHEMA.COLUMNS WHERE COLUMN_NAME like ''%ColumnNameHere%''' |
号
1 2 3 | SELECT sys.columns.name AS ColumnName, TABLES.name AS TableName FROM sys.columns JOIN sys.tables ON sys.columns.object_id = TABLES.object_id |
。
我刚刚意识到,下面的查询将为您提供数据库中表中的所有列名(SQL Server 2017)
1 2 | SELECT DISTINCT NAME FROM SYSCOLUMNS ORDER BY Name |
号
或者简单地说
1 | SELECT Name FROM SYSCOLUMNS |
号
如果你不在乎重复的名字。
另一种选择是从
1 2 | SELECT DISTINCT column_name FROM INFORMATION_SCHEMA.COLUMNS ORDER BY column_name |
号
通常情况下,更有趣的是让表名以及下面的查询中的columnname Ant这样做。
1 2 3 4 | SELECT Object_Name(Id) AS TableName, Name AS ColumnName FROM SysColumns |
号
结果是
1 2 3 4 5 6 | TableName ColumnName 0 Table1 column11 1 Table1 Column12 2 Table2 Column21 3 Table2 Column22 4 Table3 Column23 |
尝试下面的查询
1 2 3 4 5 6 7 8 9 10 | DECLARE @Query VARCHAR(MAX) SELECT @Query = 'USE ? SELECT ''?'' AS DataBaseName, sys.columns.name AS ColumnName , sys.tables.name AS TableName , schema_name (sys.tables.schema_Id) AS schemaName FROM sys.columns JOIN sys.tables ON sys.columns.object_id = sys.tables.object_id WHERE sys.columns.name = ''id'' ' EXEC SP_MSFOREACHDB @Query |
号
提供包含来自所有数据库的ID列的表的列表。
一些小的改进
->以前的答案没有显示所有结果
->可以通过设置列名变量来筛选列名
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | DECLARE @columnname nvarchar(150) SET @columnname='' DECLARE @SQL VARCHAR(MAX) SET @SQL='' SELECT @SQL=@SQL+'UNION select '''+d.name+'.''+sh.name+''.''+o.name COLLATE SQL_Latin1_General_CP1_CI_AS as name,c.name COLLATE SQL_Latin1_General_CP1_CI_AS as columnname,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 where c.name like ''%'+@columnname+'%'' and sh.name<>''sys'' ' FROM sys.databases d SELECT @SQL=RIGHT(@SQL,LEN(@SQL)-5)+'order by 1,3' --print @SQL EXEC (@SQL) |
号
感谢所有的帖子和评论,有些很好,但有些更好。
第一个大脚本很好,因为它提供了所需的内容。最快和最详细的建议是从信息中选择"schema.columns."。
我需要找到几乎相同名称和几个数据库的所有出错列。Sooo,我做了我的两个版本(见下文)…下面的两个脚本中的任何一个都可以工作并在几秒钟内交付货物。
在这个链接的其他文章中,假设第一个代码示例可以成功地用于每个数据库,这对我来说是不可取的。这是因为信息在特定的数据库中,"fedb"的简单使用不会产生正确的结果,它只是不提供访问权。因此,我使用一个光标来收集数据库,忽略那些离线的数据库,在本例中,这是一个实用程序脚本,很好地使用了它们。
总之,我读了每个人的帖子,把所有的文章更正了起来,并写出了另外两篇精彩的文章。我在下面列出了这两个文件,并将脚本文件放在OneDrive.com的公用文件夹中,您可以通过以下链接访问:http://1drv.ms/1vr8ynx
享受吧!汉克·弗里曼
高级-SQL Server DBA-数据架构师分开试试……
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 | --------------------------- --- 1st example (works) --- --------------------------- DECLARE @DBName sysname ,@SQL_String1 nvarchar(4000) ,@SQL_String2 nvarchar(4000) ,@ColumnName nvarchar(200) --set @ColumnName = 'Course_ID' -------- Like Trick -------- -- IF you want to add more the @ColumnName so it looks like Course_ID,CourseID -- then add an additional pairing of +''','''+'NewColumnSearchIDValue' ---------------------------- SET @ColumnName = 'Course_ID' +''','''+'CourseID' --select @ColumnName ----- DECLARE @Column_Info TABLE ( [DatabaseName] nvarchar(128) NULL, [ColumnName] sysname NULL, [ObjectName] nvarchar(257) NOT NULL, [ObjectType] nvarchar(60) NULL, [DataType] nvarchar(151) NULL, [NULLABLE] VARCHAR(8) NOT NULL, [MiscInfo] nvarchar(MAX) NOT NULL ) -------------- BEGIN SET @SQL_String2 = 'SELECT DB_NAME() as ''DatabaseName'', 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 into ##Temp_Column_Info 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 -------------------------------------------- --- DBA - Hank 12-Feb-2015 added this specific where statement -- where Upper(s.name) like ''COURSE%'' -- where Upper(s.name) in (''' + @ColumnName + ''') -- where Upper(s.name) in (''cycle_Code'') -- ORDER BY sh.name+''.''+o.name,s.column_id order by 1,2' -------------------- DECLARE DB_cursor CURSOR FOR SELECT name FROM sys.databases --select * from sys.databases WHERE STATE = 0 -- and Name not IN ('master','msdb','tempdb','model','DocxPress') AND Name NOT IN ('msdb','tempdb','model','DocxPress') OPEN DB_cursor Fetch NEXT FROM DB_cursor INTO @DBName While @@FETCH_STATUS = 0 BEGIN --select @DBName as '@DBName'; SET @SQL_String1 = 'USE [' + @DBName + ']' SET @SQL_String1 = @SQL_String1 + @SQL_String2 EXEC sp_executesql @SQL_String1; -- INSERT INTO @Column_Info SELECT * FROM ##Temp_Column_Info; DROP TABLE ##Temp_Column_Info; Fetch NEXT FROM DB_cursor INTO @DBName END CLOSE DB_cursor; Deallocate DB_cursor; --- SELECT * FROM @Column_Info ORDER BY 2,3 ---------------------------- END --------------------------- Below IS the SECOND script.. --------------------------- --- 2nd example (works) --- --------------------------- -- This is by far the best/fastes of the lot for what it delivers. --Select * into dbo.hanktst From Master.INFORMATION_SCHEMA.COLUMNS --FileID: SCRIPT_Get_Column_info_(INFORMATION_SCHEMA.COLUMNS).sql ---------------------------------------- --FileID: SCRIPT_Get_Column_info_(INFORMATION_SCHEMA.COLUMNS).sql -- Utility to find all columns in all databases or find specific with a like statement -- Look at this line to find a: --> set @SQL_String2 = ' select * into ##Temp_Column_Info.... ---------------------------------------- --- SET NOCOUNT ON BEGIN DECLARE @hanktst TABLE ( [TABLE_CATALOG] NVARCHAR(128) NULL ,[TABLE_SCHEMA] NVARCHAR(128) NULL ,[TABLE_NAME] sysname NOT NULL ,[COLUMN_NAME] sysname NULL ,[ORDINAL_POSITION] INT NULL ,[COLUMN_DEFAULT] NVARCHAR(4000) NULL ,[IS_NULLABLE] VARCHAR(3) NULL ,[DATA_TYPE] NVARCHAR(128) NULL ,[CHARACTER_MAXIMUM_LENGTH] INT NULL ,[CHARACTER_OCTET_LENGTH] INT NULL ,[NUMERIC_PRECISION] TINYINT NULL ,[NUMERIC_PRECISION_RADIX] SMALLINT NULL ,[NUMERIC_SCALE] INT NULL ,[DATETIME_PRECISION] SMALLINT NULL ,[CHARACTER_SET_CATALOG] sysname NULL ,[CHARACTER_SET_SCHEMA] sysname NULL ,[CHARACTER_SET_NAME] sysname NULL ,[COLLATION_CATALOG] sysname NULL ,[COLLATION_SCHEMA] sysname NULL ,[COLLATION_NAME] sysname NULL ,[DOMAIN_CATALOG] sysname NULL ,[DOMAIN_SCHEMA] sysname NULL ,[DOMAIN_NAME] sysname NULL ) DECLARE @DBName sysname ,@SQL_String2 nvarchar(4000) ,@TempRowCnt VARCHAR(20) ,@Dbug bit = 0 DECLARE DB_cursor CURSOR FOR SELECT name FROM sys.databases WHERE STATE = 0 -- and Name not IN ('master','msdb','tempdb','model','DocxPress') AND Name NOT IN ('msdb','tempdb','model','DocxPress') OPEN DB_cursor Fetch NEXT FROM DB_cursor INTO @DBName While @@FETCH_STATUS = 0 BEGIN SET @SQL_String2 = ' select * into ##Temp_Column_Info from [' + @DBName + '].INFORMATION_SCHEMA.COLUMNS where UPPER(Column_Name) like ''COURSE%'' ;' IF @Dbug = 1 SELECT @SQL_String2 AS '@SQL_String2'; EXEC sp_executesql @SQL_String2; INSERT INTO @hanktst SELECT * FROM ##Temp_Column_Info; DROP TABLE ##Temp_Column_Info; Fetch NEXT FROM DB_cursor INTO @DBName END SELECT * FROM @hanktst ORDER BY 4,2,3 CLOSE DB_cursor; Deallocate DB_cursor; SET @TempRowCnt = (SELECT CAST(COUNT(1) AS VARCHAR(10)) FROM @hanktst ) Print ('Rows found: '+ @TempRowCnt +' end ...') END -------- |
号
通常,我会尽我所能避免使用光标,但下面的查询将为您提供所需的一切:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | --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 |
号
我在主查询中添加了一个WHERE子句(如"%%",b.table_name如"%%",b.column_name如"%%"),这样您可以根据需要搜索特定的表和/或列。
用户@km说出最佳答案。
我用这个:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | 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 + '%' ) |
。
对KM的解决方案进行了细微的改进,适用于像我这样的在DB服务器上享受排序乐趣的人……
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | DECLARE @SQL VARCHAR(MAX)='' SELECT @SQL=@SQL+'UNION select '''+d.name +'.''+sh.name+''.''+o.name COLLATE SQL_Latin1_General_CP1_CI_AS,c.name COLLATE SQL_Latin1_General_CP1_CI_AS,c.column_id from '+d.name +'.sys.columns c inner join sys.objects o on c.object_id=o.object_id INNER JOIN 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) |
(仍然生活在希望我们能找到一种方法做到这一点,并将其包装成一个视图。)