简体   繁体   中英

SQL Server 2008 R2 Read through XML

I have a SQL query which can return n number of row. Each row has below mentioned XML. I want to read Rate Plan ID & insert into temp table.

<AvailRateUpdateRS xmlns="http://www.expediaconnect.com/EQC/AR/2007/02">
    <Success>
        <Warning code="7022">Inventory date 2016-12-30; Room Type ID 20583; Rate Plan ID 207782211; Inactive Rate Plan Updated Ref=[b44d7e4e-cf66-11e6-950b-e19b2852ebb6] </Warning>
        <Warning code="7022">Inventory date 2016-12-31; Room Type ID 20583; Rate Plan ID 207782211; Inactive Rate Plan Updated Ref=[b44d7e4e-cf66-11e6-950b-e19b2852ebb6] </Warnring>
        <Warning code="7022">Inventory date 2017-01-02; Room Type ID 20583; Rate Plan ID 203619420; Inactive Rate Plan Updated Ref=[b44d7e4e-cf66-11e6-950b-e19b2852ebb6] </Warning>
        <Warning code="7022">Inventory date 2017-01-03; Room Type ID 20583; Rate Plan ID 203619420; Inactive Rate Plan Updated Ref=[b44d7e4e-cf66-11e6-950b-e19b2852ebb6] </Warning>
        <Warning code="7022">Inventory date 2017-01-04; Room Type ID 20583; Rate Plan ID 203619420; Inactive Rate Plan Updated Ref=[b44d7e4e-cf66-11e6-950b-e19b2852ebb6] </Warning>
    </Success>
</AvailRateUpdateRS>

Thanks in advance.

Ï need to remove the xmlns to Expedia, but in your environment maybe you di not do it.

First, create a function to separate de columns of the warning

Create FUNCTION dbo.Wordparser
(
  @multiwordstring VARCHAR(max),
  @wordnumber      NUMERIC,
  @Separator char(1) 
)
returns VARCHAR(max)
AS
  BEGIN
      DECLARE @remainingstring VARCHAR(max)
      SET @remainingstring=@multiwordstring

      DECLARE @numberofwords NUMERIC
      SET @numberofwords=(LEN(@remainingstring) - LEN(REPLACE(@remainingstring, @Separator, '')) + 1)

      DECLARE @word VARCHAR(max)
      DECLARE @parsedwords TABLE
      (
         line NUMERIC IDENTITY(1, 1),
         word VARCHAR(max)
      )

      WHILE @numberofwords > 1
        BEGIN
            SET @word=LEFT(@remainingstring, CHARINDEX(@Separator, @remainingstring) - 1)

            INSERT INTO @parsedwords(word)
            SELECT @word

            SET @remainingstring= REPLACE(@remainingstring, @word + @Separator, '')
            SET @numberofwords=(LEN(@remainingstring) - LEN(REPLACE(@remainingstring, @Separator, '')) + 1)

            IF @numberofwords = 1
              BREAK

            ELSE
              CONTINUE
        END

      IF @numberofwords = 1
        SELECT @word = @remainingstring
      INSERT INTO @parsedwords(word)
      SELECT @word

      RETURN
        (SELECT RTRIM(LTRIM(word))
         FROM   @parsedwords
         WHERE  line = @wordnumber)

  END

GO

Second, use it:

declare @xml xml = REPLACE('<AvailRateUpdateRS xmlns="http://www.expediaconnect.com/EQC/AR/2007/02">
  <Success>
    <Warning code="7022">Inventory date 2016-12-30; Room Type ID 20583; Rate Plan ID 207782211; Inactive Rate Plan Updated Ref=[b44d7e4e-cf66-11e6-950b-e19b2852ebb6] </Warning>
    <Warning code="7022">Inventory date 2016-12-31; Room Type ID 20583; Rate Plan ID 207782211; Inactive Rate Plan Updated Ref=[b44d7e4e-cf66-11e6-950b-e19b2852ebb6] </Warning>
    <Warning code="7022">Inventory date 2017-01-02; Room Type ID 20583; Rate Plan ID 203619420; Inactive Rate Plan Updated Ref=[b44d7e4e-cf66-11e6-950b-e19b2852ebb6] </Warning>
    <Warning code="7022">Inventory date 2017-01-03; Room Type ID 20583; Rate Plan ID 203619420; Inactive Rate Plan Updated Ref=[b44d7e4e-cf66-11e6-950b-e19b2852ebb6] </Warning>
    <Warning code="7022">Inventory date 2017-01-04; Room Type ID 20583; Rate Plan ID 203619420; Inactive Rate Plan Updated Ref=[b44d7e4e-cf66-11e6-950b-e19b2852ebb6] </Warning>
  </Success>
</AvailRateUpdateRS>','xmlns="http://www.expediaconnect.com/EQC/AR/2007/02"','')


select DISTINCT
    dbo.Wordparser(tbl.Col.value('/','varchar(max)'),3,';') 
  ,dbo.Wordparser(dbo.Wordparser(tbl.Col.value('/','varchar(max)'),3,';') ,2,'D')
FROm
 @xml.nodes('/AvailRateUpdateRS/Success/Warning') Tbl(Col)  

Result

------------------------ -----------
Rate Plan ID 207782211   207782211

The example below should work for you. Just adjust it to your environment...

-- We create a table with sample data.
CREATE TABLE #mySource
(
    input XML
);

INSERT INTO #mySource VALUES (N' 
<AvailRateUpdateRS xmlns="http://www.expediaconnect.com/EQC/AR/2007/02">
<Success>
    <Warning code="7022">Inventory date 2016-12-30; Room Type ID 20583; Rate Plan ID 207782211; Inactive Rate Plan Updated Ref=[b44d7e4e-cf66-11e6-950b-e19b2852ebb6] </Warning>
    <Warning code="7022">Inventory date 2016-12-31; Room Type ID 20583; Rate Plan ID 207782211; Inactive Rate Plan Updated Ref=[b44d7e4e-cf66-11e6-950b-e19b2852ebb6] </Warning>
    <Warning code="7022">Inventory date 2017-01-02; Room Type ID 20583; Rate Plan ID 203619420; Inactive Rate Plan Updated Ref=[b44d7e4e-cf66-11e6-950b-e19b2852ebb6] </Warning>
    <Warning code="7022">Inventory date 2017-01-03; Room Type ID 20583; Rate Plan ID 203619420; Inactive Rate Plan Updated Ref=[b44d7e4e-cf66-11e6-950b-e19b2852ebb6] </Warning>
    <Warning code="7022">Inventory date 2017-01-04; Room Type ID 20583; Rate Plan ID 203619420; Inactive Rate Plan Updated Ref=[b44d7e4e-cf66-11e6-950b-e19b2852ebb6] </Warning>
</Success>
</AvailRateUpdateRS>');

INSERT INTO #mySource VALUES (N' 
<AvailRateUpdateRS xmlns="http://www.expediaconnect.com/EQC/AR/2007/02">
<Success>
    <Warning code="7022">Inventory date 2016-12-30; Room Type ID 205838; Rate Plan ID 207782213; Inactive Rate Plan Updated Ref=[b44d7e4e-cf66-11e6-950b-e19b2852ebb6] </Warning>
    <Warning code="7022">Inventory date 2016-12-31; Room Type ID 2058; Rate Plan ID 207782213; Inactive Rate Plan Updated Ref=[b44d7e4e-cf66-11e6-950b-e19b2852ebb6] </Warning>
    <Warning code="7022">Inventory date 2017-01-02; Room Type ID 20583; Rate Plan ID 203619425; Inactive Rate Plan Updated Ref=[b44d7e4e-cf66-11e6-950b-e19b2852ebb6] </Warning>
    <Warning code="7022">Inventory date 2017-01-03; Room Type ID 2058322; Rate Plan ID 203619425; Inactive Rate Plan Updated Ref=[b44d7e4e-cf66-11e6-950b-e19b2852ebb6] </Warning>
    <Warning code="7022">Inventory date 2017-01-04; Room Type ID 20583; Rate Plan ID 203619425; Inactive Rate Plan Updated Ref=[b44d7e4e-cf66-11e6-950b-e19b2852ebb6] </Warning>
</Success>
</AvailRateUpdateRS>');

-- We select the content of all Warning nodes from the XML.
WITH XMLNAMESPACES (DEFAULT 'http://www.expediaconnect.com/EQC/AR/2007/02'),

    myWarningNodes AS
    (
    SELECT 
    myWarningNode.value('(.)[1]', 'nvarchar(500)') AS WarningString
    FROM #mySource
    CROSS APPLY #mySource.input.nodes('AvailRateUpdateRS/Success/Warning') AS     myWarning (myWarningNode)
    )

-- We parse the ID from the string. May be you can find a better way to do this. Here is just one possible option. However, avoid using any scalar user defined function, if you care about performance.
    SELECT DISTINCT SUBSTRING(RIGHT(WarningString, LEN(WarningString) - PATINDEX('%Rate Plan ID %', WarningString) -11), 1, PATINDEX('%;%', RIGHT(WarningString, LEN(WarningString) - PATINDEX('%Rate Plan ID %', WarningString) -11))-1) AS RatePlanId
    INTO #myOutput
    FROM myWarningNodes;

-- We check the result.
SELECT * FROM #myOutput;

-- We clean the garbage.
drop table #mySource;
drop table #myOutput;

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