如何列出特定表中的列具有特定类型的所有数据库?

时间:2017-06-21 12:36:20

标签: sql sql-server sql-server-2008 tsql

我想列出具有特定名称的所有数据库,并且特定表中的列具有特定类型,如DATE

获取具有特定名称的所有数据库:

SELECT [name] FROM [sysdatabases] WHERE [name] like 'myDBname_%'

获取所有列的特定类型:

select TABLE_CATALOG,TABLE_NAME, COLUMN_NAME, DATA_TYPE from myDBname_something.INFORMATION_SCHEMA.COLUMNS where TABLE_NAME = 'A_SPECIFIC_TABLE_NAME' 

如何链接这两个请求? 换句话说,如何获得第一次请求的每个结果的第二次请求的结果?

3 个答案:

答案 0 :(得分:2)

这是另一个不使用任何循环或游标的选项。我正在使用sys.database生成一个select语句。除非你有很多数据库,否则这对基于循环的解决方案的性能提升不会太大(如果有的话)。但我真的不喜欢游标和循环,这是构建动态sql以避免使用循环的一种相当简单的方法。

DECLARE @SQL NVARCHAR(MAX) = '' --need to initialize to empty string
    , @TableToFind sysname = 'YourTableName'

SELECT @SQL = @SQL + 'select TABLE_CATALOG, TABLE_NAME, COLUMN_NAME, DATA_TYPE from [' + db.name + '].INFORMATION_SCHEMA.COLUMNS  where TABLE_NAME = @TableToFind UNION ALL '
FROM sys.databases db
WHERE [state] = 0 --only gets online multi user databases
    AND name LIKE 'myDBname_%'

IF LEN(@SQL) > 0
BEGIN
    SELECT @SQL = LEFT(@SQL, LEN(@SQL) - 10)

    SELECT @SQL
    --uncomment the line below when you are comfortable the dynamic sql generated will function.
    --EXEC sp_executesql @SQL, N'@TableToFind sysname', @TableToFind = @TableToFind
END

答案 1 :(得分:1)

您可以将第二个查询作为系统过程中的参数sp_MSforeachdb

执行
EXECUTE master.sys.sp_MSforeachdb 'select TABLE_CATALOG,TABLE_NAME, COLUMN_NAME, DATA_TYPE from [?].INFORMATION_SCHEMA.COLUMNS where TABLE_NAME = ''A_SPECIFIC_TABLE_NAME'' '

如果只想过滤某些数据库,可以在TABLE_CATALOG列上向第二个查询添加其他过滤器。 TABLE_CATALOG是数据库名称。

如果要确保没有任何符合过滤器的列的数据库没有得到任何空结果,可以在查询之前放置IF EXISTS():

    EXECUTE master.sys.sp_MSforeachdb 'IF EXISTS(SELECT * from [?].INFORMATION_SCHEMA.COLUMNS where TABLE_NAME = ''A_SPECIFIC_TABLE_NAME'')
      select TABLE_CATALOG,TABLE_NAME, COLUMN_NAME, DATA_TYPE from [?].INFORMATION_SCHEMA.COLUMNS where TABLE_NAME = ''A_SPECIFIC_TABLE_NAME'' '

答案 2 :(得分:1)

在循环中使用动态sql来获取数据库名称或使用带有游标的动态sql

方法1:使用循环

Declare @ssql nvarchar(max),@DBName varchar(100),@rowcount int,@datatype varchar(10)

Create table #temp(id int identity(1,1) ,DBName varchar(100))

set @rowcount=0
set @datatype='int'

Insert into #temp(DBName)
SELECT [name]  FROM sys.[sysdatabases] WHERE [name] like 'MyDBName%'

while @rowcount<=1
begin

select @DBName=DBName from #temp where id=@rowcount

set @ssql=N'select TABLE_CATALOG,TABLE_NAME, COLUMN_NAME, DATA_TYPE from '+@DBName+'.INFORMATION_SCHEMA.COLUMNS
where TABLE_NAME in (select TABLE_NAME from '+@DBName+'.INFORMATION_SCHEMA.TABLES where TABLE_TYPE=''BASE TABLE'')
and DATA_TYPE='''+@datatype+''''

--select @ssql
exec sp_executesql @ssql

set @rowcount=@rowcount+1
end

方法2:光标

    Declare @ssql nvarchar(max),@DBName varchar(100),@rowcount int,@datatype varchar(10)
set @rowcount=0
set @datatype='int'
DECLARE cursorDBName CURSOR -- Declare cursor
FOR

SELECT [name]  FROM sys.[sysdatabases] WHERE [name] like 'MyDBName%'
OPEN cursorDBName -- open the cursor

FETCH NEXT FROM cursorDBName

 INTO @DBName

WHILE @@FETCH_STATUS = 0

BEGIN

 set @ssql=N'select TABLE_CATALOG,TABLE_NAME, COLUMN_NAME, DATA_TYPE from '+@DBName+'.INFORMATION_SCHEMA.COLUMNS
where TABLE_NAME in (select TABLE_NAME from '+@DBName+'.INFORMATION_SCHEMA.TABLES where TABLE_TYPE=''BASE TABLE'')
and DATA_TYPE='''+@datatype+''''

--select @ssql
exec sp_executesql @ssql

 FETCH NEXT FROM cursorDBName

   INTO @DBName
END

CLOSE cursorDBName -- close the cursor

DEALLOCATE cursorDBName