2009-07-16 22 views
3

私はXPathの一部としてパラメータ値を使用するSQLサーバにパラメータ化されたクエリを書き込もうとしていますが、期待通りに動作しないようです。ここに私のサンプルは次のとおりです。SQLサーバーでパラメータ化されたXPathクエリを作成するにはどうすればよいですか?

create table ##example (xmltest xml) 

declare @LanguagePath varchar(75) 

set @LanguagePath = '(/languages/language[@id="en-US"])[1]' 
insert into ##example 
values ('<languages> 
      <language id="en-US">c</language> 
      <language id="es-ES">c</language> 
     </languages>') 

insert into ##example 
values ('<languages> 
      <language id="en-US">b</language> 
      <language id="es-ES">b</language> 
     </languages>') 


insert into ##example 
values ('<languages> 
      <language id="en-US">a</language> 
      <language id="es-ES">a</language> 
     </languages>') 

--This is a working statement: 
--select * from ##example 
--order by xmltest.value('(/languages/language[@id="en-US"])[1]', 'varchar') 


declare @SQL nvarchar(4000) 
set @SQL = ' 
select * from ##example 
order by xmltest.value(@LanguagePath1, ''varchar'') 
' 

exec sp_executesql @SQL, N'@LanguagePath1 varchar(75)', @LanguagePath1 = @LanguagePath; 

drop table ##example 

このエラーのコード結果: 引数xmlデータ型のメソッドの1「の値が」文字列リテラルでなければなりません。

どのように私はこれを動作させることができますか?私はxpathクエリをSQLインジェクションから安全にしようとしたいと思います。

答えて

8

@LanguagePath1の代わりにsql:variable("@LanguagePath1")を使用する必要があります。それについてもっと読むhere。動的xpathがうまくいくかどうかわかりません:)しかし、xmltest.value('(/languages/language[@id=sql:variable("@languageCode")])[1]のようなものはうまくいくはずです。

+0

甘いありがとう。それはまさに私が探していたものでした。 –

+0

Saulius、あなたのソリューションはなぜ機能するのですか? http://goo.gl/pI4Ap – ekkis

0

条件全体が動的に指定される場合はどうなりますか?

@clause = xmltest.value('(/languages/language[@id="en-US"])[1]', 'varchar')=1 

select * from ##example 
where @clause 
+1

where句をパラメータとして渡すことができるので、これはうまくいかないと思います。全体を文字列に変換して@clauseを連結すると動作しますが、それは実際には文字列全体を入力する以外のパラメータ化されたクエリではないので、 SQLインジェクションを回避しようとするときのパラメータSauliusのやり方はうまくいった。 –

関連する問題