Many times our application uses data from external suppliers. These data, mostly
recived by the Internet, is written in XML format and has different from our data
mode structure. But it`s still very important for us so we want to process them
by extracting data from. Of course we may procesing XML documents in CLR or
simple .NET project and than pass them to database but we should this about performance
of each our solution. For example if we recieved 100MB XML document from supplier
and we processed them we still need to send those data to our database which means
that we have to pass data by the network- it`s very costly...
Now assume that the same operation, connected with proccessing XMLdocuemnt, can be done in SQL SERVER side. Looks great don`t You? So let`s begin.
First of all we should learn something more about three things:
Now its time for out table. For this example there is only one table (noncompilant with 2NF and 3NF!).
Now lets try our procedure:
Now assume that the same operation, connected with proccessing XMLdocuemnt, can be done in SQL SERVER side. Looks great don`t You? So let`s begin.
First of all we should learn something more about three things:
- master.dbo.sp_xml_preparedocument: start preparing passed text as XML document with checking document integrity. The first (OUTPUT type) parameter 'idoc' returns handle to XML cached in memory.
- OPENXML (keyword): used to generate table from XML parameters passed as a handle to a file in memory. Allow to processing XML document fragment.
- master.dbo.sp_xml_removedocument: removes all information conected with passed 'idoc' handler.
Now we are able to use elements enumerated above to create simple importing stored
procedure. Let`s assumed that we are going to import the following XML document
fragment (not entire XML document!!):
Code Snippet
- DECLARE @t as ='<Car Brand="Audi">
- <Model Name="A1">
- <Type TypeName="Sendan">
- <EngineType Vol="1.6" Fuel="Benzine" Version="Standard" BasePrince="80000" />
- <EngineType Vol="1.8" Fuel="Benzine" Version="Standard" BasePrince="85000" />
- <EngineType Vol="1.8" Fuel="Benzine" Version="Full" BasePrince="95000" />
- <EngineType Vol="1.9" Fuel="Diseal" Version="Standard" BasePrince="95000" />
- <EngineType Vol="1.9" Fuel="Diseal" Version="Full" BasePrince="105000" />
- </Type>
- <Type TypeName="Coupe">
- <EngineType Vol="1.6" Fuel="Benzine" Version="Standard" BasePrince="81000" />
- <EngineType Vol="1.8" Fuel="Benzine" Version="Standard" BasePrince="86000" />
- <EngineType Vol="1.8" Fuel="Benzine" Version="Full" BasePrince="96000" />
- <EngineType Vol="1.9" Fuel="Diseal" Version="Standard" BasePrince="96000" />
- <EngineType Vol="1.9" Fuel="Diseal" Version="Full" BasePrince="106000" />
- </Type>
- </Model>
- <Model Name="A4">
- <Type TypeName="Sendan">
- <EngineType Vol="1.6" Fuel="Benzine" Version="Standard" BasePrince="110000" />
- <EngineType Vol="1.8" Fuel="Benzine" Version="Standard" BasePrince="115000" />
- <EngineType Vol="1.8" Fuel="Benzine" Version="Full" BasePrince="115000" />
- <EngineType Vol="1.9" Fuel="Diseal" Version="Standard" BasePrince="115000" />
- <EngineType Vol="1.9" Fuel="Diseal" Version="Full" BasePrince="125000" />
- </Type>
- <Type TypeName="AllRoad">
- <EngineType Vol="1.6" Fuel="Benzine" Version="Standard" BasePrince="110000" />
- <EngineType Vol="1.8" Fuel="Benzine" Version="Standard" BasePrince="115000" />
- <EngineType Vol="1.8" Fuel="Benzine" Version="Full" BasePrince="115000" />
- <EngineType Vol="1.9" Fuel="Diseal" Version="Standard" BasePrince="115000" />
- <EngineType Vol="1.9" Fuel="Diseal" Version="Full" BasePrince="125000" />
- </Type>
- </Model>
- </Car>';
Now its time for out table. For this example there is only one table (noncompilant with 2NF and 3NF!).
Code Snippet
- CREATE TABLE dbo.Cars
- (
- CarID int IDENTITY(1,1) PRIMARY KEY,
- CarBrand nvarchar(50) not null,
- ModelName nvarchar(50) not null,
- TypName nvarchar(50) not null,
- Engine float not null,
- FuelType nvarchar(10) not null,
- CarVersion nvarchar(50) not null,
- BasePrince int not null
- )
- GO;
Code Snippet
- CREATE PROCEDURE dbo.ImportCars
- @data xml
- AS
- BEGIN
- DECLARE @handle int; --handler declaration
- --Preparing document
- EXEC master.dbo.sp_xml_preparedocument @handle OUTPUT, @data;
- --Reading XML and inserting selected values
- INSERT INTO dbo.Cars(CarBrand,ModelName,TypName,
- Engine, FuelType, CarVersion ,BasePrince)
- SELECT * FROM OPENXML(@handle, 'Car/Model/Type/EngineType')
- WITH (CarBrand varchar(50) '../../../@Brand', --three nodes up
- Model varchar(50) '../../@Name', --two nodes up
- TypeName varchar(50) '../@TypeName', --one node up
- Engine float '@Vol', --current node attribute
- Fuel nvarchar(10)'@Fuel',
- CarVersion nvarchar(50)'@Version',
- Price int '@BasePrince')
- --remove XML from memory
- EXEC master.dbo.sp_xml_removedocument @handle;
- END
Now lets try our procedure:
EXEC dbo.ImportCars @t
SELECT * FROM dbo.Cars
Thank You.