我想列出具有特定名称的所有数据库,并且特定表中的列具有特定类型,如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'
如何链接这两个请求? 换句话说,如何获得第一次请求的每个结果的第二次请求的结果?
答案 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