4

我可以使用以下查询检索单个数据库

Select Table_catalog[Instance Name],
Table_name[Database Table],
Column_name[Column],
Data_type[Column Type] 
FROM information_schema.columns
where Data_type in ('varchar')
Order by Table_name,Data_type

但我想为服务器中的所有可用数据库列出它

  Declare @I int =1,@Qry nVarchar(1000),@DatabaseName nvarchar(100)
   Declare @TempTable Table
(
 Sno Int Identity(1,1),
  DatabaseName Varchar(100)
 )
    Insert into @TempTable
    Select name 
    from sys.databases
    where database_id>4
 Select * from @TempTable
    While(@i<=(Select max(sno) from @TempTable))
        Begin

            Select @DatabaseName=DatabaseName from @TempTable where sno=@i

                Select @DatabaseName
             set  @Qry='Use '+ @DatabaseName
             **exec sp_executesql @Qry**
             set  @Qry= '
                        Select  Table_catalog[Instance Name],
                                Table_name[Database Table],
                                Column_name[Column],
                                Data_type[Column Type] 
                                FROM information_schema.columns
                        where Data_type in (''datetime'',''date'',''time'',''smalldatetime'')
                        Order by Table_name,Data_type'
                 exec sp_executesql @Qry


        Set @i=@i+1
        End

它不起作用,因为使用数据库名称实际上并未更改数据库并重复当前使用的数据库的结果集..对此有任何建议,

4

3 回答 3

2

动态 SQL 始终在其自己的范围内执行,因此您的USE语句对第二个动态查询没有影响。

这应该对您有用(您的循环是不必要且尴尬的):

declare @Database sysname, @sql nvarchar(max)
declare Databases cursor local fast_forward
for select name from sys.databases where database_id > 4

open Databases
fetch next from Databases into @Database
while @@fetch_status = 0
begin
    set @sql =  'Select  
                    Table_catalog [Instance Name],
                    Table_name [Database Table],
                    Column_name [Column],
                    Data_type [Column Type] 
                FROM 
                    ' + quotename(@Database) + '.information_schema.columns
                where 
                    Data_type in (''datetime'',''date'',''time'',''smalldatetime'')
                Order by 
                    Table_name,
                    Data_type'

    exec sp_executesql @sql

    fetch next from Databases into @Database    
end
close Databases
deallocate Databases
于 2013-05-06T18:48:50.423 回答
1

您可以为此任务使用未记录的过程sp_MSforeachdb。刚刚在我的环境中进行了测试,它可以完美运行。

编辑

正如 Pondlife 指出的那样,三部分名称语法中缺少数据库部分。添加,现在可以正常工作。还添加了一个WHERE子句以避免在不必要的数据库中搜索master,msdb和.tempdbmodel

EXEC sp_MSforeachdb 
 'SELECT Table_catalog[Instance Name],
         Table_name[Database Table],
         Column_name[Column],
         Data_type[Column Type] 
    FROM ?.information_schema.columns
  WHERE Data_type in (''varchar'')
        AND ''?'' NOT IN (''master'',''msdb'',''tempdb'',''model'')
  ORDER BY Table_name,Data_type'

以防万一您想了解更多有关此无证程序的信息,请查看此处此处。请记住,未记录意味着 Microsoft 正式不支持此过程,因此它可能会更改,恕不另行通知。

AdventureWorks2008R2 数据库的示例结果:

 Instance Name        Database Table        Column              Column Type
AdventureWorks2008R2    Customer          AccountNumber            varchar
AdventureWorks2008R2    Password          PasswordHash             varchar
AdventureWorks2008R2    Password          PasswordSalt             varchar
AdventureWorks2008R2    SalesOrderHeader  CreditCardApprovalCode   varchar
于 2013-05-06T08:20:50.457 回答
0

感谢@pondlife 根据您的建议,我可以进行一些小的更改(从动态查询范围之外传递数据库名称)并且查询返回结果而不是我使用的游标 while 循环

      Declare @I int =1,@Qry nVarchar(1000),@DatabaseName nvarchar(100)
       Declare @TempTable Table
    (
     Sno Int Identity(1,1),
      DatabaseName Varchar(100)
     )
        Insert into @TempTable
        Select name 
        from sys.databases
        where database_id>4
     Select * from @TempTable
        While(@i<=(Select max(sno) from @TempTable))
            Begin

                Select @DatabaseName=DatabaseName from @TempTable where sno=@i

                     Select @DatabaseName
                 --set  @Qry='Use '+ @DatabaseName
                 -- exec sp_executesql @Qry**
                 set  @Qry= '
                            Select  Table_catalog[Instance Name],
                                    Table_name[Database Table],
                                    Column_name[Column],
                                    Data_type[Column Type] 
                                    FROM'+quotename(@DatabaseName)+ '. information_schema.columns
                            where Data_type in (''datetime'',''date'',''time'',''smalldatetime'')
                            Order by Table_name,Data_type'
                     exec sp_executesql @Qry


            Set @i=@i+1
            End
于 2013-05-08T12:00:07.717 回答