編集:おっと、私は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の不足を回避するためにhereとhereからいくつかのスニペットを引っ張られ、全体で情報を共有しません:
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
それを実行するにはデータベース。
だから、あなたはただDB名が欲しいですか?あなたの 'USE'の後の行に' IF OBJECT_ID( '' dbo.Items '')のIS NOT NULL'を追加し、2番目のSELECTを失う –
ああ、['sp_msforeachdb'は恐ろしいアイデアです。](https:// www.mssqltips.com/sqlservertip/2201/making-a-more-reliable-and-flexible-spmsforeachdb/)。 –
チップのおかげで@AaronBertrand –