2013-03-18 4 views
0

У меня есть таблица в SQL Server 2008 со следующей структурой:Выберите из XML с неизвестной структурой

id  = int 
numero = int 
datos = xml 
[other_misc_fields] 

Вы можете увидеть таблицу с некоторыми, например, данные по этому sql fiddle. Как вы можете видеть по ссылке, поле datos (data) - это XML. Этот XML не имеет известной структуры. Все, что я знаю, это то, что корень «lote» и что каждое поле имеет атрибут «title», который является «отображаемым именем» поля. Я хотел бы иметь возможность запросить что-то по этой линии

id | numero | display_name_field_1 | display_name_field_2 | display_name_field_3 
1 | 23 |  value_field_1 |  value_field_2 |  value_field_3 

Использование некоторых dynamic sql (от another so answer) Я могу получить значение из каждого узла, но я не могу понять, как переименовать его с помощью атрибут title:

select @SQL = 'select '+stuff(
    (
    select ',T.N.value('''+T.N.value('local-name(.)', 'sysname')+'[1]'', ''varchar(max)'') as '+T.N.value('local-name(.)', 'sysname') 
    from @XML.nodes('/*[local-name(.)=sql:variable("@KnownName")]/*') as T(N) 
    for xml path(''), type 
).value('.', 'nvarchar(max)'), 1, 1, '')+ 
    ' from @XML.nodes(''/*[local-name(.)=sql:variable("@KnownName")]'') as T(N) 

Где @KnownName "lote".

Как изменить этот запрос, чтобы поле переименовывало в атрибут @title этого узла? Или, альтернативно, есть ли лучший способ сделать это, чем динамический sql?

ответ

0

Оказывается, это было относительно легко сделать. Единственная проблема заключается в том, что имена столбцов не могут быть легко установлены на динамическое значение. Наконец, я решил разобраться с на стороне клиента XML, но это способ сделать что-то подобное тому, что я хотел, в случае, если кому-то интересно:

SELECT @SQL = 'select '+stuff(
     (
     SELECT ',T.N.value('''+T.N.value('local-name(.)', 'sysname')+'[1]'',''varchar(max)'') as '+ T.N.value('local-name(.)', 'sysname')+', T.N.value(''('+T.N.value('local-name(.)', 'sysname')+'/@title)[1]'+''',''varchar(max)'') as '+ T.N.value('local-name(.)', 'sysname')+'@title' 
     FROM @XML.nodes('/*[local-name(.)=sql:variable("@KnownName")]/*') AS T(N) 
     FOR xml path(''), TYPE 
    ).value('.', 'nvarchar(max)'), 1, 1, '')+ 
     ' from @XML.nodes(''/*[local-name(.)=sql:variable("@KnownName")]'') as T(N)' 

Вы можете видеть, что «в действии» в этом sqlfiddle : http://www.sqlfiddle.com/#!3/5408e/13/0

Смежные вопросы