The Execute method of the XML Bulk Load object model takes two parameters. The first parameter is the mapping schema file. The second parameter provides the XML data that is to be loaded in the database. There are two ways to pass the XML data to the Execute method of XML Bulk Load:
-
Specify the file name as the parameter.
-
Pass a stream that contains the XML data.
This example illustrates how to bulk load from a stream.
VBScript first executes a SELECT statement to retrieve customer information from the Customers table in the Northwind database. Because the FOR XML clause is specified (with the ELEMENTS option) in the SELECT statement, the query returns an element-centric XML document of this form:
<Customer>
<CustomerID>..</CustomerID>
<CompanyName>..</CompanyName>
<City>..</City>
</Customer>
...
The script then passes the XML as a stream to the Execute method as its second parameter. The Execute method bulk loads the data into the Cust table.
Because this script sets the SchemaGen property to TRUE and SGDropTables property to TRUE, XML Bulk Load creates the Cust table in the specified database. (If the table already exists, it first drops the table and then re-creates it.)
This is the VBScript example:
Set objBL = CreateObject("SQLXMLBulkLoad.SQLXMLBulkload.4.0")
Set objCmd = CreateObject("ADODB.Command")
Set objConn = CreateObject("ADODB.Connection")
Set objStrmOut = CreateObject ("ADODB.Stream")
objBL.ConnectionString = "provider=SQLOLEDB;data source=localhost;database=tempdb;integrated security=SSPI"
objBL.ErrorLogFile = "c:\error.log"
objBL.CheckConstraints = True
objBL.SchemaGen = True
objBL.SGDropTables = True
objBL.XMLFragment = True
' Open a connection to the instance of SQL Server to get the source data.
objConn.Open "provider=SQLOLEDB;server=(local);database=tempdb;integrated security=SSPI"
Set objCmd.ActiveConnection = objConn
objCmd.CommandText = "SELECT CustomerID, CompanyName, City FROM Customers FOR XML AUTO, ELEMENTS"
' Open the return stream and execute the command.
Const adCRLF = -1
Const adExecuteStream = 1024
objStrmOut.Open
objStrmOut.LineSeparator = adCRLF
objCmd.Properties("Output Stream").Value = objStrmOut
objCmd.Execute , , adExecuteStream
objStrmOut.Position = 0
' Execute bulk load. Read source XML data from the stream.
objBL.Execute "SampleSchema.xml", objStrmOut
Set objBL = Nothing
The following XSD mapping schema provides the necessary information to create the table:
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:sql="urn:schemas-microsoft-com:mapping-schema">
<xsd:element name="ROOT" sql:is-constant="true" >
<xsd:complexType>
<xsd:sequence>
<xsd:element ref="Customers"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element name="Customers" sql:relation="Cust" >
<xsd:complexType>
<xsd:sequence>
<xsd:element name="CustomerID"
type="xsd:string"
sql:datatype="nvarchar(5)"/>
<xsd:element name="CompanyName"
type="xsd:string"
sql:datatype="nvarchar(40)"/>
<xsd:element name="City"
type="xsd:string"
sql:datatype="nvarchar(40)"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:schema>
This is equivalent XDR schema:
<?xml version="1.0" ?>
<Schema xmlns="urn:schemas-microsoft-com:xml-data"
xmlns:dt="urn:schemas-microsoft-com:xml:datatypes"
xmlns:sql="urn:schemas-microsoft-com:xml-sql" >
<ElementType name="CustomerID" dt:type="int" />
<ElementType name="CompanyName" dt:type="string" />
<ElementType name="City" dt:type="string" />
<ElementType name="root" sql:is-constant="1">
<element type="Customers" />
</ElementType>
<ElementType name="Customers" sql:relation="Cust" >
<element type="CustomerID" sql:field="CustomerID" />
<element type="CompanyName" sql:field="CompanyName" />
<element type="City" sql:field="City" />
</ElementType>
</Schema>
Opening a Stream on an Existing File
You can also open a stream on an existing XML data file and pass the stream as a parameter to the Execute method (instead of passing the file name as the parameter).
This is a Visual Basic example of passing a stream as the parameter:
Private Sub Form_Load()
Dim objBL As New SQLXMLBulkLoad
Dim objStrm As New ADODB.Stream
Dim objFileSystem As New Scripting.FileSystemObject
Dim objFile As Scripting.TextStream
MsgBox "Begin BulkLoad..."
objBL.ConnectionString = "provider=SQLOLEDB;data source=localhost;database=tempdb;integrated security=SSPI"
objBL.ErrorLogFile = "c:\error.log"
objBL.CheckConstraints = True
objBL.SchemaGen = True
objBL.SGDropTables = True
' Here again a stream is specified that contains the source data
' (instead of the file name). But this is just an illustration.
' Usually this is useful if you have an XML data
' stream that is created by some other means that you want to bulk
' load. This example starts with an XML text file, so it may not be the
' best to use a stream (you can specify the file name directly).
' Here you could have specified the file name itself.
Set objFile = objFileSystem.OpenTextFile("c:\SampleData.xml")
objStrm.Open
objStrm.WriteText objFile.ReadAll
objStrm.Position = 0
objBL.Execute "c:\SampleSchema.xml", objStrm
Set objBL = Nothing
MsgBox "Done."
End Sub
To test the application, use the following XML document in a file (SampleData.xml) and the XSD schema that is provided in this example:
This is the XML source data (SampleData.xml):
<ROOT>
<Customers>
<CustomerID>1111</CustomerID>
<CompanyName>Hanari Carnes</CompanyName>
<City>NY</City>
<Order OrderID="1" />
<Order OrderID="2" />
</Customers>
<Customers>
<CustomerID>1112</CustomerID>
<CompanyName>Toms Spezialitten</CompanyName>
<City>LA</City>
<Order OrderID="3" />
</Customers>
<Customers>
<CustomerID>1113</CustomerID>
<CompanyName>Victuailles en stock</CompanyName>
<Order CustomerID= "4444" OrderID="4" />
</Customers>
</ROOT>
This is the equivalent XDR schema:
<?xml version="1.0" ?>
<Schema xmlns="urn:schemas-microsoft-com:xml-data"
xmlns:dt="urn:schemas-microsoft-com:xml:datatypes"
xmlns:sql="urn:schemas-microsoft-com:xml-sql" >
<ElementType name="Order" sql:relation="CustOrder" >
<AttributeType name="OrderID" />
<AttributeType name="CustomerID" />
<attribute type="OrderID" />
<attribute type="CustomerID" />
</ElementType>
<ElementType name="CustomerID" dt:type="int" />
<ElementType name="CompanyName" dt:type="string" />
<ElementType name="City" dt:type="string" />
<ElementType name="root" sql:is-constant="1">
<element type="Customers" />
</ElementType>
<ElementType name="Customers" sql:relation="Cust" >
<element type="CustomerID" sql:field="CustomerID" />
<element type="CompanyName" sql:field="CompanyName" />
<element type="City" sql:field="City" />
<element type="Order" >
<sql:relationship
key-relation="Cust"
key="CustomerID"
foreign-key="CustomerID"
foreign-relation="CustOrder" />
</element>
</ElementType>
</Schema>