2016-07-21 3 views
0
Running Microsoft SQL Server 11.0.3128 
on Windows Server 2012 R2 Essentials 

指定された変数(SQLスクリプトを呼び出すバッチファイル)に基づいて特定のデータベースの名前を返そうとしています。Transact SQL(mssql)SELECTの "search"からDBの名前を返します

For each database in instance 
     Look in the current database 
       Return databasename if variable is found in column 

私がこれまでに取り組んできたコードは次のようになります:

プロセスは、私の頭の中で、次のようになります

EXEC dbo.sp_MSForeachdb ' 
USE [?];   
SELECT DB_NAME() AS DBName 
     UNION SELECT 
      ColumnName 
      FROM dbo.Items 
      WHERE ColumnName =''variable'' 
' 

問題は、このリターンですそれは "変数"を含まないデータベースの "null"値を返し、 "ColumnName"を含まないデータベースのメッセージを作成するので、私が望む以上に多くのことをします。

しかし、私は他のものなしで私が望む特定の情報を得る方法を理解していないようです。初めてのポスターで、私が質問を改善できるかどうか教えてください。

ありがとうございました!

+0

だから、あなたはただDB名が欲しいですか?あなたの 'USE'の後の行に' IF OBJECT_ID( '' dbo.Items '')のIS NOT NULL'を追加し、2番目のSELECTを失う –

+0

ああ、['sp_msforeachdb'は恐ろしいアイデアです。](https:// www.mssqltips.com/sqlservertip/2201/making-a-more-reliable-and-flexible-spmsforeachdb/)。 –

+0

チップのおかげで@AaronBertrand –

答えて

0

編集:おっと、私はmysqlではなくmysqlで作業していました。以下の原則は引き続き有効です。構文をちょっと調整して、ユーザー関数を使用してgroup_concatを置き換える必要があります。これは、mssqlにはその機能がないためです。

ここにはsp_MSForeachdbのないアプローチがあります。最初にパラメータをサニタイズする必要があることに注意してください。

delimiter $$ 

create procedure FindDatabases 
(
    in varName varchar(2000), 
    in tableName varchar(2000), 
    in columnName varchar(2000) 
) 
begin 
    declare selectQuery varchar(2000); 

    select group_concat(
       concat('select ''', 
        table_schema, 
        ''' as DatabaseName from ', 
        table_schema, 
        '.', 
        tableName, 
        ' where ', 
        columnName, 
        ' = ''', 
        varName, 
        '''') 
       separator ' union ') as DatabaseNames 
    from information_schema.tables 
    where table_name = tableName 
    into @selectQuery; 

    prepare preparedSql from @selectQuery; 
    execute preparedSql; 
    deallocate prepare preparedSql; 

end $$ 
delimiter ; 

使用例:

call FindDatabases ('variable', 'Items', 'ColumnName') 

この手順は、供給されたテーブル名と一致するテーブル名と、各データベースのSQLクエリを生成すると共に組合して、その後、それらを実行します。ユニオン内の各クエリは、そのデータベース内の指定されたテーブルに、指定された変数名に一致する値を含む指定された名前と一致する列がある場合、そのデータベース名を返します。これらの要件に一致するデータベースのみがクエリ結果に表示されるので、結果にNULL値がないか心配する必要はありません。

追加編集:約束どおり、ここではsqlserverのバージョンです。

exec FindDatabases 'someVar', 'Items', 'ColumnName' 

私は臆面もなく、ローカルデータベースの情報を持つGROUP_CONCAT機能とのSQLServerのINFORMATION_SCHEMAの不足を回避するためにherehereからいくつかのスニペットを引っ張られ、全体で情報を共有しません:

create procedure FindDatabases 
(
    @varName varchar(2000), 
    @tableName varchar(2000), 
    @columnName varchar(2000) 
) 
as 
begin 
    declare @selectQuery nvarchar(2000) 


    -- first, get a list of database names that contain the specified table 
    IF OBJECT_ID('tempdb.dbo.#db_temp') IS NOT NULL 
     DROP TABLE #db_temp 

    CREATE TABLE #db_temp (DatabaseName SYSNAME) 

    SELECT @selectQuery = (
     SELECT ' 
      USE [' + d.name + ']; 

      INSERT INTO #db_temp (DatabaseName) 
      SELECT DB_NAME() as DatabaseName 
      WHERE EXISTS(
       SELECT 1 
       FROM sys.objects 
       WHERE [object_id] = OBJECT_ID(''' + @tableName + ''') 
        AND [type] = ''U'' 
      )' 
     FROM sys.databases d 
     WHERE d.name NOT IN ('master', 'tempdb', 'model', 'msdb') 
      AND d.state_desc != 'OFFLINE' 
     FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)') 

    EXEC sys.sp_executesql @selectQuery 

    -- use something like mysql's group_concat function to turn that list into a bunch of union all select statements 
    select 
     @selectQuery = 
     (
      SELECT LEFT(database_names , LEN(database_names) - 10) AS  database_names 
      FROM #db_temp AS extern 
     CROSS APPLY 
      (
       SELECT 'select ''' + DatabaseName + ''' as  DatabaseName from ' + DatabaseName + '.dbo.' + @tableName + 
       ' where ' + @columnName + ' = ''' + @varName + '''' +  ' union all ' 
       FROM #db_temp AS intern 
       FOR XML PATH('') 
      ) pre_trimmed (database_names) 
      GROUP BY database_names 
     )  

    drop table #db_temp 

    -- run those select statements 
    exec sp_executesql @selectQuery 
end 

それを実行するにはデータベース。

+0

あなたはmssqlのために働く何かを持つことは起こりませんか? 私はSSMSで動作するようにしようとしてきましたが、構文はわかりません。 –

+0

私は今は時間がありませんが、私はあなたのためにSQL Serverのバージョンを一緒に置くために今夜の時間を作ろうとします。私は自分の答えを更新するつもりです。 –

+0

mssql版の最新の編集を見てください。 –

関連する問題