Simple way to Import XML Data into SQL Server with T-SQL

Problem

XML is a data format that shares data in a form that can be easily used and shared. Often, we need to import XML files into SQL Server, and there are several ways to do so. In this tip, we will look at a simple way to do this using T-SQL commands.

Solution

Many possible ways exist to perform this type of import. This tip demonstrates how to use T-SQL and OPENROWSET to read the XML data and load it into a SQL Server table.  Let’s walk through an example.

Step 1 – Create Table to Store Imported Data

Let’s create a simple table that’ll store the data of our customers.

USE mssqltips_db
GO
CREATE TABLE [CUSTOMERS_TABLE](
    [ID] [int] IDENTITY(1,1) NOT NULL,
    [DOCUMENT] [varchar](20) NOT NULL,
    [NAME] [varchar](50) NOT NULL,
    [ADDRESS] [varchar](50) NOT NULL,
    [PROFESSION] [varchar](50) NOT NULL,
 CONSTRAINT [CUSTOMERS_PK] PRIMARY KEY ([Id])
)
GO

Step 2 – Create Sample XML File

Below is a sample of XML data.  You can use this as is or modify it for your tests. I copied this data and stored it in a file named MSSQLTIPS_XML.xml.

<?xml version="1.0" encoding="utf-8"?>
<Customers>
  <Customer>
    <Document>000 000 000</Document>
    <Name>Mary Angel</Name>
    <Address>Your City, YC 1212</Address>
    <Profession>Systems Analyst</Profession>
  </Customer>
  <Customer>
    <Document>000 000 001</Document>
    <Name>John Lenon</Name>
    <Address>Your City, YC 1212</Address>
    <Profession>Driver</Profession>
  </Customer>
  <Customer>
    <Document>000 000 002</Document>
    <Name>Alice Freeman</Name>
    <Address>Your City, YC 1212</Address>
    <Profession>Architect</Profession>
  </Customer>
  <Customer>
    <Document>000 000 003</Document>
    <Name>George Sands</Name>
    <Address>Your City, YC 1212</Address>
    <Profession>Doctor</Profession>
  </Customer>
  <Customer>
    <Document>000 000 004</Document>
    <Name>Mark Oliver</Name>
    <Address>Your City, YC 1212</Address>
    <Profession>Writer</Profession>
  </Customer>
</Customers>

Step 3 – Importing the XML Data File into a SQL Server Table

Next, we need to make SQL Server read the XML file, then import it using the OPENROWSET function. This function is native to T-SQL. It allows us to read data from many different file types through the BULK import feature, which allows the import from lots of file types, like XML.

Here is the code to read the XML file and to INSERT the data into a table.

INSERT INTO CUSTOMERS_TABLE (DOCUMENT, NAME, ADDRESS, PROFESSION)
SELECT
   MY_XML.Customer.query('Document').value('.', 'VARCHAR(20)'),
   MY_XML.Customer.query('Name').value('.', 'VARCHAR(50)'),
   MY_XML.Customer.query('Address').value('.', 'VARCHAR(50)'),
   MY_XML.Customer.query('Profession').value('.', 'VARCHAR(50)')
FROM (SELECT CAST(MY_XML AS xml)
      FROM OPENROWSET(BULK 'C:\temp\MSSQLTIPS_XML.xml', SINGLE_BLOB) AS T(MY_XML)) AS T(MY_XML)
      CROSS APPLY MY_XML.nodes('Customers/Customer') AS MY_XML (Customer);
  • The first thing we are doing is a simple INSERT into our table CUSTOMERS_TABLE.
  • The columns in the SELECT are pulled from the alias we created named MY_XML. We are querying each element of the Customer node.
  • The FROM clause comes from using the OPENROWSET operation using the BULK option and the SINGLE_BLOB option to have the data returned from the XML file into a single column and row. The function nodes(), along with CROSS APPLY, allows navigation through the XML elements to get all of the Customer objects properly encapsulated.

Step 4 – Check the Imported XML Data

After the insert, you can query the table to check the results.

SELECT * FROM CUSTOMERS_TABLE
xml file import query results

Next Steps

10 Comments

  1. I’ve tried the original proposal as well as the modified proposal of Mikael Eriksson, with my own data, but it does not work.
    I’ve looked at the examples multiple times, but do not see any difference.
    Could you please help?

  2. I recreated the sample. Didn’t work for me. Got “Customer is not a invalid function, property, or field” in MY_XML.Customer.query.

    No big. Moving on.

  3. I see now, thanks.

    I tried to run the commands but got syntax error in the following statement at “.value”:

    SELECT
    MY_XML.Customer.query(‘Document’).value(‘.’, ‘VARCHAR(20)’),

    Any idea?

  4. Hi Filip,

    It is a little confusing.

    This is the query the tip is using.

    INSERT INTO CUSTOMERS_TABLE (DOCUMENT, NAME, ADDRESS, PROFESSION)
    SELECT
    MY_XML.Customer.query(‘Document’).value(‘.’, ‘VARCHAR(20)’),
    MY_XML.Customer.query(‘Name’).value(‘.’, ‘VARCHAR(50)’),
    MY_XML.Customer.query(‘Address’).value(‘.’, ‘VARCHAR(50)’),
    MY_XML.Customer.query(‘Profession’).value(‘.’, ‘VARCHAR(50)’)
    FROM (SELECT CAST(MY_XML AS xml)
    FROM OPENROWSET(BULK ‘C:\temp\MSSQLTIPS_XML.xml’, SINGLE_BLOB) AS T(MY_XML)) AS T(MY_XML)
    CROSS APPLY MY_XML.nodes(‘Customers/Customer’) AS MY_XML (Customer);

    The subquery below is part of the above query and is given an alias name using this part of the above query “AS MY_XML (Customer)”.

    SELECT CAST(MY_XML AS xml)
    FROM OPENROWSET(BULK ‘C:\temp\MSSQLTIPS_XML.xml’, SINGLE_BLOB) AS T(MY_XML)) AS T(MY_XML)
    CROSS APPLY MY_XML.nodes(‘Customers/Customer’

    This is done so the query part below can pull data from the subquery using the alias name “AS MY_XML (Customer)”.

    SELECT
    MY_XML.Customer.query(‘Document’).value(‘.’, ‘VARCHAR(20)’),
    MY_XML.Customer.query(‘Name’).value(‘.’, ‘VARCHAR(50)’),
    MY_XML.Customer.query(‘Address’).value(‘.’, ‘VARCHAR(50)’),
    MY_XML.Customer.query(‘Profession’).value(‘.’, ‘VARCHAR(50)’)

  5. Hi Filip,

    You should be able to just run each set of code and this should work.

    For the “alias” info, he is just explaining the code which is using a subquery to gather the data.

    Let me know if you have more questions and I can see if I can help.

  6. It would be nice to have all the steps described here. For people who are doind it for the first time becomes a little confusing when you mention an alias but does not show how to do it.

  7. Hi Marcin,

    I don’t think that is possible. If I find something that says it can be done I will add another comment.

    -Greg

Leave a Reply

Your email address will not be published. Required fields are marked *