遍历数据库以获取INFORMATION_SCHEMA.COLUMNS

时间:2019-07-22 20:31:43

标签: sql sql-server

我有一个查询需要针对几个数据库运行:

SELECT TABLE_NAME, DATA_TYPE, COLUMN_NAME
    FROM INFORMATION_SCHEMA.COLUMNS
    WHERE COLUMN_NAME LIKE '%zip%';

是否存在迭代字符串列表并使用可以替换为USE语句的变量的想法?

my_dbs = ['test_db', 'live_db', 'dev_copy_db']

?? For each db in my_dbs: ??
    USE @db;
    SELECT TABLE_NAME, DATA_TYPE, COLUMN_NAME
        FROM INFORMATION_SCHEMA.COLUMNS
        WHERE COLUMN_NAME LIKE '%zip%';

还是有一种方法可以默认查看所有数据库,而不仅仅是master

3 个答案:

答案 0 :(得分:1)

您有两个选择:

  1. 未记录的系统存储过程 sp_MSforeachdb
  2. 基于sys.databases的游标

选项1: 未公开的系统存储过程 sp_MSforeachdb 使您可以在实例上的每个数据库上执行SQL语句:

declare @cmd varchar(500);
SET @cmd = 'USE ?; SELECT db_name();';
EXEC sp_MSforeachdb @cmd;

选项2: 您也可以使用sys.databases上的光标自己做类似的事情。像这样:

declare @cmd2 nvarchar(3000) = 'SELECT db_name();'
declare @cmd1 nvarchar(1000);
declare @cmd nvarchar(4000);
declare @db_name sysname;

declare dbs cursor fast_forward for 
select [name] from sys.databases 
where database_id > 4 
    and state = 0;

OPEN dbs;  

FETCH NEXT FROM dbs INTO @db_name;

WHILE (@@FETCH_STATUS = 0)
BEGIN  

    set @cmd1 = 'USE ' + @db_name + ';';
    set @cmd = @cmd1 + @cmd2;
    EXEC sp_executeSQL @cmd;
    FETCH NEXT FROM dbs INTO @db_name;
END 

CLOSE dbs;
DEALLOCATE dbs;

答案 1 :(得分:1)

对于sql-server,有'sp_MSforeachdb'。它将为您遍历服务器上的所有数据库。在其中,您可以使用动态sql并将数据泵入在其外部创建的临时表中。

create table #columnDatas (
    dbase_name sysname,
    table_name sysname,
    data_type sysname,
    column_name sysname
);

exec sp_MSforeachdb '

    use     [?]

    insert  #columnDatas 
    select  ''?'', table_name, data_type, column_name
    from    information_schema.columns
    where   column_name like ''%zip%'';

';

select * from #columnDatas

答案 2 :(得分:0)

动态地执行此操作当然是可能的。但是只有3个数据库,只需将其写出即可轻松进行编码和测试。这将在一次通过中检索您在这三个数据库上请求的信息。我还添加了数据库名称,以便您知道它的来源。

SELECT DatabaseName = 'test_db'
    , TABLE_NAME
    , DATA_TYPE
    , COLUMN_NAME
FROM test_db.INFORMATION_SCHEMA.COLUMNS
WHERE COLUMN_NAME LIKE '%zip%'

UNION ALL

SELECT DatabaseName = 'live_db'
    , TABLE_NAME
    , DATA_TYPE
    , COLUMN_NAME
FROM live_db.INFORMATION_SCHEMA.COLUMNS
WHERE COLUMN_NAME LIKE '%zip%'

UNION ALL

SELECT DatabaseName = 'dev_copy_db'
    , TABLE_NAME
    , DATA_TYPE
    , COLUMN_NAME
FROM dev_copy_db.INFORMATION_SCHEMA.COLUMNS
WHERE COLUMN_NAME LIKE '%zip%'

如果这是一个更具动态性的解决方案,它将需要一些动态sql来完成。这不是什么大问题,但是比3个数据库所付出的努力还要多。