Question

Reading an XML file from inside a stored procedure.

Asked by: DementedManiac

Hello.

How do I open an XML file from inside a stored procedure? I've not used XML much, and am trying to bash my way through this, but all the examples I'm seeing aer showing me how to return results from xml as a varchar string, but how do I get my file into the varchar in the first place?

D.Maniac

This Question has been solved and asker verified All Experts Exchange premium technology solutions are available to subscription members.

Subscribe now for full access to Experts Exchange and get

Instant Access to this Solution

  • Plus...
  • 30 Day FREE access, no risk, no obligation
  • Collaborate with the world's top tech experts
  • Unlimited access to our exclusive solution database
  • Never be left without tech help again

Subscribe Now

Asked On
2003-07-06 at 20:41:21ID20670044
Tags

xml

,

file

,

procedure

,

stored

,

read

Topics

MS SQL Server

,

Extensible HTML (XHTML)

Participating Experts
7
Points
300
Comments
17

Trusted by hundreds of thousands everyday for fast, accurate and reliable tech support.

  • "The time we save is the biggest benefit of Experts Exchange to Warner Bros. What could take multiple guys 2 hours or more each to find is accessed in around 15 minutes on Experts Exchange." Mike Kapnisakis, Warner Bros.
  • "Our team likes having a resource that is more secure than just using Google and most experts using this service really know their stuff. It's nice to look here first versus using Google." Dayna Sellner, Lockheed Martin
  • "Anytime that I've been stumped with a problem, 9 out of 10 times Experts Exchange has either the accepted solution or an open discussion of the potential solution to the problem." Kenny Red, eBay Inc.

See what Experts Exchange can do for you.

Got a question?

We've got the answer.

Experts Exchange has been collecting answers to technology questions since 1996…3 million and counting! If you have a question, chances are we already have your answer.

Screenshot of Experts Exchange Knowledgebase

Need individual assistance?

Our experts are ready to help.

If you can't find the exact answer you're looking for, ask our exclusive community of 50,000 experts. You’ll get a personalized answer from a trusted professional.

Screenshot of Experts Exchange Knowledgebase

Want to learn from the best?

Read articles from industry experts.

Thousands of free tech tips, tricks, how-to’s and tutorials are available in our peer reviewed articles section. See for yourself how smart our experts are, no login required.

Screenshot of an Article

Working on a long term project?

Store your work and research.

Save solutions to your questions, answers you’ve discovered through searching plus helpful articles in your personal knowledgebase for easy future access.

Screenshot of Experts Exchange Knowledgebase

Access the answers to your technology questions today.

Subscribe Now

30-day free trial. Register in 60 seconds.

What Makes Experts Exchange Unique?

Members of the expert community talk about why the experience at Experts Exchange is different than what you will find anywhere else.

Trusted by the world's most respected brands.

image of each brand's logo

Faithfully serving IT professionals since 1996.

Experts Exchange Logo

Try it out and discover for yourself.

Subscribe Now

30-day free trial. Register in 60 seconds.

Related Solutions

  1. SQL Server 2000 - Update XML text in stored procedure
    In a stored procedure, is it possible to update the xml text that has been passed in and then pass this updated xml back? I am building up xml text over a series of asp pages and using this xml text to update tables. I would also like to be able to update the xml text with...
  2. Return a well-formed XML string from Stored Procedure
    I have a requirement to return a valid xml document back for SQL stored procedure call. Here's the basic request... Requesting system executes stored procecure passing in key input parms that allow stored proc to gather requested info. Result is to be a varchar (or text)...
  3. Passing an XML file to a stored procedure
    I am trying to get XML file information passed into a stored procedure so that I can insert it into my database. If I hardcode the xml into the stored procedure, everything works fine. But if I try to pass the XML file as a parameter, it isn't working. Here is what I have ...

Free Tech Articles

  1. WARNING: 5 Reasons why you should NEVER fix a computer for free.
    It is in our nature to love the puzzle. We are obsessed. The lot of us. We love puzzles. We love the challenge. We thrive on finding the answer. We hate disarray. It bothers us deep in our soul. W...
  2. SCCM OSD Basic troubleshooting
    SCCM 2007 OSD is a fantastic way to deploy operating systems, however, like most things SCCM issues can sometimes be difficult to resolve due to the sheer volume of logs to sift through and the dispe...
  3. Migrate Small Business Server 2003 to Exchange 2010 and Windows 2008 R2
    This guide is intended to provide step by step instructions on how to migrate from Small Business Server 2003 to Windows 2008 R2 with Exchange 2010. For this migration to work you will need the fo...
  4. Create a Win7 Gadget
    This article shows you how to create a simple "Gadget" -- a sort of mini-application supported by Windows 7 and Vista. Gadgets can be dropped anywhere on the desktop to provide instant information, ...
  5. Outlook continually prompting for username and password
    There have been a lot of questions recently regarding Outlook prompting for a username and password whilst using Exchange 2007. There are a few reasons why this would happen and I will try to cover t...
  6. Backup Exchange 2010 Information Store using Windows Backup
    There seems to be quite a lot of confusion around the ability to backup Exchange 2010 using the built in Windows Backup feature. This stems from the omission of this feature prior to Exchange 2007 s...

Cloud Class Webinars

  1. Avoiding Bugs in Microsoft Access
    Alison Balter takes and in-depth look at avoiding bugs in Access. In this webinar you will learn about using the immediate window to debug your applications, invoking the debugger, using breakpoints to troubleshoot, stepping through code, setting the next statement to execute, ...
  2. Top 10 Best New Features in Visio 2010
    Scott Helmers gives live demonstrations of the top 10 new features in Visio 2010. This webinar will teach you how to create compelling diagrams by adding shapes to the page with a single click, linking the shapes in a diagram to data in Excel (or SQL Server, or SharePoint), ...
  3. IT Consultant Business Secrets Revealed
    Michael Munger, Experts Exchange tech pro and IT consultant, pulls back the curtain on his very successful businesses and answers question on every IT consultant and business owner should know about. He shares secrets on what he did to solve the 5 most common problems in IT, ...
  4. Disaster Recovery and Business Continuity
    Quest CTO, Mike Billon, gives an overview of the steps involved in building a dunamic disaster recovery plan. Through case studies and an examination of software/hardware tooles for monitoring and testing, you'll gain a better understandin of where you are, where you want ...
  5. Organize Your Visio Diagrams with Containers and Lists
    Scott Helmers uses cross functional flowcharts, wireframe diagrams, data graphic legends and seating charts to teach you: how to ustilize all three new structured diagram components in Visio 2010, the best practices for organizeing shapes in previous version of Visio, how to organize ...
  6. How to Us Objects, Properties, Events and Methods in Microsoft Access
    Alison Dalter gives an in-depbth look at objects, properties, events and methods in Microsoft Access. In this webinar you will learn about using the object browser, referring to objects, working with properties and methods, working with object variables, understanding the ...

Join the Community

Give a Little. Get a Lot.

Join the community of experts here and help other tech pros by answering question in your area of expertise. You can earn FREE access to all Experts Exchange's premium features and resources.

Join the Community

Answers

 

by: xenon_jePosted on 2003-07-07 at 01:28:59ID: 8867656

redad in BOl about openXML

Here is the sample from BOL:

DECLARE @idoc int
DECLARE @doc varchar(1000)
SET @doc ='
<ROOT>
<Customer CustomerID="VINET" ContactName="Paul Henriot">
   <Order CustomerID="VINET" EmployeeID="5" OrderDate="1996-07-04T00:00:00">
      <OrderDetail OrderID="10248" ProductID="11" Quantity="12"/>
      <OrderDetail OrderID="10248" ProductID="42" Quantity="10"/>
   </Order>
</Customer>
<Customer CustomerID="LILAS" ContactName="Carlos Gonzlez">
   <Order CustomerID="LILAS" EmployeeID="3" OrderDate="1996-08-16T00:00:00">
      <OrderDetail OrderID="10283" ProductID="72" Quantity="3"/>
   </Order>
</Customer>
</ROOT>'
--Create an internal representation of the XML document.
EXEC sp_xml_preparedocument @idoc OUTPUT, @doc
-- Execute a SELECT statement that uses the OPENXML rowset provider.
SELECT    *
FROM       OPENXML (@idoc, '/ROOT/Customer',1)
            WITH (CustomerID  varchar(10),
                  ContactName varchar(20))

The content of the xml file can be imported in a table column by simply using DTS....

good luck,
  xenon

 

by: DementedManiacPosted on 2003-07-07 at 05:23:19ID: 8868783

Xenon, thanks for the suggestion, but what I need to know is how to read XML from a file.

I'm not sure how I could accomplish what I'm after with DTS as I've got XML files being emailed in, and I'm intending to use xp_readMail etc to collect them. They have xml attachments which I want to parse and store some of the data in the file.

Is it possible to start a DTS package from a stored procedure?
Is it possible to then have a file data source connection in that DTS package dynamically set the path to the path of the attachment.

Thanks,

Dawson

 

by: xenon_jePosted on 2003-07-07 at 06:05:47ID: 8869069

What I sugested was to import that XML file in a table field.. then from there put in a variable, and from that variable using the opnexml sugested above you can browse it in a user friendly way....

Using bcp or DTS you can import the XML file into a table with no transformation at all...

From a stored procedure you can start a job (with exec msdb.dbo.sp_start_job @job_name='XXX').
A DTS after you created it you can schedule it in EM by right click + schedule package)

Regarding dynamicaly setting the path..... I realy don't know if it's possible.......... :((

good luck,
           xenon

 

by: xenon_jePosted on 2003-07-07 at 06:14:26ID: 8869130

What I sugested was to import that XML file in a table field.. then from there put in a variable, and from that variable using the opnexml sugested above you can browse it in a user friendly way....

Using bcp or DTS you can import the XML file into a table with no transformation at all...

From a stored procedure you can start a job (with exec msdb.dbo.sp_start_job @job_name='XXX').
A DTS after you created it you can schedule it in EM by right click + schedule package)

Regarding dynamicaly setting the path..... I realy don't know if it's possible.......... :((

good luck,
           xenon

 

by: Mr_PeerapolPosted on 2003-07-07 at 08:47:44ID: 8870253

Hi,

I can only give you an example how to read text file from a stored procedure. You probably need to modify it a lot.
Anyway, let see if you can modify it to read your XML file.

declare @objFSys int
declare @objFile int
declare @blnEndOfFile int
declare @strLine varchar(4000)

exec sp_OACreate 'Scripting.FileSystemObject', @objFSys out

-- Change the file path to the one that is passed to your stored procedure
exec sp_OAMethod @objFSys, 'OpenTextFile', @objFile out, 'C:\test.txt', 1
exec sp_OAMethod @objFile, 'AtEndOfStream', @blnEndOfFile out
while @blnEndOfFile=0 begin
  exec sp_OAMethod @objFile, 'ReadLine', @strLine out
  -- Here you got one line from the file
  select @strLine
  exec sp_OAMethod @objFile, 'AtEndOfStream', @blnEndOfFile out
end
exec sp_OADestroy @objFile
exec sp_OADestroy @objFSys

 

by: DementedManiacPosted on 2003-07-08 at 20:10:26ID: 8882146

Thanks for your help people,

In the end, a couple of factors have conspired together to mean that I'm not going to use the xp_***Mail stored procedures to get the attachments. I'll do it in VB.
It turns out that the size of the XML files is around the 25,000 character mark, which means I can't bring it in to a VarChar(8000), but would have to use a TEXT data field in a table. From what I read, it seems that sp_xml_preparedocument would happily take a TEXT parameter, but I'm not sure how to do that.... but this doesn't matter anyhow, as it turns out the XML file is not particularly well formed, and therefore doesn't appear to be able to be easily machine read in it's current form, which is why I'm going to use VB to massage the xml file first, then send the harvested data into the database.


Mr Mr_Peerapol, I'm giving you the points as your suggestion of using the FileSystemObject would have worked, if I'd realised that the xml file was unicode, I discovered this when I ran the code shown on the following link, which worked fantastic straight out of the box
http://www.planet-source-code.com/vb/scripts/ShowCode.asp?txtCodeId=359&lngWId=5
I could of course modify the FSO code to work with a unicode file, but by the time I'd realised that that was why it wasn't working, I had already decided not to do it that way anyhow.

Thanks for your help guys.

D.Maniac

 

by: murrayjohnPosted on 2003-10-21 at 16:52:58ID: 9595170

Dear D.Maniac,

I also have a need to read an XML file from within a stored procedure.

Combining the ideas of Joseph Gama (http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnsqlpro03/html/sp03g8.asp) and Umachandar Jayachandran ( http://www.sqlxml.org/faqs.aspx?faq=42), I have built the following procedure (u_xmlfile_preparedocument), that currently handles files up to 2.5MB (it can easily be extended to handle larger files if necessary).


Regards, MurrayJohn

if not exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[u_xmlfile_preparedocument]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
  execute('CREATE PROCEDURE [dbo].[u_xmlfile_preparedocument] As Begin Return End')
GO

ALTER PROCEDURE dbo.u_xmlfile_preparedocument @hdoc Integer Output,
                                              @xmlfile varchar(1000) = NULL
AS
--
--    Description:
--
--        Utility procedure to invoke sp_xml_preparedocument from a file rather than text
--
--    Credits:
--
--        Joseph Gama (http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnsqlpro03/html/sp03g8.asp)
--        Umachandar Jayachandran (http://www.sqlxml.org/faqs.aspx?faq=42)
--
--    Example invocation:
--
--        exec dbo.u_xmlfile_preparedocument @hdoc OUTPUT, 'C:\test.xml'
--
--    Change History
--    
--    Date        Who              Change
--    ----------- ---------------- -------------------------------------------------
--    17-Oct-2003 Murray Crosswell CR841: Initial version
--
--  $Id: dbo.u_xmlfile_preparedocument.PRC,v 1.1 2003/10/21 07:31:04 mcrosswell Exp $
--
Begin

SET NOCOUNT ON

Declare @i int,
        @size int,
        @blocks int,
        @cmdDS varchar(8000),
        @cmdD1 varchar(8000),
        @cmdD2 varchar(8000),
      @cmdD3 varchar(8000),
        @cmdD4 varchar(8000),
        @cmdDF varchar(8000),
        @cmdR1 varchar(8000),
        @cmdR2 varchar(8000),
      @cmdR3 varchar(8000),
        @cmdR4 varchar(8000),
        @cmdF1 varchar(8000),
        @cmdF2 varchar(8000),
      @cmdF3 varchar(8000),
        @cmdF4 varchar(8000),
        @cmdE varchar(8000)

create table #filedetails
(altname varchar(30),size int,createdate varchar(32),
 createtime varchar(32),lastwrittendt varchar(30),
 lastwrittentime varchar(32),lastaccessdt varchar(30),
 lastaccesstime varchar(32),attributes int)

insert into #filedetails exec master..xp_getfiledetails @xmlfile

set @size=(select size from #filedetails)

drop table #filedetails

SET @blocks=@size/4000+1

--create all temporary variables
SET @cmdDS='DECLARE @fso int, @fl int, @hr int, @qm char(1), @vp varchar(8000), @vs varchar(8000), '

SET @cmdDF=' Set @qm = char(39)'
SET @cmdDF=@cmdDF+' Set @vp = ''DECLARE @Handle int EXEC sp_xml_preparedocument @Handle OUT, ''+@qm'
SET @cmdDF=@cmdDF+' Set @vs = @qm+'' DECLARE he_cur CURSOR GLOBAL FOR SELECT @Handle'''
SET @cmdDF=@cmdDF+' EXEC @hr = sp_OACreate ''Scripting.FileSystemObject'', @fso OUT '
SET @cmdDF=@cmdDF+'exec sp_oamethod @fso, ''opentextfile'', @fl out, '''+@xmlfile+''', 1 '

--read and fix data
SET @cmdD1 = ''
SET @cmdD2 = ''
SET @cmdD3 = ''
SET @cmdD4 = ''
SET @cmdR1 = ''
SET @cmdR2 = ''
SET @cmdR3 = ''
SET @cmdR4 = ''
SET @cmdF1 = ''
SET @cmdF2 = ''
SET @cmdF3 = ''
SET @cmdF4 = ''
SET @i=1
WHILE @i<=@blocks
      BEGIN
      IF @i < 171
            BEGIN
                     SET @cmdD1=@cmdD1+'@v'+CONVERT(VARCHAR(9),@i)+' varchar(8000), '
            SET @cmdR1=@cmdR1+'exec @hr=sp_oamethod @fl,''read'','+'@v'+CONVERT(VARCHAR(9),@i)+' out,4000 '
            SET @cmdF1=@cmdF1+'Set @v'+CONVERT(VARCHAR(9),@i)+'=Replace(@v'+CONVERT(VARCHAR(9),@i)+',@qm,@qm+@qm) '      
            END
      ELSE IF @i < 341
            BEGIN
            SET @cmdD2=@cmdD2+'@v'+CONVERT(VARCHAR(9),@i)+' varchar(8000), '
            SET @cmdR2=@cmdR2+'exec @hr=sp_oamethod @fl,''read'','+'@v'+CONVERT(VARCHAR(9),@i)+' out,4000 '
            SET @cmdF2=@cmdF2+'Set @v'+CONVERT(VARCHAR(9),@i)+'=Replace(@v'+CONVERT(VARCHAR(9),@i)+',@qm,@qm+@qm) '
            END
      ELSE IF @i < 511
            BEGIN
                     SET @cmdD3=@cmdD3+'@v'+CONVERT(VARCHAR(9),@i)+' varchar(8000), '
            SET @cmdR3=@cmdR3+'exec @hr=sp_oamethod @fl,''read'','+'@v'+CONVERT(VARCHAR(9),@i)+' out,4000 '
            SET @cmdF3=@cmdF3+'Set @v'+CONVERT(VARCHAR(9),@i)+'=Replace(@v'+CONVERT(VARCHAR(9),@i)+',@qm,@qm+@qm) '      
            END
      ELSE
            BEGIN
            SET @cmdD4=@cmdD4+'@v'+CONVERT(VARCHAR(9),@i)+' varchar(8000), '
            SET @cmdR4=@cmdR4+'exec @hr=sp_oamethod @fl,''read'','+'@v'+CONVERT(VARCHAR(9),@i)+' out,4000 '
            SET @cmdF4=@cmdF4+'Set @v'+CONVERT(VARCHAR(9),@i)+'=Replace(@v'+CONVERT(VARCHAR(9),@i)+',@qm,@qm+@qm) '
            END
        SET @i=@i+1
      END      
IF @cmdD4 <> ''
      SET @cmdD4=LEFT(@cmdD4,len(@cmdD4)-1)
ELSE IF @cmdD3 <> ''
      SET @cmdD3=LEFT(@cmdD3,len(@cmdD3)-1)
ELSE IF @cmdD2 <> ''
      SET @cmdD2=LEFT(@cmdD2,len(@cmdD2)-1)
ELSE
      SET @cmdD1=LEFT(@cmdD1,len(@cmdD1)-1)
--execute sp_xml_preparedocument
SET @cmdE='exec(@vp+'
SET @i=1
WHILE @i<=@blocks
      BEGIN
      SET @cmdE=@cmdE+'@v'+CONVERT(NVARCHAR(9),@i)+'+'
      SET @i=@i+1
      END      
SET @cmdE=LEFT(@cmdE,len(@cmdE)-1)
SET @cmdE=@cmdE+'+@vs) '
SET @cmdE=@cmdE+'EXEC @hr = sp_OADestroy @fl EXEC @hr = sp_OADestroy @fso'
exec( @cmdDS+@cmdD1+@cmdD2+@cmdD3+@cmdD4+@cmdDF+@cmdR1+@cmdR2+@cmdR3+@cmdR4+@cmdF1+@cmdF2+@cmdF3+@cmdF4+@cmdE )

OPEN GLOBAL he_cur
FETCH he_cur INTO @hdoc
DEALLOCATE GLOBAL he_cur

IF @hdoc IS NULL
    RAISERROR( 'Invalid Handle!', 16, 1 )

END

 

by: cetafuddPosted on 2003-11-19 at 13:56:36ID: 9782847

MurrayJohn,

You did a great job on that stored procedure, it works perfect.
The only problem I have is because it handles files only up to 2.5 MB and I need to handle files up to 10 MB.
I remember you said it could easily be extended to handle larger files if necessary....:)  Well, I gave it a look
but I got completely lost. Could you help me on that one ?

Thanks a lot

Ceta

 

by: murrayjohnPosted on 2003-11-23 at 16:15:11ID: 9807628

Ceta,

to make the procedure handle larger files one would just add more set of variables (i.e. @cmdD5, @cmdR5, @cmdF5) and extend the code that utilises them.

Alternatively one could abstract the procedure one more level so that the above variable extensions are generated as well.

I have now done this below - the new version should now easily support 10MB files.

The new limit (I think) is around 14MB. To go beyond there, the variable @cmdsrc2 in the following procedure would need to be split into multiple parts as it will be the first one to hit the 8,000 character limit.


Cheers, MurrayJohn.


if not exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[u_xmlfile_preparedocument]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
  execute('CREATE PROCEDURE [dbo].[u_xmlfile_preparedocument] As Begin Return End')
GO

ALTER PROCEDURE dbo.u_xmlfile_preparedocument @hdoc Integer Output,
                                              @xmlfile varchar(1000) = NULL
AS
--
--    Description:
--
--        Utility procedure to invoke sp_xml_preparedocument from a file rather than text
--
--    Credits:
--
--        Joseph Gama (http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnsqlpro03/html/sp03g8.asp)
--        Umachandar Jayachandran (http://www.sqlxml.org/faqs.aspx?faq=42)
--
--    Example invocation:
--
--        exec dbo.u_xmlfile_preparedocument @hdoc OUTPUT, 'C:\test.xml'
--
--    Change History
--    
--    Date        Who              Change
--    ----------- ---------------- -------------------------------------------------
--    17-Oct-2003 Murray Crosswell CR841: Initial version
--    24-Nov-2003 Murray Crosswell CR841: Move to another level of code generation abstraction to support larger files.
--
--  $Id: dbo.u_xmlfile_preparedocument.PRC,v 1.2 2003/10/22 00:12:38 mcrosswell Exp $
--
Begin

SET NOCOUNT ON    

Declare @i int,
        @size int,
        @blocks int,
        @varcnt int,
        @qm char(1),
        @bperv integer,
        @cmdsrc varchar(8000),
        @cmdsrc2 varchar(8000),
        @cmdsrc3 varchar(8000),
        @CRLF Varchar(2)

Set @CRLF = Char(13) + Char(10)

create table #filedetails
(altname varchar(30),size int,createdate varchar(32),
 createtime varchar(32),lastwrittendt varchar(30),
 lastwrittentime varchar(32),lastaccessdt varchar(30),
 lastaccesstime varchar(32),attributes int)

insert into #filedetails exec master..xp_getfiledetails @xmlfile

set @size=(select size from #filedetails)

drop table #filedetails

Set @bperv = 165
Set @qm = char(39)
Set @blocks=@size/4000+1
Set @varcnt=(@blocks-1)/@bperv+1

Set @cmdsrc = 'Declare @cmdDS varchar(8000), '
Set @cmdsrc = @cmdsrc + '@cmdES varchar(8000), '
Set @i=1
While @i<=@varcnt
  Begin
  Set @cmdsrc = @cmdsrc + '@cmdD' + Convert(Varchar(9),@i) + ' Varchar(8000), '
  Set @cmdsrc = @cmdsrc + '@cmdR' + Convert(Varchar(9),@i) + ' Varchar(8000), '
  Set @cmdsrc = @cmdsrc + '@cmdF' + Convert(Varchar(9),@i) + ' Varchar(8000), '
  Set @cmdsrc = @cmdsrc + '@cmdE' + Convert(Varchar(9),@i) + ' Varchar(8000), '
  Set @i=@i+1
  End      
Set @cmdsrc = @cmdsrc + '@cmdDF varchar(8000), '
Set @cmdsrc = @cmdsrc + '@cmdEF varchar(8000), '
Set @cmdsrc = @cmdsrc + '@i int, @blocks int'

Set @cmdsrc = @cmdsrc + ' SET @blocks=' + Convert(Varchar(9),@blocks)
Set @cmdsrc = @cmdsrc + ' SET @cmdDS='+@qm+'DECLARE @fso int, @fl int, @hr int, @qm char(1), @vp varchar(8000), @vs varchar(8000), '+@qm

Set @cmdsrc = @cmdsrc + ' SET @cmdDF='+@qm+' Set @qm = char(39)'+@qm
Set @cmdsrc = @cmdsrc + ' SET @cmdDF=@cmdDF+'+@qm+' Set @vp = '+@qm+@qm+'DECLARE @Handle int EXEC sp_xml_preparedocument @Handle OUT, '+@qm+@qm+'+@qm'+@qm
Set @cmdsrc = @cmdsrc + ' SET @cmdDF=@cmdDF+'+@qm+' Set @vs = @qm+'+@qm+@qm+' DECLARE he_cur CURSOR GLOBAL FOR SELECT @Handle'+@qm+@qm+@qm
Set @cmdsrc = @cmdsrc + ' SET @cmdDF=@cmdDF+'+@qm+' EXEC @hr = sp_OACreate '+@qm+@qm+'Scripting.FileSystemObject'+@qm+@qm+', @fso OUT '+@qm
Set @cmdsrc = @cmdsrc + ' SET @cmdDF=@cmdDF+'+@qm+'exec sp_oamethod @fso, '+@qm+@qm+'opentextfile'+@qm+@qm+', @fl out, '+@qm+@qm+@xmlfile+@qm+@qm+', 1 '+@qm
Set @i=1
While @i<=@varcnt
  Begin
  Set @cmdsrc = @cmdsrc + ' SET @cmdD' + Convert(Varchar(9),@i) + '='+@qm+@qm
  Set @cmdsrc = @cmdsrc + ' SET @cmdR' + Convert(Varchar(9),@i) + '='+@qm+@qm
  Set @cmdsrc = @cmdsrc + ' SET @cmdF' + Convert(Varchar(9),@i) + '='+@qm+@qm
  Set @cmdsrc = @cmdsrc + ' SET @cmdE' + Convert(Varchar(9),@i) + '='+@qm+@qm
  Set @i=@i+1
  End      
Set @cmdsrc = @cmdsrc + ' SET @i=1'
Set @cmdsrc = @cmdsrc + ' WHILE @i<=@blocks'
Set @cmdsrc = @cmdsrc + ' BEGIN'
Set @cmdsrc2 = ''
Set @i=1
While @i<=@varcnt
  Begin
  If @i <> 1 Set @cmdsrc2 = @cmdsrc2 + ' ELSE'
  If @i <> @varcnt Set @cmdsrc2 = @cmdsrc2 + ' IF @i < ' + Convert(Varchar(9),@i*@bperv+1)
  If @varcnt > 1 Set @cmdsrc2 = @cmdsrc2 + ' BEGIN'  
  Set @cmdsrc2 = @cmdsrc2 + ' SET @cmdD' + Convert(Varchar(9),@i) + '=@cmdD' + Convert(Varchar(9),@i) + '+'+@qm+'@v'+@qm+'+CONVERT(VARCHAR(9),@i)+'+@qm+' varchar(8000), '+@qm
  Set @cmdsrc2 = @cmdsrc2 + ' SET @cmdR' + Convert(Varchar(9),@i) + '=@cmdR' + Convert(Varchar(9),@i) + '+'+@qm+'exec @hr=sp_oamethod @fl,'+@qm+@qm+'read'+@qm+@qm+','+@qm+'+'+@qm+'@v'+@qm+'+CONVERT(VARCHAR(9),@i)+'+@qm+' out,4000 '+@qm
  Set @cmdsrc2 = @cmdsrc2 + ' SET @cmdF' + Convert(Varchar(9),@i) + '=@cmdF' + Convert(Varchar(9),@i) + '+'+@qm+'Set @v'+@qm+'+CONVERT(VARCHAR(9),@i)+'+@qm+'=Replace(@v'+@qm+'+CONVERT(VARCHAR(9),@i)+'+@qm+',@qm,@qm+@qm) '+@qm
  Set @cmdsrc2 = @cmdsrc2 + ' SET @cmdE' + Convert(Varchar(9),@i) + '=@cmdE' + Convert(Varchar(9),@i) + '+'+@qm+'@v'+@qm+'+CONVERT(VARCHAR(9),@i)+'+@qm+'+'+@qm
  If @varcnt > 1 Set @cmdsrc2 = @cmdsrc2 + ' END'
  Set @i=@i+1
  End      
Set @cmdsrc3 = ' SET @i=@i+1'
Set @cmdsrc3 = @cmdsrc3 + ' END'

Set @cmdsrc3 = @cmdsrc3 + ' SET @cmdD' + Convert(Varchar(9),@varcnt) + '=LEFT(@cmdD' + Convert(Varchar(9),@varcnt) + ',len(@cmdD' + Convert(Varchar(9),@varcnt) + ')-1)'

Set @cmdsrc3 = @cmdsrc3 + ' SET @cmdES='+@qm+'exec(@vp+'+@qm
Set @cmdsrc3 = @cmdsrc3 + ' SET @cmdEF='+@qm+'@vs) EXEC @hr = sp_OADestroy @fl EXEC @hr = sp_OADestroy @fso'+@qm
Set @cmdsrc3 = @cmdsrc3 + ' exec( @cmdDS+'
Set @i=1
While @i<=@varcnt
  Begin
  Set @cmdsrc3 = @cmdsrc3 + '@cmdD' + Convert(Varchar(9),@i) + '+'
  Set @i=@i+1
  End      
Set @cmdsrc3 = @cmdsrc3 + '@cmdDF+'
Set @i=1
While @i<=@varcnt
  Begin
  Set @cmdsrc3 = @cmdsrc3 + '@cmdR' + Convert(Varchar(9),@i) + '+'
  Set @i=@i+1
  End      
Set @i=1
While @i<=@varcnt
  Begin
  Set @cmdsrc3 = @cmdsrc3 + '@cmdF' + Convert(Varchar(9),@i) + '+'
  Set @i=@i+1
  End      
Set @cmdsrc3 = @cmdsrc3 + '@cmdES+'
Set @i=1
While @i<=@varcnt
  Begin
  Set @cmdsrc3 = @cmdsrc3 + '@cmdE' + Convert(Varchar(9),@i) + '+'
  Set @i=@i+1
  End      
Set @cmdsrc3 = @cmdsrc3 + '@cmdEF )'

Execute (@cmdsrc+@cmdsrc2+@cmdsrc3)

OPEN GLOBAL he_cur
FETCH he_cur INTO @hdoc
DEALLOCATE GLOBAL he_cur

IF @hdoc IS NULL
    RAISERROR( 'Invalid Handle!', 16, 1 )

End

 

by: cetafuddPosted on 2003-11-26 at 05:07:44ID: 9824318

You are number one !
Perfect....
Thank you very much...

 

by: khinvraPosted on 2004-08-12 at 02:17:10ID: 11781744

I  need to use the namespace with this store procedure as I am trying to read the file which is created by ADO

'<xml xmlns:rs="urn:schemas-microsoft-com:rowset" xmlns:z="#RowsetSchema"/>'  

is the namespace.

How should we do it ?

Rahul

 

by: acperkinsPosted on 2004-08-12 at 07:17:30ID: 11784005

>>How should we do it ?<<
You post a new question in this Topic Area.

 

by: murrayjohnPosted on 2004-08-12 at 20:34:03ID: 11790308

Rahul,

one just needs to add another optional parameter to the procedure and then pass the value to sp_xml_preparedocument as follows:

Replace:

ALTER PROCEDURE dbo.u_xmlfile_preparedocument @hdoc Integer Output,
                                              @xmlfile varchar(1000) = NULL
AS

With:

ALTER PROCEDURE dbo.u_xmlfile_preparedocument @hdoc Integer Output,
                                              @xmlfile varchar(1000) = NULL,
                                              @xpath_namespaces varchar(1000) = NULL
AS

... and replace:

Set @cmdsrc = @cmdsrc + ' SET @cmdDF=@cmdDF+'+@qm+' Set @vp = '+@qm+@qm+'DECLARE @Handle int EXEC sp_xml_preparedocument @Handle OUT, '+@qm+@qm+'+@qm'+@qm
Set @cmdsrc = @cmdsrc + ' SET @cmdDF=@cmdDF+'+@qm+' Set @vs = @qm+'+@qm+@qm+' DECLARE he_cur CURSOR GLOBAL FOR SELECT @Handle'+@qm+@qm+@qm

With:

Set @cmdsrc = @cmdsrc + ' SET @cmdDF=@cmdDF+'+@qm+' Set @vp = '+@qm+@qm+'DECLARE @Handle int EXEC sp_xml_preparedocument @Handle OUT, '+@qm+@qm+'+@qm'+@qm
Set @cmdsrc = @cmdsrc + ' SET @cmdDF=@cmdDF+'+@qm+' Set @vs = @qm+'+@qm+@qm+', '+@qm+@qm+'+@qm+'+@qm+@qm+IsNull(@xpath_namespaces,'')+@qm+@qm+'+@qm+'+@qm+@qm+' DECLARE he_cur CURSOR GLOBAL FOR SELECT @Handle'+@qm+@qm+@qm


Now procedure u_xmlfile_preparedocument supports the complete functionality of sp_xml_preparedocument.


Cheers, MurrayJohn.

 

by: khinvraPosted on 2004-08-15 at 20:22:44ID: 11806832

Thanx a lot
Rahul

 

by: Heiland5Posted on 2004-08-18 at 12:58:07ID: 11835143

John Murray,

Can you take your solution a step farther?
I am trying to write one row into a table for each XML tag "TRANSACTION" that is in my XML file, of which there are multiples.  Within each TRANSACTION, there are the various levels of elements.  When I do multiple OPENXML statements to get the various pieces of information to load into a single table row, I see multiple rows appearing in Query Analyzer for each OPENXML statement.

How should I code these OPENXML statements so as to make sure that I insert one row per TRANSACTION tag?

I've included my stored procedure (as follows):
++++++++++++++++++++++++++++++++++++++++++++++++++++++
CREATE PROCEDURE pr_NIPR_InsertResponse
                  (@xmlDocName text)

AS

      declare @intDoc int
      declare @xmlDoc2 varchar(8000)

-- SAMPLE DATA
--<?xml version="1.0" standalone="yes"?>
--<NIPR>
--    <TRANSACTION>
--      <APPLICANT>
--            <GENDER>M</GENDER>
--            <LICENSE_KEY>
--                  <LICENSE_CLASS>1022</LICENSE_CLASS>
--                  <LICENSE_ID>ABCDEFGH</LICENSE_ID>
--            </LICENSE_KEY>
--            <TAX_NUM>123456789</TAX_NUM>
--            <TYPE>I</TYPE>
--      </APPLICANT>
--      <CUST_BATCH>5</CUST_BATCH>
--      <CUST_TRANS>1</CUST_TRANS>
--      <LICENSE>
--            <DATE_EFFECTIVE>20021017</DATE_EFFECTIVE>
--            <INT_RESPONSE>
--                  <DATE_STAMP>20040730</DATE_STAMP>
--                  <RESP_MESSAGE>
--                        <ACTION_REQD>N</ACTION_REQD>
--                        <COMMENTS>Transaction has been sent to state for review</COMMENTS>
--                        <COMMENT_CODE>10003</COMMENT_CODE>
--                  </RESP_MESSAGE>
--                  <TIME_STAMP>092937000</TIME_STAMP>
--            </INT_RESPONSE>
--            <LICENSE_CLASS>1022</LICENSE_CLASS>
--            <LOA>
--                  <LOA_CODE>11</LOA_CODE>
--            </LOA>
--            <LOA>
--                  <LOA_CODE>30</LOA_CODE>
--            </LOA>
--            <LOA>
--                  <LOA_CODE>127</LOA_CODE>
--            </LOA>
--      </LICENSE>
--      <NIPR_TRANS>16793274</NIPR_TRANS>
--      <TRANS_HEAD>
--            <DATE_STAMP>20040730</DATE_STAMP>
--            <STATE_CODE>ID</STATE_CODE>
--            <TIME_STAMP>103224000</TIME_STAMP>
--            <TRANSACTION_TYPE>1</TRANSACTION_TYPE>
--      </TRANS_HEAD>
--      <TRANS_STATUS>SR</TRANS_STATUS>
--      <VALID>P</VALID>
--   </TRANSACTION>
--</NIPR>

      -- load XML document into memory -- called to obtain a document handle that is then passed to the OPENXML statement
      EXEC u_xmlfile_preparedocument @intDoc OUTPUT, @xmlDocName      -- worked passing "C:\DotNet Apps\NIPRApp\bin\LGI200407301031_NIPR.XM" to procedure

      -- process XML document with OPENXML statement
            -- 2 indicates an element-centric mapping (instead of by attributes)
      
      -- Transaction batch info
      SELECT *
            FROM OPENXML(@intDoc, '/NIPR/TRANSACTION', 2)
            WITH      (VALID char(1),
                  CUST_BATCH int,
                  CUST_TRANS int,
                  NIPR_TRANS int,
                  TRANS_STATUS char(2))
      -- Transaction batch info (more)
      SELECT *
            FROM OPENXML(@intDoc, '/NIPR/TRANSACTION/TRANS_HEAD', 2)
            WITH       (DATE_STAMP char(8),
                  TIME_STAMP char(9),
                  STATE_CODE char(2),
                  TRANSACTION_TYPE int)
      -- Transaction Response info
      SELECT *
            FROM OPENXML(@intDoc, '/NIPR/TRANSACTION/LICENSE/INT_RESPONSE/RESP_MESSAGE', 2)
            WITH       (ACTION_REQD char(1),
                  COMMENTS varchar(500),
                  COMMENT_CODE int)
      -- Applicant Tax ID info
      SELECT *
            FROM OPENXML(@intDoc, '/NIPR/TRANSACTION/APPLICANT',2)
            WITH      (TAX_NUM char(9))
      -- Applicant License info
      SELECT *
            FROM OPENXML(@intDoc, '/NIPR/TRANSACTION/APPLICANT/LICENSE_KEY',2)
            WITH      (LICENSE_CLASS int,
                  LICENSE_ID varchar(14))

               -- INSERT data into 'NIPRResponse' table
               -- ???????

      -- remove XML document from memory
      EXEC sp_xml_removedocument @intDoc
GO
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Thanks for any help you can give on this!
Kevin

 

by: murrayjohnPosted on 2004-08-18 at 18:51:10ID: 11837533

Kevin,

your query is not specifically related to my procedure but is a general OpenXML one - regardless the following suggestion is offered:

Within each transaction block there needs to be a unique identifier - lets assume element NIPR_TRANS is going to be unique.

In this case we could expose NIPR_TRANS within each query as follows:

     SELECT *
          FROM OPENXML(@intDoc, '/NIPR/TRANSACTION/TRANS_HEAD', 2)
          WITH      (NIPR_TRANS int '../NIPR_TRANS',
               DATE_STAMP char(8),
               TIME_STAMP char(9),
               STATE_CODE char(2),
               TRANSACTION_TYPE int)
     -- Transaction Response info

     SELECT *
          FROM OPENXML(@intDoc, '/NIPR/TRANSACTION/LICENSE/INT_RESPONSE/RESP_MESSAGE', 2)
          WITH (NIPR_TRANS int '../../../NIPR_TRANS',
               ACTION_REQD char(1),
               COMMENTS varchar(500),
               COMMENT_CODE int)
     -- Applicant Tax ID info

     SELECT *
          FROM OPENXML(@intDoc, '/NIPR/TRANSACTION/APPLICANT',2)
          WITH     (NIPR_TRANS int '../NIPR_TRANS',
                    TAX_NUM char(9))
     -- Applicant License info
     SELECT *
          FROM OPENXML(@intDoc, '/NIPR/TRANSACTION/APPLICANT/LICENSE_KEY',2)
          WITH     (NIPR_TRANS int '../../NIPR_TRANS',
               LICENSE_CLASS int,
               LICENSE_ID varchar(14))


One could then place a cursor around the first main transaction query retrieving the NIPR_TRANS value on each FETCH and then use the value in a 'WHERE' clause added to each of the above secondary select statements.

If there is not a unique transaction reference then you are in trouble (or you need to add one if you have control of the XML creation).

It could be added as an attribute like '<TRANSACTION ID="1">' and then referenced within the WITH clause as:

ID int '@ID',

in the primary transaction query or:

ID int '../@ID'

in the secondary queries (matching the ../ depth as per NIPR_TRANS shown above).


Cheers, Murray.

 

by: Heiland5Posted on 2004-08-23 at 11:38:55ID: 11873607

Thanks!

I have used your tip on to expose the NIPR_TRANS value, and exposed many other values that I want to insert into my table.  The following INSERT statement appears to work ok with the OPENXML statement.   If you have concerns with this statement for any reason, like any hidden or potential problem with it, please let me know as soon as possible.

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-- Insert row into table for each Transaction element on the XML file
INSERT into NIPRResponse
      (
      CustBatchNo, CustTransNo, NIPRTransNo, TransValid, TransStatus,
      TaxID, LicenseNo, BatchDate, BatchTime, StateAbbrev,
      LicInitRespActionReqd, LicInitRespComments, LicInitRespCode,
      LicRespApproved, LicRespEffectiveDt, LicRespDate, LicRespTime, LicRespActionReqd, LicRespComments, LicRespCode
      )
      SELECT *
      FROM OPENXML(@intDoc, '/NIPR/TRANSACTION', 2)
      WITH      (
      CUST_BATCH int 'CUST_BATCH',
            CUST_TRANS int 'CUST_TRANS',
            NIPR_TRANS int 'NIPR_TRANS',
            VALID char(1) 'VALID',
            TRANS_STATUS char(2) 'TRANS_STATUS',
            TAX_NUM char(9) 'APPLICANT/TAX_NUM',
            LICENSE_ID varchar(14) 'APPLICANT/LICENSE_KEY/LICENSE_ID',
                   DATE_STAMP char(8) 'TRANS_HEAD/DATE_STAMP',
                   TIME_STAMP char(9) 'TRANS_HEAD/TIME_STAMP',
                   STATE_CODE char(2) 'TRANS_HEAD/STATE_CODE',

                  ACTION_REQD char(1) 'LICENSE/INT_RESPONSE/RESP_MESSAGE/ACTION_REQD',
                  COMMENTS varchar(500) 'LICENSE/INT_RESPONSE/RESP_MESSAGE/COMMENTS',
                  COMMENT_CODE int 'LICENSE/INT_RESPONSE/RESP_MESSAGE/COMMENT_CODE',

                  APPROVED char(1) 'LICENSE/RESPONSE/APPROVED',
                                   DATE_EFFECTIVE char(8) 'LICENSE/RESPONSE/DATE_EFFECTIVE',
                         DATE_STAMP char(8) 'LICENSE/RESPONSE/DATE_STAMP',
                         TIME_STAMP char(9) 'LICENSE/RESPONSE/TIME_STAMP',
                  ACTION_REQD char(1) 'LICENSE/RESPONSE/RESP_MESSAGE/ACTION_REQD',
                  COMMENTS varchar(500) 'LICENSE/RESPONSE/RESP_MESSAGE/COMMENTS',
                  COMMENT_CODE int 'LICENSE/RESPONSE/RESP_MESSAGE/COMMENT_CODE'
                  )

      -- Clear memory of XML document
      EXEC sp_xml_removedocument @intDoc
++++++++++++++++++++++++++++++++++++++++++++++++++

20120131-EE-VQP-002

3 Ways to Join

30-Day Free Trial

The Experts

98% positive feedback on 31,087 answers since March 2000. angeliii is a Microsoft Most Valuable Professional for his work with MS SQL Server & Develoment.

He has also proven his knowledge of Visual Basic Programming, PHP Scripting and Oracle Databases.

The Experts

97% positive feedback on 10,752 answers since July 2000. lrmoore has more than 18 years experience in the networking industry.

The six-time Mircosoft MVPs specialties include firewalls, virtual private networking, and network management.

Testimonials

"...and excellent source for support... Kind of like having your very own IT dept." Electriciansnet

Testimonials

"I was apprehensive at signing up at first. However... it has already made my life as an IT administrator much easier." JaCrews

Testimonials

"WOW! You guys have great, active, and knowledgeable people on here." moore50

Business Clients

Business Clients

In the Press

"If you’ve got a question... Experts Exchange can supply an answer.”

In the Press

"...an invaluable aid for both IT professionals and those who require tech support."

In the Press

"where IT professionals provide quick answers on just about any topic"

Business Account Plans

Loading Advertisement...