2

クエリ関数と値関数を使用して、xml データである列を持つテーブルをクエリしようとしています。通常の文字列リテラルを使用する場合は問題ありませんが、それをストアド プロシージャに入れて変数を使用しようとすると機能しません。

正しいデータ型を使用していないと思いますが、検索を行った後、クエリ関数が必要とするデータ型がわかりません。

例: テーブルの内容

| Id | xmldata                         |
| 1  | <data><node>value</node></data> |

今、選択クエリを使用して

select id
from table
where xmldata.query('/data/node').value('.', 'VARCHAR(50)') = 'value'

必要なデータを取得します。しかし、これをストアドプロシージャで使用し、パラメーターを使用して 、エラーが発生@xpath varchar(100)したときにそれをクエリメソッドに渡すとxmldata.query(@xpath)

The argument 1 of the xml data type method "query" must be a string literal.

varchar(100) は正しくないと思いますが、MSSQL を満足させるにはどのデータ型を使用できますか?


更新:わかりました。どうやら「そのように」クエリメソッドにパラメーターを渡すことはできませんが、ローカル名と組み合わせて sql:variable を使用して、その一部を処理することはできます。したがって、たとえば、これは機能します

declare @xpath VarChar(100)
set @xpath='node'
select objectData.query('/data/*[local-name() = sql:variable("@xpath")]')
                 .value('.', 'varchar(100)') as xmldata
from table

列 xmldata で値が選択されます。しかし (!) ルート ノードがクエリ関数の最初の値である必要があります。以下は動作しませ

declare @xpath VarChar(100)
set @xpath='/data/node'
select objectData.query('*[local-name() = sql:variable("@xpath")]')
                 .value('.', 'varchar(100)') as xmldata
from table

クエリ パスが変数まで「上に移動」されていることに注意してください。私は私の調査を続けます..

4

1 に答える 1

3

Aliteralは a の反対ですvariable。このメッセージは、変数を の最初の引数として渡すことができないことを意味しますquery

これを回避する 1 つの方法は、動的 SQL です。

declare @sql varchar(max)
set @sql = 'select id from table where xmldata.query(''' + @path + 
    ''').value(''.'', ''VARCHAR(50)'') = ''value'''
exec @sql

ご覧のとおり、動的 SQL は非常に読みやすいコードにはなりません。私は確かに代替案を調査します。

local-name()編集:ノード名の作品のあなたの提案。

declare @nodename varchar(max)
set @nodename = 'node'
...
where   xmldata.query('//*[local-name()=sql:variable("@nodename")]')
            .value('.', 'varchar(50)') = 'value'

パスに相当するものはないようです。

于 2012-03-21T13:48:31.753 に答える