2017-04-03 6 views
1

ように私は、SQLサーバーで動的なクエリを使用している:私は@conditionは、任意の値を持っているかどうか、私の結果を得ることができたsp_executesqlを

このことにより
declare @sql nvarchar (1000),@condition nvarchar(100)=''; 
set @sql=N'select * from tablename where (0=0)'[email protected]+''; 
exec(@sql) 

。 しかし、私はsp_executesqlがクエリプランの再利用を促進するので、execが良いことを知りました。

だから、私は、sp_executesqlを `と私のクエリを試してみました

set @sql =N'select * from dbo.testclient where (0=0) @condition' 
exec sp_executesql @sql,N'@condition nvarchar(100)',@condition 

しかし

Incorrect syntax near '@condition'. 

私の問題は、私は上記のクエリは、sp_executesqlどこで動作するように作ることができる方法であるとして、それはエラーで失敗しましたパラメータ@conditionは条件または空白( '')となり、何が間違っているのでしょうか。

+0

動的SQLは危険です。おそらく、あなたはそれなしであなたが望むものを手に入れる方法を見つけようとするべきでしょう。 –

+1

これはまだSQLインジェクション攻撃に対するオープンな扉です。ユーザが 'column = 'value';ドロップテーブルtablename; - 'の状態に入ると、どうなるでしょうか? –

+0

@ZoharPeled最初にこの問題を指摘してくれてありがとうございました。私たちは実際にクエリのパラメータを作成しています。次に、同じ結果を得るために複数の条件を書くことを避けたかったのです。 – vikscool

答えて

0

sp_executesqlで@conditionなどの変数を使用すると、SQL文字列の変数を変数の内容で置き換えるだけではありません。

何が起こるかは、変数が指定された値にバインドされており、SQL文が変更されていないことです。

これは、クエリプランの再利用を利用したい場合は、変数を使用する完全なSQL文を作成する必要があることを意味します。例えば

SET @byIDsql = 'select * from tableName where (0=0) and Id = @Id' 
SET @byNameSQL = 'select * from tableName where (0=0) and FirstName = @FirstName' 

その後、あなたは@Idと@firstNameの値を指定し、クエリプランの再利用を取得するためにsp_executesqlを使用することができます。

exec sp_executesql @byIDsql, N'@ID INT', 15 
+0

私は実際に複数のクエリを書くことを避けようとしていました。 – vikscool

+0

さて、それは面倒です。クエリを生成することはできますが、それ以上の作業が必要です。 SQLインジェクションから安全を守りたい場合、および/またはクエリプランの再利用を最大限にしたい場合は、回避するのは難しいです。 –

+0

Erland Sommarskogのこの巨大なブログ記事を読むことを強くお勧めします。http://www.sommarskog.se/dynamic_sql.html –

0

テストされたコード、

 DECLARE @Sql nvarchar(MAX)='',         
     @paramlist nvarchar(4000),   
@id int=3 
set @paramlist = N' @id1 int' 
set @Sql='select * from test where [email protected]' 

exec sp_executesql @Sql,@paramlist,@id 
select @Sql 
+0

@PeterHenell、私は実行プランをテストせずにsp_executesqlの構文を与えました。クエリプランはdofferent rasonのために再利用できないかもしれません。今、私のスクリプトをチェックしてください。 – KumarHarsh

+0

@PeterHenell、今すぐチェックする – KumarHarsh

+0

うん、そうする方法。 –

関連する問題