2009-08-24 27 views
11

テーブル名になるパラメータを使用するストアドプロシージャを書きたいと思います。動的SQL(パラメータとしてテーブル名を渡す)

例えば:

@tablename << Parameter 

SELECT * FROM @tablename 

どのようにこれは可能ですか?

私はこれを書いた:

set ANSI_NULLS ON 
set QUOTED_IDENTIFIER ON 
GO 

ALTER PROCEDURE [dbo].[GetAllInterviewQuestions] 
@Alias varchar = null 
AS 
BEGIN 
Exec('Select * FROM Table as ' @Alias) 
END 

をしかし、それは@alias近くに不正な構文を言います。

答えて

18

まず、文字列から '+'を省略しました。物事のこの方法では、理想からかけ離れているが、あなたは

DECLARE @SQL varchar(250) 
SELECT @SQL = 'SELECT * FROM ' + QuoteName(@Alias) 
Exec(@SQL) 

を行うことができます私は強くしかし、あなたがこれを行う方法を再考することをお勧めしたいです。動的SQLを生成すると、SQLインジェクションの脆弱性が発生することが多く、SQL Server(および他のDB)がクエリを処理する最適な方法を見つけるのが難しくなります。テーブルを返すことができるストアドプロシージャを使用している場合、ストアドプロシージャの利点はほとんどありません。最初はストアドプロシージャであり、最適化の方法ではあまり効果がありません。セキュリティ上のメリットも大きく奪われています。

1

多くの場合、テーブル名をパラメータ化すると、データベーススキーマを再考する必要があることが示されます。あなたが多くの異なるテーブルからインタビューの質問を引き出しているのであれば、異なるテーブルがどのような形であっても質問を区別する列を持つテーブルを作成する方が良いでしょう。

0

SQLのほとんどの実装では、パラメータを使用してテーブル名、カラム名、カラム順などの構造要素を指定することはできません。動的SQLを使用してクエリのこれらの側面をパラメータ化する必要があります。

はしかし、SQLを見て、あなたが持っている:

Exec('SELECT * FROM Table AS ' @Alias) 

確かに、これはコードのみを今までに「表」と呼ばれるテーブルから選択することを意味するだろう、とあなたは@aliasを連結する必要がありますそれを - と、多くのSQL方言では、連結は「||」で示されます。

Exec('SELECT * FROM Table AS ' || @Alias) 

これはおそらくまだあなたがやりたいことはありません - しかし、プロシージャが作成されたとき、それは(構文エラーを生成しないことがあります実行時にエラーが発生する可能性があります)。

4

あなたはこのようにそれを行う必要があるでしょう: exec('select * from '[email protected]+' where...')

しかし、あなたは完全にSQLインジェクション攻撃などのリスクを、理解しておいてください。一般に、DBがうまく設計されていれば、このようなものを使う必要はありません。

+2

予約語であるテーブル名やテーブル名にスペースを入れることを避けるために、テーブル名を角括弧で囲む方が少し良いです。 exec( 'select * from [' + @ tablename + '] where ...') –

3

はあなたが@alias前+を忘れてしまったので、

Exec('SELECT * FROM ' + @tableName) 

はまた、あなたが得るエラーがあることを意味しないでください。

関連する問題