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ステートメントは 2 番目の動的クエリには影響しません。

これはうまくいくはずです(ループは不要で厄介です):

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 が指摘したように、3 つの部分からなる名前の構文にデータベース部分がありませんでした。追加され、正しく機能するようになりました。、、などのWHERE不要なデータベースでの検索を回避する句も追加されました。mastermsdbtempdbmodel

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 に答える