Tsql 如何使用OPENXML将XML数据加载到现有的SQL表中?

Tsql 如何使用OPENXML将XML数据加载到现有的SQL表中?,tsql,openxml,Tsql,Openxml,我是OPENXML的新手。但我正在尝试将一个.XML文件加载到为此创建的SQL表中。我没有收到此代码的任何错误,但它也不会插入任何记录。这是我在2008 SQL Server中创建的表: CREATE TABLE HOMEROOM( HOMEROOM_TEACHER INT, HOMEROOM_NUMBER INT, ENTITY_ID INT) 这是我试图执行的T-SQL代码: DECLARE @idoc int DECLARE @xmlDocument varchar(MAX) DECLA

我是OPENXML的新手。但我正在尝试将一个.XML文件加载到为此创建的SQL表中。我没有收到此代码的任何错误,但它也不会插入任何记录。这是我在2008 SQL Server中创建的表:

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
DECLARE@idoc int
声明@xmlDocument varchar(最大值)
声明@Status INT
SET@xmlDocument=
'
EXEC@Status=sp_xml_preparedocument@idoc OUTPUT,@xmlDocument
选择“sp_xml_preparedocument status=”、@status
挑选*
来自OPENXML(@idoc,“/xml/”,1)
与(
家庭教师INT'@C0'
,教室编号VARCHAR(10)“@C1”
,实体ID VARCHAR(10)‘C2’
)
--sp_xml_removedocument@idoc
从HOMEROOM中选择*
但在我执行此操作之后,我会将0行添加到HOMEROOM。有什么建议可以让这项工作顺利进行吗

当我执行上述操作时,我得到一个错误: (1行受影响) Msg 245,16级,状态1,第627行
将nvarchar值“Gym2”转换为数据类型int时,转换失败。

您需要在您的选择上方添加
插入到家庭(家庭教师、家庭编号、实体ID)
,并将选择更改为
选择家庭教师、家庭编号、实体ID

首先,我会在OPENXML上使用SQL Server 2005 XQuery—对我来说似乎更简单、更干净

第二,不完全清楚要提取哪些元素或属性

第三:您忽略了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
这可能还不是你想要的,但它可能是一个起点

我做到了:

  • 使用带有XMLNAMESPACES的
    构造定义相关的XML名称空间
    rs:
    z:
  • 创建了一个“伪表”
    Nodes
    ,其中包含一个伪列
    Attr
    ,基本上每个元素都有一行XML来匹配该XPath表达式
  • 然后我进入伪表中的那些行,我能够提取出我需要的相关信息
试试这个:

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' 
) 

仅供参考,可以找到有关将OPENXML与名称空间结合使用的信息。

我喜欢这个解决方案!是的,你抓住了我所有的错误。现在这对我有用了。非常感谢你!你太棒了!嘿,我错了。它没有将任何这些数据添加到我的表中,因为事实证明我有两个varchar字段。所以我得到了上面的错误。我也用新数据更新了我的描述。你能再看一看吗?没关系,我只是用瓦查尔重新制作了这张桌子。谢谢,谢谢,马克,我没有试过你的解决方案,但看起来效果不错。我有以属性为中心的数据。以前我不懂如何声明名称空间,但现在我懂了。你知道在服务器上哪个更高效吗?XQuery还是OPENXML?对不起,Marc,我弄错了。我有两个VARCHAR值和一个INT。我已经用错误消息更新了我的描述。你能再看一看吗?没关系,我只是用瓦查尔重新制作了这张桌子。谢谢
HOMEROOM_TEACHER HOMEROOM_NUMBER ENTITY_ID
---------------- --------------- -----------
22943            101             55
22929            102             55
22854            103             55
22908            104             55
22881            105             55