Импорт XML в SQL Server - PullRequest
6 голосов
/ 27 марта 2009

Я могу найти множество примеров того, как импортировать определенные типы XML-данных в SQL Server 2005. Но мне дали данные в следующем формате (повторение «строки» и «ячейки» с идентификаторами вместо тегов было по имени и т.д .:

<?xml version="1.0"?> <rows>
    <row id='1'>
        <cell id='category'>Simple</cell>
        <cell id='query'>summary</cell>
        <cell id='clientsfound'>6</cell>
        <cell id='eligibleclients'>11</cell>
        <cell id='percentage'>55</cell>
        <cell id='days'>0</cell>
    </row>

    <row id='2'>
        <cell id='category'>Complex</cell>
        <cell id='query'>details</cell>
        <cell id='clientsfound'>4</cell>
        <cell id='eligibleclients'>6</cell>
        <cell id='percentage'>67</cell>
        <cell id='days'>5</cell>
    </row>

    ...
     </rows>

В идеале я хочу загрузить его в таблицу, такую ​​как:

CREATE TABLE [dbo].[QueryResults](
    [UserString] [varchar](50) NULL,
    [ImportStamp] [timestamp] NULL,
    [RowID] [int] NULL,
    [Category] [nchar](10) NULL,
    [Query] [nchar](10) NULL,
    [ClientsFound] [int] NULL,
    [EligibleClients] [int] NULL,
    [Percentage] [int] NULL,
    [Days] [int] NULL
)

Может ли кто-нибудь дать мне пример или указать на онлайн-учебник?

Ответы [ 2 ]

9 голосов
/ 27 марта 2009

Внутри xml должно быть "" не ", нет?

В любом случае, вы можете самостоятельно анализировать тип данных XML. Откровенно опасно sp_xml_preparedocument из-за накладных расходов на использование памяти.

DECLARE @foo XML;

SET @foo = N'<?xml version="1.0"?>
<rows>
    <row id="1">
        <cell id="category">Simple</cell>
        <cell id="query">summary</cell>
        <cell id="clientsfound">6</cell>
        <cell id="eligibleclients">11</cell>
        <cell id="percentage">55</cell>
        <cell id="days">0</cell>
    </row>
    <row id="2">
        <cell id="category">Complex</cell>
        <cell id="query">details</cell>
        <cell id="clientsfound">4</cell>
        <cell id="eligibleclients">6</cell>
        <cell id="percentage">67</cell>
        <cell id="days">5</cell>
    </row>
</rows>';

SELECT
    x.item.value('@id', 'int') AS RowID,
    y.item.value('(./cell[@id="category"])[1]', 'nchar(10)') AS category,
    y.item.value('(./cell[@id="query"])[1]', 'nchar(10)') AS query,
    y.item.value('(./cell[@id="clientsfound"])[1]', 'int') AS clientsfound,
    y.item.value('(./cell[@id="eligibleclients"])[1]', 'int') AS eligibleclients,
    y.item.value('(./cell[@id="percentage"])[1]', 'int') AS percentage,
    y.item.value('(./cell[@id="days"])[1]', 'int') AS days
FROM
    @foo.nodes('/rows/row') x(item)
    CROSS APPLY
    x.item.nodes('.') AS y(item)
1 голос
/ 27 марта 2009

Вы можете сделать это, используя OPENXML и XQUERY.

DECLARE @XMLdoc XML
DECLARE @idoc int
SELECT @XMLdoc = '<?xml version="1.0"?>
  <rows>
    <row id="1">
        <cell id="category">Simple</cell>
        <cell id="query">summary</cell>
        <cell id="clientsfound">6</cell>
        <cell id="eligibleclients">11</cell>
        <cell id="percentage">55</cell>
        <cell id="days">0</cell>
    </row>
    <row id="2">
        <cell id="category">Complex</cell>
        <cell id="query">details</cell>
        <cell id="clientsfound">4</cell>
        <cell id="eligibleclients">6</cell>
        <cell id="percentage">67</cell>
        <cell id="days">5</cell>
    </row>
  </rows>'


-- Create an internal representation of the XML document.
EXEC sp_xml_preparedocument @idoc OUTPUT, @XMLDoc

INSERT INTO QueryResults (RowID,Category,Query,ClientsFound,EligibleClients,Percentage,Days)
SELECT  id,
        overflow.value('(/row/cell[@id="category"])[1]', 'nchar(10)'),
        overflow.value('(/row/cell[@id="query"])[1]', 'nchar(10)'),
        overflow.value('(/row/cell[@id="clientsfound"])[1]', 'int'),
        overflow.value('(/row/cell[@id="eligibleclients"])[1]', 'int'),
        overflow.value('(/row/cell[@id="percentage"])[1]', 'int'),
        overflow.value('(/row/cell[@id="days"])[1]', 'int')
FROM OPENXML (@idoc, '/rows/row',10)
WITH (id int '@id',
    overflow xml '@mp:xmltext' --the row xml node
)

-- Release resources allocated for the XML document.
EXEC sp_xml_removedocument @idoc

SELECT * FROM QueryResults

Результаты:

UserString  ImportStamp        RowID  Category  Query    ClientsFound EligibleClients Percentage  Days
----------- ------------------ ------ --------- -------- ------------ --------------- ----------- ----
NULL        0x000000000000C1CA 1      Simple    summary  6            11              55          0
NULL        0x000000000000C1CB 2      Complex   details  4            6               67          5

Я не уверен, что вы хотите заполнить в 'UserString', но вы можете разобраться с этим позже.

Надеюсь, что это подходящее решение для вашего вопроса.

- Извините, gbn, вы, вероятно, правы по поводу sp_xml_preparedocument. Я просто использовал этот подход из некоторых аналогичных хранимых процедур, которые были у нас в проекте, над которым мы работали с командой Microsoft SDC, поэтому решил, что это будет безопасно. Твой подход в любом случае, вероятно, чище.

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