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: 227
  • Last Modified:

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

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
Richard Quadling
Asked:
Richard Quadling
1 Solution
 
Eugene ZCommented:
0
 
Richard QuadlingSenior Software DeverloperAuthor Commented:
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
 
Computer101Commented:
PAQed with points refunded (500)

Computer101
EE Admin
0

Featured Post

What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

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