4

私の質問に対する答えは、私には理解できない単純なものになると思います。シナリオは次のとおりです。

SQL Server 2008 R2を使用しています。テーブルには、データが次の形式で保存されるXML列があります。

<Person>
    <firstName>John</firstName>
    <lastName>Lewis</lastName>
</Person>

Personノードには、要素名が異なる可能性のある子ノードをいくつでも含めることができます(事前にはわかりません)。すべてのノードの値を属性として持つXMLを返すクエリを探しています。

したがって、上記のXMLの出力は次のようになります。

<Person firstName="John" lastName="Lewis"/>

上記の出力を取得するためのクエリは考えられません。次のようなクエリは使いたくない

Select 
      PersonColumn.value('(/Person/firstName)[1]', 'varchar(100)') AS '@firstName'
    , PersonColumn.value('(/Person/lastName)[1]', 'varchar(100)') AS '@lastName'
FROM MyTable
WHERE MyTable.MyPrimaryKey=1
FOR XML PATH('Person'), TYPE

ノードの下にどのノードがあるのか​​わからないのでPerson

4

2 に答える 2

2

私はこれをやろうとしました

select
    PersonColumn.query('
        element Person {
            for $i in /Person/*
            return attribute {local-name($i)} {string($i)}
        }
    ')
from MyTable

しかし、動的属性名を使用することは不可能であることが判明しました

XQuery [MyTable.PersonColumn.query()]: Only constant expressions are supported for the name expression of computed element and attribute constructors.: select PersonColumn.query(' element Person { for $i in /Person/* return attribute {local-name($i)} {string($i)} } ') from MyTable

これまでにできる最善のことは

select 
    cast(
        '<Person ' + 
        (
            select
                PersonColumn.query('
                for $i in /Person/*
                return concat(local-name($i), "=""", data($i), """")
                ').value('.', 'nvarchar(max)')
            for xml path('')
        ) + '/>'
    as xml)
from MyTable

これを行うことも可能です

select
    cast(
        '<Person ' + 
        PersonColumn.query('
            for $i in /Person/*
            return concat(local-name($i), "=""", data($i), """")
        ').value('.', 'nvarchar(max)') +
        '/>'
      as xml)
from MyTable

< >ただし、データに次のような文字が含まれている場合は機能しません。

于 2012-11-21T17:13:26.363 に答える
0

基本的PIVOTに、Personノードの直接の子である要素の名前を指定したいようです。これをすべてTSQLで行う必要がある場合は、クエリを動的に作成する必要があります。インスピレーションを得るために、T-SQLでXML列の属性をピボットする方法を参照してください。その場合、ピボット式も属性値でしたが、あなたの場合は要素名です。

私は明白なことを指摘する義務があると感じています-そのようなソリューションはパフォーマンスが悪い可能性があり、結果を消費するのは難しく(列名とカウントが不明であるため)、コンテキストによってはSQLインジェクション攻撃を受けやすい可能性があります。

于 2012-11-21T18:10:11.013 に答える