Как использовать OPENXML для загрузки данных XML в существующую таблицу SQL? - PullRequest
1 голос
/ 06 августа 2010

Я новичок в OPENXML.Но я пытаюсь загрузить файл .XML в таблицу SQL, которую я создал для этого.Я не получаю никаких ошибок с этим кодом, но он также не вставляет никаких записей.Это таблица, которую я создал в SQL Server 2008:

CREATE TABLE HOMEROOM(
HOMEROOM_TEACHER INT,
HOMEROOM_NUMBER INT,
ENTITY_ID INT)

И это код T-SQL, который я пытаюсь выполнить:

DECLARE @idoc int
DECLARE @xmlDocument varchar(MAX)
DECLARE @Status INT

SET @xmlDocument ='
<xml xmlns:s="uuid:BDC6E3F0-6DA3-11d1-A2A3-00AA00C14882" xmlns:dt="uuid:C2F41010-65B3-11d1-A29F-00AA00C14882" xmlns:rs="urn:schemas-microsoft-com:rowset" xmlns:z="#RowsetSchema">
  <s:Schema id="RowsetSchema">
    <s:ElementType name="row" content="eltOnly">
      <s:AttributeType name="c0" rs:name="HOMEROOM-TEACHER" rs:number="1" rs:nullable="true">
        <s:datatype dt:type="int" dt:maxLength="4" rs:precision="10" rs:fixedlength="true" />
      </s:AttributeType>
      <s:AttributeType name="c1" rs:name="HOMEROOM-NUMBER" rs:number="2">
        <s:datatype dt:type="string" rs:dbtype="str" dt:maxLength="10" rs:maybenull="false" />
      </s:AttributeType>
      <s:AttributeType name="c2" rs:name="ENTITY-ID" rs:number="3">
        <s:datatype dt:type="string" rs:dbtype="str" dt:maxLength="10" rs:maybenull="false" />
      </s:AttributeType>
      <s:extends type="rs:rowbase" />
    </s:ElementType>
  </s:Schema>
  <rs:data>
    <z:row c0="22943" c1="101" c2="055" />
    <z:row c0="22929" c1="102" c2="055" />
    <z:row c0="22854" c1="103" c2="055" />
    <z:row c0="22908" c1="104" c2="055" />
    <z:row c0="22881" c1="105" c2="055" />
<z:row c0="22926" c1="Gym2" c2="055" />
<z:row c0="22935" c1="Gym3" c2="055" />
  </rs:data>
</xml>
'
EXEC @Status = sp_xml_preparedocument @idoc OUTPUT, @xmlDocument
SELECT 'sp_xml_preparedocument status=',@Status

select *
FROM   OPENXML (@idoc, '/xml/',1)
         WITH    (
            HOMEROOM_TEACHER          INT    '@C0'
            ,HOMEROOM_NUMBER          VARCHAR(10) '@C1'
            ,ENTITY_ID          VARCHAR(10) 'C2'
                )

--sp_xml_removedocument @idoc

SELECT * FROM HOMEROOM

Но после этого яполучить 0 строк, добавленных в HOMEROOM.Любые предложения о том, как сделать это?Gym2 для типа данных int.

Ответы [ 3 ]

1 голос
/ 06 августа 2010

Прежде всего, я бы использовал SQL Server 2005 XQuery поверх OPENXML - мне кажется, проще и чище.

Во-вторых, не совсем ясно, какие элементы или атрибуты вы хотите извлечь ....

В-третьих: вы игнорируете пространства имен XML, поэтому ничего не работает ... они существуют по какой-то причине, и вам нужно обратить на них внимание!

Итак, я попробовал что-то вроде этого:

DECLARE @input XML = '.....'

;WITH XMLNAMESPACES('urn:schemas-microsoft-com:rowset' AS rs, '#RowsetSchema' AS z)
SELECT
    Nodes.Attr.value('(@c0)[1]', 'INT') AS 'HomeroomTeacher',
    Nodes.Attr.value('(@c1)[1]', 'INT') AS 'HomeroomNumber',
    Nodes.Attr.value('(@c2)[1]', 'INT') AS 'EntityID'
FROM
    @input.nodes('/xml/rs:data/z:row') AS NOdes(Attr)

и я получаю вывод:

HomeroomTeacher  HomeroomNumber  EntityID
   22943              101           55
   22929              102           55
   22854              103           55
   22908              104           55
   22881              105           55

Возможно, это еще не совсем то, что вы ищете, но это может быть отправной точкой!

Я сделал:

  • определяет соответствующие пространства имен XML rs: и z:, используя WITH XMLNAMESPACES construct
  • создал «псевдотаблица» Nodes с псевдостолбцом Attr, который в основном имеет одну строку XML для каждого элемента, соответствующего этому выражению XPath
  • Затем я вхожу в эти строки в псевдотаблице и могу извлечь нужные мне биты информации
1 голос
/ 06 августа 2010

Попробуйте это:

EXEC @Status = sp_xml_preparedocument @idoc OUTPUT, 
@xmlDocument, '<xml xmlns:s="uuid:BDC6E3F0-6DA3-11d1-A2A3-00AA00C14882" 
       xmlns:dt="uuid:C2F41010-65B3-11d1-A29F-00AA00C14882" 
       xmlns:rs="urn:schemas-microsoft-com:rowset" 
       xmlns:z="#RowsetSchema"/>' 
SELECT 'sp_xml_preparedocument status=',@Status 

SELECT * 
FROM OPENXML (@idoc, '/xml/rs:data/z:row',1) 
WITH ( 
   HOMEROOM_TEACHER   INT    '@c0' 
  ,HOMEROOM_NUMBER    INT    '@c1' 
  ,ENTITY_ID          INT    '@c2' 
) 

Я сделал несколько вещей:

  1. Добавил объявление пространства имен в качестве третьего параметра в sp_xml_preparedocument.
  2. Изменил xpathраздел от '/ xml /' до '/ xml / rs: data / z: row', чтобы указать правильную позицию и пространства имен в документе XML
  3. Изменены переменные @C в нижний регистр (@c)

Результаты были следующими:

HOMEROOM_TEACHER HOMEROOM_NUMBER ENTITY_ID
---------------- --------------- -----------
22943            101             55
22929            102             55
22854            103             55
22908            104             55
22881            105             55

К вашему сведению, информацию об использовании OPENXML с пространствами имен можно найти здесь .

0 голосов
/ 06 августа 2010

Вам нужно добавить INSERT INTO HOMEROOM (HOMEROOM_TEACHER, HOMEROOM_NUMBER, ENTITY_ID) над вашим выбором и изменить ваш SELECT на SELECT HOMEROOM_TEACHER ,HOMEROOM_NUMBER ,ENTITY_ID.

...