SQL 2008: получение строк с объединением в поле XML? - PullRequest
2 голосов
/ 01 августа 2010

Не уверен, что этот вопрос приводит к некоторой низкой производительности в будущем, но, кажется, по крайней мере, сейчас он чувствует себя "лучше" ..

Я пытаюсь сделать следующее:

У меня есть таблица CONTACTS, в которой, помимо прочего, есть поле первичного ключа с именем memberID

У меня также есть поле XML, которое содержит идентификаторы ваших друзей (например) .. например:

  <root><id>2</id><id>6</id><id>14</id></root>

Итак, что я пытаюсь сделать с помощью сохраненного процесса, передать ваш идентификатор участника и вернуть всю информацию о ваших друзьях, например:

  select name, address, age, dob from contacts
  where id... xml join stuff...

Предыдущий способ, которым я пользовалсяон работал (ну вроде!) выделил все узлы XML (/ root / id) во временную таблицу, а затем сделал соединение из этой временной таблицы с таблицей контактов, чтобы получить поля контактов ...

Любая помощь очень ценится ... просто немного перегружена примерами .query .nodes, и, конечно, возможно, это лучший способ сделать это ...

СПАСИБО В СЛУЧАЕ!

<- EDIT -> Я получил что-то работает, но выглядит какзаявление SQL Франкенштейна!По сути, мне нужно было получить идентификаторы контактов друзей из поля XML и заполнить их временной таблицей, например:

Declare @contactIDtable TABLE (ID int)
INSERT INTO @contactIDtable (ID)
        SELECT CONVERT(INT,CAST(T2.memID.query('.') AS varchar(100))) AS friendsID
        FROM dbo.members
        CROSS APPLY memberContacts.nodes('/root/id/text()') AS T2(memID)

Но чёрт!вещь преобразования / приведения выглядит серьезной ... поскольку мне нужно получить INT для следующего бита, который является фактическим соединением, чтобы вернуть контактные данные следующим образом:

SELECT memberID, memberName, memberAddress1
    FROM members
    INNER JOIN @contactIDtable cid
    ON members.memberID = cid.ID
    ORDER BY memberName

RESULT ... Хорошо, это работает.в моем случае в моем поле XML memberContacts было 3 узла (в данном случае идентификаторы), а приведенный выше запрос вернул 3 строки данных (memberID, memberName, memberAddress1) ...

Весь смысл этогоКонечно, нужно было попытаться сохранить создание таблицы с множеством соединений, то есть списка всех идентификаторов моих друзей ... просто не уверен, что вышесказанное действительно делает это быстрее и проще ...

Больше идей / более эффективных способов попробоватьсделать это ???

Ответы [ 2 ]

13 голосов
/ 01 августа 2010

Синтаксис SQL Server для чтения XML является одним из наименее интуитивно понятных. В идеале вы бы хотели:

select   f.name
from     friends f
join     @xml x
on       x.id = f.id

Вместо этого SQL Server требует, чтобы вы все прописали. Чтобы превратить переменную или столбец XML в «набор строк», необходимо указать точный путь и придумать два псевдонима:

@xml.nodes('/root/id') as table_alias(column_alias)

Теперь вы должны объяснить SQL Server, как превратить <id>1</id> в int:

table_alias.column_alias.value('.', 'int')

Итак, вы можете понять, почему большинство людей предпочитают декодировать XML на стороне клиента:)

Полный пример:

declare @friends table (id int, name varchar(50))
insert @friends (id, name)
          select  2, 'Locke Lamorra'
union all select  6, 'Calo Sanzo'
union all select 10, 'Galdo Sanzo'
union all select 14, 'Jean Tannen'

declare @xml xml
set @xml = ' <root><id>2</id><id>6</id><id>14</id></root>'

select  f.name
from    @xml.nodes('/root/id') as table_alias(column_alias)
join    @friends f
on      table_alias.column_alias.value('.', 'int') = f.id
2 голосов
/ 01 августа 2010

Чтобы получить содержимое XML в виде строк из «псевдотаблицы», вам нужно использовать .nodes() в столбце XML - что-то вроде:

DECLARE @xmlfield XML
SET @xmlfield = '<root><id>2</id><id>6</id><id>14</id></root>'

SELECT
   ROOT.ID.value('(.)[1]', 'int')
FROM
   @xmfield.nodes('/root/id') AS ROOT(ID)

SELECT
    (list of fields)
FROM
    dbo.Contacts c
INNER JOIN
    @xmlfield.nodes('/root/id') AS ROOT(ID) ON c.ID = Root.ID.value('(.)[1]', 'INT')  

По сути, .nodes() определяет псевдотаблица ROOT с одним столбцом ID, который будет содержать по одной строке для каждого узла в выражении XPath, а .value() выбирает из этого конкретного значения Фрагмент XML.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...