2011-07-29 2 views
6

は、私たちは、私がこのようなクエリがあるとしましょう:テーブル名を文字列として指定する方法はありますか?

SELECT * FROM 
(
    SELECT * FROM 
    (
    SELECT * FROM DB.dbo.Table 
) 
    INNER JOIN DB.dbo.Table ON ... 

私は手動でどこでも文字列を変更することにより、別のテーブルでこのクエリを複数回実行しています。私は、次のことを宣言してみました:

DECLARE @tablename AS VARCHAR(255) 
SET @tablename = 'DB.dbo.Table' 

しかし、それは私がそれを使用することができます前に、テーブル変数として@tablename宣言する必要というエラーが私を投げるので、これは動作するようには思えません。テーブル名をテンプレート化するにはどうすれば可能ですか?Intellisenseはまだ動作しますか?あなたはこのようなEXEC文でそれをラップすることができます

答えて

7

declare @my_tablename nvarchar(100) = 'mytable'; 
exec(' 
SELECT * FROM 
(
    SELECT * FROM 
    (
    SELECT * FROM ' + @my_tablename + ' 
) 
    INNER JOIN ' + @my_tablename + ' ON ...' 
); 

しかし、いや、インテリセンスはそのシナリオでは動作しません。

出力がどのようになっているかが分かっている場合は、結果を保持する一時テーブルを宣言して、EXECなしでアクセスすることができます。あなたは一時テーブルにインテリセンスを持っています。例えば

--this must match whatever your SELECT is going to return 
    CREATE TABLE #results(
    FIELD1 INT 
    ,FIELD2 NVARCHAR(100) 
    ,FIELD3 BIT 
    ); 

EXEC(' 
    INSERT INTO #results(field1,field2,field3) 
    SELECT FIELD1,FIELD2,FIELD3 FROM ' + @my_tablename 
); 

select * from #results --you will have intellisense on #results 
3

あなたは、動的SQLを使用しています。あなたは非常に多くのネストされたSELECT文を必要とするが、それはようなものになるだろう、なぜ:

DECLARE @sql NVARCHAR(MAX) = N'SELECT ... FROM ' + @tablename + '...'; 
EXEC sp_executeSQL @sql; 

しかしSQLインジェクションの点に注意してください。また、IntelliSenseにはオブジェクト名の文字列を解析する機能がありません(またはオブジェクト名が編集されていることを知ることさえありません)。

+0

+1。依存性注入について言及していただきありがとうございます。 –

4

いいえ、C#プログラムの関数名を文字列として指定することはできません。 T-SQLコンパイルでは、正確なアクセスプランが用意されています。これは、クエリを満たすためにどのインデックスを開いて使用するかを意味します。 C#では、メソッドとして '文字列'を呼び出すコードを生成することが不可能であるように、 '文字列'の計画を立てることは不可能です。

declare @sql NVARCHAR(MAX) = N'SELECT ... FROM ' + 
    quotename(@dbname) + N'.' + quotename(@schema) + N'.' + quotename(@table) + 
    N' WHERE ...'; 
exec sp_executesql @sql; 

...ちょうどC#で使用すると、動的なランタイム呼び出しを行うためにリフレクションを使用するように:

ソリューションは、動的SQLです。

詳細はThe Curse and Blessings of Dynamic SQLを参照してください。

PS。 @tablenameをコンポーネントに分割し、QUOTENAMEを使用することは絶対必要であり、agaisnt SQL Injectionを守ります。あなたのために分割を行うにはPARSENAMEを使用してください。

+0

リンクの+1は、動的SQLを扱うときには常に最初に実行されます – Lamak

関連する問題