Want to protect your cyber security and still get fast solutions? Ask a secure question today.Go Premium

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 496
  • Last Modified:

SQL Reading XML

The below T-SQL does not create an error but it only reads the first row of "FacNo,YearMonth, Visits"?  The XML file being read is below the T-SQL
DECLARE @x xml
SELECT @x = P
FROM OPENROWSET (BULK 'C:\EPD\DataTest.xml', SINGLE_BLOB) AS Products(P)

DECLARE @hdoc int
EXEC sp_xml_preparedocument @hdoc OUTPUT, @x

SELECT * FROM OPENXML (@hdoc, '/CMPDocument/Volume', 2)
WITH (
      FacNo varchar(max),
      YearMonth varchar(max),
      Visits varchar(max))

EXEC sp_xml_removedocument @hdoc

--------------------------------------- XML Table is below  ------------------
 <?xml version="1.0" encoding="utf-8"?>
<CMPDocument>
   <Volume>
      <FacNo>183</FacNo>
      <YearMonth>201312</YearMonth>
      <Visits>1</Visits>
      <FacNo>183</FacNo>
      <YearMonth>201401</YearMonth>
      <Visits>1</Visits>
      <FacNo>203</FacNo>
      <YearMonth>201311</YearMonth>
      <Visits>1</Visits>
      <FacNo>203</FacNo>
      <YearMonth>201401</YearMonth>
      <Visits>1</Visits>
    </Volume>
</CMPDocument>
0
dastaub
Asked:
dastaub
1 Solution
 
Surendra NathTechnology LeadCommented:
The only reason why your code didn't work is because, SQL Server is expecting your XML to be in the format of

<CMPDocument>
   <Volume>
      <FacNo>183</FacNo>
      <YearMonth>201312</YearMonth>
      <Visits>1</Visits>
   </Volume>

   <Volume>
      <FacNo>183</FacNo>
      <YearMonth>201401</YearMonth>
      <Visits>1</Visits>
   </Volume>
</CMPDocument>

as it is not the case, the sp_prepareXMLdocument and the openXML will take only the first nodes available and discard the rest....

you can try the below code

declare @X XML 
SET @X = 
'<?xml version="1.0" encoding="utf-8"?>
<CMPDocument>
   <Volume>
      <FacNo>183</FacNo>
      <YearMonth>201312</YearMonth>
      <Visits>1</Visits>
      <FacNo>183</FacNo>
      <YearMonth>201401</YearMonth>
      <Visits>1</Visits>
      <FacNo>203</FacNo>
      <YearMonth>201311</YearMonth>
      <Visits>1</Visits>
      <FacNo>203</FacNo>
      <YearMonth>201401</YearMonth>
      <Visits>1</Visits>
    </Volume>
</CMPDocument>
'

select @X




;WITH Visits AS
(
SELECT  ROW_NUMBER() OVER(ORDER BY (SELECT 1)) R1,T.c.query('.') as V FROM @X.nodes('CMPDocument/Volume/Visits') T(C)
),FACNO AS
(
SELECT  ROW_NUMBER() OVER(ORDER BY (SELECT 1)) R2,T.c.query('.') as F FROM @X.nodes('CMPDocument/Volume/FacNo') T(C)
),YearMonth AS
(
SELECT  ROW_NUMBER() OVER(ORDER BY (SELECT 1)) R3,T.c.query('.') as Y FROM @X.nodes('CMPDocument/Volume/YearMonth') T(C)
)
SELECT V.value('(/Visits)[1]','VARCHAR(100)') as Visits,F.value('(/FacNo)[1]','VARCHAR(100)') as FacNo,Y.value('(/YearMonth)[1]','VARCHAR(100)') as YearMonth
FROM Visits, FACNO,YearMonth
where R1=R2
AND R2 = R3

Open in new window

0
 
dastaubAuthor Commented:
The solution was to fix the malformed XML that you pointed out to me.  
<Item> </Item> was added and then it all worked.

  <CMPDocument>
    <Volume>
      <Item>
      <FacNo>183</FacNo>
      <YearMonth>201312</YearMonth>
      <Visits>341</Visits>
      </Item>
            <Item>
      <FacNo>183</FacNo>
      <YearMonth>201401</YearMonth>
      <Visits>431</Visits>
      </Item>
            <Item>
        <FacNo>203</FacNo>
        <YearMonth>201311</YearMonth>
        <Visits>144</Visits>
      </Item>
            <Item>
      <FacNo>203</FacNo>
      <YearMonth>201401</YearMonth>
      <Visits>1323</Visits>
      </Item>
          </Volume>
  </CMPDocument>
0

Featured Post

Nothing ever in the clear!

This technical paper will help you implement VMware’s VM encryption as well as implement Veeam encryption which together will achieve the nothing ever in the clear goal. If a bad guy steals VMs, backups or traffic they get nothing.

Tackle projects and never again get stuck behind a technical roadblock.
Join Now