2016-04-27 23 views
0

それでは、この小さなバックステート:特定のテーブルを含む1つのデータベース名を変数に設定する方法はありますか?

私はsp_MSForEachDBストアドプロシージャを使用する私の仕事に頻繁に使用する長いクエリを持っています。クエリは一時テーブルを作成し、sys.tablesを検索し、データベースにT_Studyというテーブルがある場合、クエリを実行してこれらの結果を一時テーブルにプルします。

私が今しようとしているのは、別のデータベースの別のテーブルに参加することです。このデータベースのタイプは異なります。これらのデータベースはすべて、存在がT_BatchStoresで区別されます。 T_BatchStoresテーブルを持つすべてのデータベースにはテーブルdbo.T_TSyntaxもあり、これは私が参加する必要があるテーブルです。

本質的に、私はこのソフトウェアを含む任意のサーバー上で実行できるユニバーサルクエリを構築しようとしています。これらのほとんどのユニバーサルテーブルがありますが、データベース自体の名前は異なります。

それでは、私がやりたいことは以下を追加し、私の一時テーブルを移入し、私のクエリで、次のとおりです。

JOIN '[email protected]+'.dbo.T_TSyntax、その後、私のON句など、この参加は私の始まりと終わりの中に発生したことを覚えておいてくださいそれにはsp_MSforEachDbが実行されます。

T_BatchStoresテーブルを含むSQLインスタンス上の任意のデータベースのランダムに選択された名前のみにする必要があります。名前は関係ありません。実行するたびにクエリを変更したくないそれ。

DECLARE @MEDDBSET/SELECT @MEDDBをこれらの要件に対応させるにはどうすればよいですか?

また、一部の読者では、SYSNAMEをデータ型として使用することをお伝えしましたが、NVARCHARも動作することがわかりましたが、理想的なヒントがほしいと思います。

Iは、以下を試してみました:

DECLARE @MEDDB SYSNAME 

SET @MEDDB = (SELECT TOP 1 name FROM sys.databases WHERE EXISTS (SELECT name FROM sys.tables WHERE name = '''T_BATCHSTORES''')) 

SELECT @MEDDB 

しかし、これはNULL値と1行を返します。私はSQLの初心者ですから、どんな支援も大歓迎です!

注:現時点では、Microsoft SQL Server 2008および2012のみを使用しています。

ありがとうございます!

名前が実際の実際のテーブル構造と正確に同じにならないようにクエリを大幅に変更した後、ここでは私が使用しているクエリのスリムダウンバージョンです「のつもり:あなたが見ることができるように

/* Add or change variables as needed and comment back in WHERE statements in Insert section as needed. 
You do not need to delete any variables in this section, even if you do not need them. 
Simply comment in or out relevant data in the WHERE clause in Section 4. */ 


/* Section 1: Declaring variables. */ 

DECLARE @STUID NVARCHAR (65) 
DECLARE @IMUID NVARCHAR (200) 
DECLARE @ACCN NVARCHAR (100) 
DECLARE @MEDDB NVARCHAR (255) 

/* Section 2: Assigning values to variables such as an Image file's UID. */ 

SET @STUID = 'enterSTUID' 
SET @IMUID = 'enterIMUIDhere' 
SET @ACCN = 'enterACCNhere' 
SET @MEDDB = (SELECT TOP 1 name FROM sys.databases WHERE [name] LIKE '%med%' 
AND [name] NOT LIKE '%audit%') 


/* Section 3: Creating our temporary table to dump our results. */ 

IF OBJECT_ID('tempdb.dbo.#tempBatchResultsD6') IS NULL 

BEGIN 

CREATE TABLE #tempBatchResultsD6 

(
Database_Name VARCHAR (200), 
THING1 VARCHAR(100) NOT NULL, 
THING2 VARCHAR(200) NOT NULL, 
THING3 DATETIME NOT NULL, 
TSyntaxUID VARCHAR (66) NOT NULL, 
TSyntaxDesc VARCHAR (128) NOT NULL 
) 
END 

TRUNCATE TABLE #tempBatchResultsD6 


/* Section 4: Query that will be used to populate the contents of the temporary table created above. 
Utilizing the stored procedure "sp_MSForEachDb," this will search every database on the SQL instance. 
Here, we are limiting our results to only searching specific databases by only returning results from databases that have a "T_Studies" table. */ 

DECLARE @Command NVARCHAR(MAX) 

SET @Command = N'USE [?]; 
IF EXISTS (SELECT * FROM sys.tables WHERE [name] = ''T_Studies'') 
BEGIN 

INSERT #tempBatchResultsD6 

SELECT 

DB_Name() as Database_Name, 
THING1, 
THING2, 
THING3, 
TS.TSyntaxUID, 
TS.TSyntaxDesc 

FROM T_Studies ST WITH (nolock) 
    JOIN T_Patients PT WITH (nolock) ON ST.ST_PT_FOLDERID = PT.PT_FOLDERID 
    JOIN T_Series SE WITH (nolock) ON ST.ST_FOLDERID = SE.SE_ST_FOLDERID 
    JOIN T_Images IM WITH (nolock) ON SE.SE_FOLDERID = IM.IM_SE_FOLDERID 
    JOIN '[email protected]+'.dbo.T_TSyntaxes TS WITH (nolock) on IM.IM_TSyntaxID = TS.TSyntaxUID 

WHERE ST.STUID = '''[email protected]+''' 
--WHERE IM.IM_UID = '''[email protected]+''' 
--WHERE ST.ST_ACCNNO = '''[email protected]+''' 


END' 

EXEC sp_MSForEachDb @Command 


/* Section 5: Querying our temporary table to get our results. */ 

SELECT 

Database_Name, 
THING1, 
THING2, 
THING3, 
TSyntaxUID, 
TSyntaxDesc 

FROM #tempBatchResultsD6 

ORDER BY Database_Name 

、これは彼らにT_Studiesテーブルを持っているすべてのデータベースから引っ張ってくる巨大な一時テーブルです。それは実際のフォームでは巨大ですが、これは大幅に削減されています。

問題はセクション2で、「Med」という単語が含まれていて、「監査」という単語は含まれていない場合、@MEDDBを使用してランダムなデータベース名を選択しています。これは、すべてのサイトで一貫した名前付けを前提としているため、これらの名前が示唆されているものの、決して保証されるものではないため、問題があります。

整合性を保証するために、@MEDDB変数にWHERE [name]のような部分の代わりにT_BatchStoresテーブルを含むシステム上のANYデータベースの名前を入力しようとしています。

この新しい情報のアドバイスをいただければ幸いです!

+0

ソーステーブルの名前として変数を使用することはできません。しかし、あなたは 'IF-ELSE'ロジックを使うことができますし、動的SQLを使うこともできます。 – Shnugo

+0

明確にすることはできますか? SELECT @MEDDB =(sys.databasesから名前を選択してWHERE [name] LIKE '%med%' と[name] NOT LIKE '%audit%')を使用して変数を代替として設定することができます参加は次のようになります。 JOIN'[email protected]+'.dbo.T_TSyntax on ... これがどうして違うのか理解できません。 –

答えて

0

私はあなたの質問を完全に理解しているかどうかはわかりません。 しかし、すべてのデータベースをループしたい場合は、次のようなコードを使用できます。 "SELECT XXX"は "use '+ @ DB_Name +';"を使用してクエリになります。目的のデータベースに切り替えてクエリを実行します。

DECLARE @DB_Name varchar(100) 
DECLARE @Command nvarchar(max) 

DECLARE database_cursor CURSOR FOR 
SELECT name 
FROM MASTER.sys.sysdatabases 

OPEN database_cursor 

FETCH NEXT FROM database_cursor INTO @DB_Name 

WHILE @@FETCH_STATUS = 0 
BEGIN 


    set @Command = 
    ' 
     use ' + @DB_Name + '; 


     SELECT XXX 
    ' 


    EXEC sp_executesql @Command 

    FETCH NEXT FROM database_cursor INTO @DB_Name 

END 

CLOSE database_cursor 
DEALLOCATE database_cursor 
+0

私は全部を共有することができるまで、このクエリーが光っぽく混乱していることを認識しています。それはプロプライエタリなソフトウェアであり、テーブル名は普遍的なので、転記する前にすべてのテーブル名を変更しなければならないので、困ったことはありません。私と一緒に裸にして、私はすべてのことを投稿しますので、私は何をしようとしているのかがはっきりしています。レスポンスありがとう! –

+0

元の投稿を変更して、私が行っていることの修正版を追加しました。うまくいけば、これが役に立ちます。 –

0
DECLARE @MEDDB NVARCHAR(500) 
SET @MEDDB = 'SELECT TOP 1 name FROM sys.databases WHERE EXISTS (SELECT name FROM sys.tables WHERE name = ''T_BATCHSTORES'')' 
EXEC (@MEDDB) 

これは、動的SQLです。もちろん、結果は得られませんが、あなたのデータベースにはありません。それでも、これはあなたが「動的」こと、そして物事を変更するために変数を使用することができます:

DECLARE @MEDDB NVARCHAR(500) 
DECLARE @MEDDB2 NVARCHAR(100) = 'T_BATCHSTORES' 
SET @MEDDB = 'SELECT TOP 1 name FROM sys.databases WHERE EXISTS (SELECT name FROM sys.tables WHERE name = ''' + @MEDDB2 + ''')' 
EXEC (@MEDDB) 

私の推薦はあなたが望むものを示してシンプルなクエリを実行し、次にあなたが動的メソッドにそれらを構築することです。例えば

、私は今のAdventureWorksにいるので、私は行うことができます。

SELECT * FROM sys.databases 

これは私にここで利用可能なすべてのデータベースのリストが表示されます。

ので、多分私は

SELECT * FROM sys.databases WHERE name = 'AdventureWorks' 

にこれは私の結果は1行だけを与えることを展開します。だから、私が欲しいものだならば、私は動的な部分にそれを構築する:

DECLARE @MEDDB NVARCHAR(500) 
DECLARE @MEDDB2 NVARCHAR(100) = 'AdventureWorks' 
SET @MEDDB = 'SELECT * FROM sys.databases WHERE name =''' + @MEDDB2 + '''' 
EXEC (@MEDDB) 

それはちょうど、すべてあなたが探しているものによって決まります。私はいつも最初に必要なデータを見つけて、自分のクエリでそれを探す方法を見つけます。

+0

私は元の投稿を修正して、私が行っていることの修正版を追加しました。うまくいけば、これが役に立ちます。 –

関連する問題