简体   繁体   中英

Parse xml in TSQL: how to loop throw child nodes?

I'm developing a stored procedure for SQL Server 2012 express and developer edition with latest service pack.

I want to parse an XML and insert its data into a table.

This is my XML :

<Parent ParentId="1" ParentCodeId="ASDAS121" ParentLevelId="1">
    <Child ParentId="1" ChildCode="GF342" ChildLevel="0" Position="1"/>
    <Child ParentId="1" ChildCode="G1A42" ChildLevel="0" Position="2"/>
    <Child ParentId="1" ChildCode="GFS42" ChildLevel="0" Position="3"/>
    <Child ParentId="1" ChildCode="GF242" ChildLevel="0" Position="4"/>
                        <!-- N childs more -->
    <Child ParentId="1" ChildCode="DF342" ChildLevel="0" Position="N"/>
</Parent>

This is my stored procedure code:

CREATE PROCEDURE [dbo].[InsertXML]
    @xmlString NVARCHAR(MAX)
AS
BEGIN
    DECLARE @xml xml

    set nocount on

    -- Convert string data into XML.
    SET @xml = @XmlString

    DECLARE @hDoc int

    --Prepare input values as an XML document
    exec sp_xml_preparedocument @hDoc OUTPUT, @xmlData

    INSERT INTO [dbo].[AGGREGATIONS]
        SELECT ID_AGGREGATION, CODE, CODE_LEVEL
          FROM OPENXML(@hdoc, '/Parent', 1) WITH (ID_AGGREGATION bigint '@ParentId', CODE nvarchar(20) '@ParentCodeId', CODE_LEVEL tinyint '@ParentLevelId')

-- I don't know how to continue

    INSERT INTO [dbo].[AGGREGATION_CHILDS]
        SELECT ID_AGGREGATION, CODE, CODE_LEVEL
          FROM OPENXML(@hdoc, '/Parent/Child', 1) WITH (ID_AGGREGATION bigint 'ParentId', CODE nvarchar(20) '@ChildCodeId', CODE_LEVEL tinyint '@ChildLevelId', POSITION int  '@Position')

How can I loop through all children? I don't know how many children will be.

have a look at this link transforming xml and try this:

SQL Fiddle

MS SQL Server 2012 Schema Setup :

Query 1 :

DECLARE @xml AS XML

SET @xml =
'<Parent ParentId="1" ParentCodeId="ASDAS121" ParentLevelId="1">
    <Child ParentId="1" ChildCode="GF342" ChildLevel="0" Position="1"/>
    <Child ParentId="1" ChildCode="G1A42" ChildLevel="0" Position="2"/>
    <Child ParentId="1" ChildCode="GFS42" ChildLevel="0" Position="3"/>
    <Child ParentId="1" ChildCode="GF242" ChildLevel="0" Position="4"/>
    <Child ParentId="1" ChildCode="DF342" ChildLevel="0" Position="N"/>
</Parent>'


SELECT T.c.value('@ParentId', 'int') as ParentId,
       T.c.value('@ChildCode', 'char(5)') As ChildCode,
       T.c.value('@ChildLevel', 'int') As ChildLevel,
       T.c.value('@Position', 'char(1)') As Position
FROM   @xml.nodes('/Parent/Child') T(c)

Results :

| PARENTID | CHILDCODE | CHILDLEVEL | POSITION |
|----------|-----------|------------|----------|
|        1 |     GF342 |          0 |        1 |
|        1 |     G1A42 |          0 |        2 |
|        1 |     GFS42 |          0 |        3 |
|        1 |     GF242 |          0 |        4 |
|        1 |     DF342 |          0 |        N |

Use CURSOR :

DECLARE @ParentId   INT
       ,@ChildCode  VARCHAR(10)
       ,@ChildLevel INT
       ,@Position   VARCHAR(10);

DECLARE C CURSOR FOR
SELECT X_ParentId   AS ParentId
      ,X_ChildCode  AS ChildCode
      ,X_ChildLevel AS ChildLevel
      ,X_Position   AS Position
FROM OPENXML (@hdoc, '/Parent/Child', 1)
WITH (X_ParentId   INT         '@ParentId'
     ,X_ChildCode  VARCHAR(10) '@ChildCode'
     ,X_ChildLevel INT         '@ChildLevel'
     ,X_Position   VARCHAR(10) '@Position');

OPEN C;
FETCH NEXT FROM C INTO @ParentId, @ChildCode, @ChildLevel, @Position;

WHILE @@FETCH_STATUS = 0
BEGIN
    -- Place your INSERT here
    SELECT @ParentId, @ChildCode, @ChildLevel, @Position;

    FETCH NEXT FROM C INTO @ParentId, @ChildCode, @ChildLevel, @Position;
END

CLOSE C;
DEALLOCATE C;

OR just:

-- Place your INSERT here
SELECT X_ParentId   AS ParentId
      ,X_ChildCode  AS ChildCode
      ,X_ChildLevel AS ChildLevel
      ,X_Position   AS Position
FROM OPENXML (@hdoc, '/Parent/Child', 1)
WITH (X_ParentId   INT         '@ParentId'
     ,X_ChildCode  VARCHAR(10) '@ChildCode'
     ,X_ChildLevel INT         '@ChildLevel'
     ,X_Position   VARCHAR(10) '@Position');

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM