ここにはいくつかの解決策があります。
サンプルデータ:
declare @xml xml
set @xml =
'<EventSpecificData>
<Keyword>
<Word>myWord</Word>
<Occurences>1</Occurences>
<Context>context</Context>
</Keyword>
</EventSpecificData>'
は関係なく、両親の言葉という名前のノードから最初の値を取得します。深い検索を行い、local-name()
を使用してノード名を一致させるには、//
を使用します。
declare @Attribute varchar(max)
set @Attribute = 'Word'
select @xml.value('(//*[local-name() = sql:variable("@Attribute")])[1]', 'varchar(max)')
local-name()
を2つのレベルで使用して、別々の変数に親ノードの名前と属性を指定します。 nodes
のパラメータので
declare @Node varchar(max)
declare @Attribute varchar(max)
set @Attribute = 'Word'
set @Node = 'Keyword'
select @xml.value('(/EventSpecificData
/*[local-name() = sql:variable("@Node")]
/*[local-name() = sql:variable("@Attribute")])[1]', 'varchar(max)')
は、この問題を解決するために、動的SQLを使用するように誘うリテラル文字列でなければなりません。元の変数の内容と同じように見えるようにすることができます。
set @Attribute = 'Keyword/Word'
declare @SQL nvarchar(max)
set @SQL = 'select @xml.value(''(/EventSpecificData/'[email protected]+')[1]'', ''varchar(max)'')'
exec sp_executesql @SQL, N'@xml xml', @xml
しかし、あなたがこれを使用する場合は、SQLインジェクション攻撃に大きく開いていることに注意する必要があります。それはあなたに2つの結果セットを与えると、動的SQLを実行
set @Attribute = 'Keyword/Word)[1]'', ''varchar(max)'') select @@version --'
:一部のよこしまなエンドユーザーは次のようになります属性文字列を思い付くかもしれません。 select @@version
は、無害なコードを表示するためだけにありますが、そこにはもっと悪いものがあるかもしれません。
quotename()
を使用すると、SQLインジェクション攻撃を防ぐことができます。それは少なくとも私の試みを妨げるでしょう。
quotename()
を使用している最後のバージョンは安全ですか? Erland Sommarskog The Curse and Blessings of Dynamic SQLによってこの記事を見てください。
引用:
QUOTENAME()とquotestring()を持つので、
、我々はパラメータ化コマンドを持っているように、我々はSQLインジェクションに対するとして良好な保護 を持っているのですか?多分。私は quotestring()または quotestring()を通過するSQLを挿入する方法を知らない。それにもかかわらず、ユーザ入力を SQL文字列に補間していますが、パラメータ化されたコマンドの場合はそうではありません。
私はあなたがそうすることはできないと思っています.SQL XQueryはリテラル文字列で動作することが多く、ほとんどの場合、SQL変数で置き換えることはできません。 –