Solved

How do I convert an SQL stored XML document into discrete columns.

Posted on 2007-03-19
4
214 Views
Last Modified: 2007-04-22
You know when you say "Hey, that'll be easy" and it isn't?! ...

I've been given a shrinkwrapped app to work with. They want me to produce reports.

The original app's authors are not available and they will never be available and we cannot change the app and we have to just live with it.

So.

The app is a web app.

Instead of having a table with lots of columns, they have a table with 3 columns.

Col1 = UniqueID
Col2 = XML document
Col3 = A state (an int valued from 1 to 5).

I'm trying to get the data from the xml via an SQL command.

I can see that I can use OPENXML on MS SQL 2000, but I can't quite see how I use it.

The table is called WorkRequests and the column is called WR_SerializedObject.

What I want to do is a sort of

SELECT WR_ID, unserialized(WR_SerializedObject)  FROM WorkRequests

sort of thing.

WorkRequests is the table, WR_ID is the row's unique ID, WR_SerializedObject is the XML document.

Now I can see from the document, that they've made it include the same element 10 times ...

This is an edited doc (only the data has been edited).

<?xml version="1.0" encoding="utf-16"?>
<WorkRequest xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
      <State>BreakDownList</State>
      <SerializedObject />
      <LastEditedBy>Kevin M</LastEditedBy>
      <JobSheetNumber>039920</JobSheetNumber>
      <TimeOnScene>17:10</TimeOnScene>
      <CallOutAllowed>None</CallOutAllowed>
      <TyreMakeOrdered>RQuadling</TyreMakeOrdered>
      <Eta>13/07/2006 17:10</Eta>
      <FaxNumber>01555 123 345</FaxNumber>
      <TelephoneNumber>01555 555 987</TelephoneNumber>
      <TimeAllocated>15:39</TimeAllocated>
      <ServiceProvicerStaffName>Pete</ServiceProvicerStaffName>
      <ServiceProviderUsed>Bob Smith Quick Fitters</ServiceProviderUsed>
      <CallCentreReferenceNumber />
      <CallCenterUsed>None</CallCenterUsed>
      <Notes />
      <ConfirmDefectNumberRequired>No</ConfirmDefectNumberRequired>
      <VehicleLoaded>No</VehicleLoaded>
      <VehicleDueOutBy>13/07/2006 16:45</VehicleDueOutBy>
      <OtherVisibleDamage />
      <Mileage />
      <TrailerUnitRegistrationNumber>Free</TrailerUnitRegistrationNumber>
      <ColourOfVehicle>No</ColourOfVehicle>
      <Location>AX12 2FG</Location>
      <SpareOnBoard>No</SpareOnBoard>
      <TyreSize>10 22.5</TyreSize>
      <ConfirmRegistrationNumber>BGM39</ConfirmRegistrationNumber>
      <DamageDescription>N/A</DamageDescription>
      <TyreReason>Worn</TyreReason>
      <Position>NSR</Position>
      <DriversMobile>N/A</DriversMobile>
      <DriversName>N/A</DriversName>
      <ContactTelephoneNumber>01555 123 321</ContactTelephoneNumber>
      <ContactName>Jason</ContactName>
      <SpecificInstructions>Remoulds Acceptable</SpecificInstructions>
      <DoubleDeck>N/A</DoubleDeck>
      <Nofl>N/A</Nofl>
      <RegistrationNumber>BGM39</RegistrationNumber>
      <DefectNumberRequired>No</DefectNumberRequired>
      <HHCustomer>DHL</HHCustomer>
      <CallerLocation>FL</CallerLocation>
      <CallerName>Jason</CallerName>
      <Time>15:12</Time>
      <Date>13/07/2006</Date>
      <Contract>Bob Matton</Contract>
      <BTCOrThirdPartyJob>BTC</BTCOrThirdPartyJob>
      <StaffName>Michelle O</StaffName>
      <Comments />
      <Refusals>
            <Refusal>
                  <RefusalReason />
                  <StaffNameSpokenTo />
                  <DepotLocation />
                  <ServiceProviderName />
            </Refusal>
            <Refusal>
                  <RefusalReason />
                  <StaffNameSpokenTo />
                  <DepotLocation />
                  <ServiceProviderName />
            </Refusal>
            <Refusal>
                  <RefusalReason />
                  <StaffNameSpokenTo />
                  <DepotLocation />
                  <ServiceProviderName />
            </Refusal>
            <Refusal>
                  <RefusalReason />
                  <StaffNameSpokenTo />
                  <DepotLocation />
                  <ServiceProviderName />
            </Refusal>
            <Refusal>
                  <RefusalReason />
                  <StaffNameSpokenTo />
                  <DepotLocation />
                  <ServiceProviderName />
            </Refusal>
            <Refusal>
                  <RefusalReason />
                  <StaffNameSpokenTo />
                  <DepotLocation />
                  <ServiceProviderName />
            </Refusal>
            <Refusal>
                  <RefusalReason />
                  <StaffNameSpokenTo />
                  <DepotLocation />
                  <ServiceProviderName />
            </Refusal>
            <Refusal>
                  <RefusalReason />
                  <StaffNameSpokenTo />
                  <DepotLocation />
                  <ServiceProviderName />
            </Refusal>
            <Refusal>
                  <RefusalReason />
                  <StaffNameSpokenTo />
                  <DepotLocation />
                  <ServiceProviderName />
            </Refusal>
            <Refusal>
                  <RefusalReason />
                  <StaffNameSpokenTo />
                  <DepotLocation />
                  <ServiceProviderName />
            </Refusal>
      </Refusals>
</WorkRequest>

As I can't change the app, what I'm looking to do is add a trigger (insert/update) to update another table with the values (delete trigger to delete the values).

The app is low usage realtime, so even adding a second to the update/insert wouldn't be noticed. I don't think the app allow for the amending of MANY rows at the same time, so "inserted/deleted" should only ever be 1 row.

I think I would need 2 sets of results to insert/update the new table. The first would be of everything EXCEPT the refusals, the next would be the refusals per WR_ID, unless I can get RefusalReason_1, RefusalReason_2, etc.

I know I could use a whole ton of string manipulation, but hey, it IS XML already, so there should be some tricks I can use!

Pointers, suggestions, sympathies all accepted.

TIA.

Richard Quadling.
0
Comment
Question by:RQuadling
4 Comments
 
LVL 42

Expert Comment

by:EugeneZ
Comment Utility
0
 
LVL 40

Author Comment

by:RQuadling
Comment Utility
Thank you for that.

I've managed to get this to work as follows ...

declare @idoc int
declare @doc nvarchar(4000)
select top 1 @doc = convert(nvarchar(4000), wr_serializedobject) from workrequests where len(convert(nvarchar(4000), wr_serializedobject)) < 4000
exec sp_xml_preparedocument @idoc OUTPUT, @doc
select * from openxml(@idoc, '/WorkRequest',2)
exec sp_xml_removedocument @idoc


This is fine except that the majority of the documents are greater than 4000 characters (the XML data has a UTF-16 encoding! ARGH!).

As I want to operate on this data within T-SQL and you can't use text, ntext or varchar(8001+) or nvarchar(4001+), how do I process this XML?

0
 
LVL 1

Accepted Solution

by:
Computer101 earned 0 total points
Comment Utility
PAQed with points refunded (500)

Computer101
EE Admin
0

Featured Post

Free Gift Card with Acronis Backup Purchase!

Backup any data in any location: local and remote systems, physical and virtual servers, private and public clouds, Macs and PCs, tablets and mobile devices, & more! For limited time only, buy any Acronis backup products and get a FREE Amazon/Best Buy gift card worth up to $200!

Join & Write a Comment

In this article—a derivative of my DaytaBase.org blog post (http://daytabase.org/2011/06/18/what-week-is-it/)—I will explore a few different perspectives on which week today's date falls within using Microsoft SQL Server. First, to frame this stu…
Performance is the key factor for any successful data integration project, knowing the type of transformation that you’re using is the first step on optimizing the SSIS flow performance, by utilizing the correct transformation or the design alternat…
This video shows how to set up a shell script to accept a positional parameter when called, pass that to a SQL script, accept the output from the statement back and then manipulate it in the Shell.
Using examples as well as descriptions, and references to Books Online, show the documentation available for datatypes, explain the available data types and show how data can be passed into and out of variables.

743 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

18 Experts available now in Live!

Get 1:1 Help Now