早安技师,
愿任何人分享你的专长。
我有一个带有文档类型定义的XML文档(1GB大小)。
我需要将数据加载到sql表,但挑战是必须在运行时创建的表结构取决于.dtd文件。
.dtd文件会根据客户与客户的不断变化
我是xml的新手,请帮帮我。如果需要,我可以提供xml和.dtd。
代码我习惯将数据从xml提取到表格
;With Cte
AS
(SELECT i.value('(../@action)[1]','varchar(20)') AppAction,
i.value('(../@id)[1]','varchar(20)') AppId,
i.value('.','varchar(20)') Notes,
i.value('(../BaseVehicle/@id)[1]','varchar(20)') BaseVehicle,
k.value('(./Qual/@id)[1]','varchar(20)') Qual,
i.value('(../Qty)[1]','varchar(20)') Qty,
i.value('(../PartType/@id)[1]','varchar(20)') PartType,
i.value('(../SubModel/@id)[1]','varchar(20)') SubModel,
i.value('(../EngineBase/@id)[1]','varchar(20)') EngineBase,
i.value('(../EngineVIN/@id)[1]','varchar(20)') EngineVIN,
k.value('(./MfrLabel)[1]','varchar(20)') MfrLabel,
i.value('(../Position/@id)[1]','varchar(20)') PositionId,
i.value('(../Part)[1]','varchar(20)') Part,
k.value('(./Qual/param/@value)[1]','varchar(20)') ParamValue,
j.value('.','varchar(20)') RecordCount
FROM @X.nodes('AMUL/App[@action="A"]/Note') x(i)
OUTER APPLY x.i.nodes('../../Footer/RecordCount')y(j)
OUTER APPLY y.j.nodes('../../App')z(k))
SELECT
AppAction,AppId,BaseVehicle,Qual,Qty,PartType,MfrLabel,PositionId,Part,ParamValue,SubModel,EngineBase,EngineVIN,RecordCount,
STUFF((SELECT ' ; ' + Notes
FROM Cte X WHERE X.BaseVehicle = Y.BaseVehicle
GROUP BY BaseVehicle,Notes
FOR XML PATH('')), 1, 2, '') Note
FROM Cte Y
GROUP BY
BaseVehicle,AppAction,AppId,Qual,Qty,PartType,MfrLabel,PositionId,Part,ParamValue,SubModel,EngineBase,EngineVIN,RecordCount
非常感谢。
答案 0 :(得分:2)
这是第一次尝试:
它将创建(实际上只是声明)四个表(文件,app,qual和note) 您的数据将使用创建的外键插入。 最后一行是完全连接的结果集 我将所有XML节点都包含在目标表中,以确保丢失的信息不会丢失......
只需将整个事物复制到一个空的查询窗口中,执行并探索最终结果是否符合您的需求。
如果是,请不要忘记投票并接受。这需要付出相当大的努力: - )
快乐的编码!
DECLARE @x xml='<?xml version="1.0" encoding="utf-8"?>
<ACES version="3.0">
<Header>
<Company>Godrej</Company>
<SenderName>chail</SenderName>
<SenderPhone>xxx-712-xxxx</SenderPhone>
<TransferDate>2009-09-30</TransferDate>
<BrandAAIAID>tbzx</BrandAAIAID>
<DocumentTitle>Godrej Data</DocumentTitle>
<EffectiveDate>2009-09-30</EffectiveDate>
<SubmissionType>FULL</SubmissionType>
<xcdbVersionDate>2008-08-28</xcdbVersionDate>
<reltersionDate>2008-06-10</reltersionDate>
<xcbdVersionDate>2020-09-25</xcbdVersionDate>
</Header>
<App action="A" id="1">
<BaseVehicle id="2555"/>
<Qual id="15231">
<text>Light Duty Brakes</text>
</Qual>
<Qty>2</Qty>
<PartType id="10054"/>
<MfrLabel>Professional Grade</MfrLabel>
<Position id="22"/>
<Part>816-4000</Part>
</App>
<App action="A" id="3">
<BaseVehicle id="2557"/>
<Qual id="15231">
<text>Light Duty Brakes</text>
</Qual>
<Qty>2</Qty>
<PartType id="10054"/>
<MfrLabel>Professional Grade</MfrLabel>
<Position id="22"/>
<Part>816-4000</Part>
</App>
<App action="A" id="908">
<BaseVehicle id="1513"/>
<Qual id="9174">
<text>Standard Nut</text>
</Qual>
<Qual id="21521">
<text>Requires Stamped Retainer And Cotter Pin</text>
</Qual>
<Qty>2</Qty>
<PartType id="10054"/>
<MfrLabel>Professional Grade</MfrLabel>
<Position id="22"/>
<Part>816-4018</Part>
</App>
<App action="A" id="4007">
<BaseVehicle id="7947"/>
<Qual id="9743">
<param value="8/91"/>
<text>Thru 8/91</text>
</Qual>
<Qty>2</Qty>
<PartType id="10014"/>
<MfrLabel>Professional Grade</MfrLabel>
<Position id="22"/>
<Part>816-4265</Part>
</App>
<App action="A" id="1">
<BaseVehicle id="5861" />
<Note>Manual</Note>
<Qty>1</Qty>
<PartType id="13117" />
<Position id="12" />
<Part>955-304</Part>
</App>
<App action="A" id="9951">
<BaseVehicle id="3883" />
<Note>Reflector</Note>
<Note>Packaging Type: Box</Note>
<Qty>1</Qty>
<PartType id="11720" />
<Position id="88" />
<Part>1650140</Part>
</App>
<App action="A" id="16578">
<BaseVehicle id="18667" />
<SubModel id="694" />
<Note>Composite Type</Note>
<Note>Smoked Lens, w/Black Trim</Note>
<Qty>1</Qty>
<PartType id="10762" />
<Position id="12" />
<Part>1591142</Part>
</App>
<App action="A" id="19633">
<BaseVehicle id="18659" />
<Note>Power</Note>
<Note>w/Heat</Note>
<Note>wo/Memory</Note>
<Qty>1</Qty>
<PartType id="13117" />
<Position id="12" />
<Part>955-1162</Part>
</App>
<App action="A" id="83948">
<BaseVehicle id="4470" />
<Note>Compare to Original</Note>
<Note>Bulb Call-Out Size: 194</Note>
<Note>Wattage: 1.2</Note>
<Note>Light Color: White</Note>
<Qty>1</Qty>
<PartType id="11730" />
<Position id="1" />
<Part>194W-SMD</Part>
</App>
<App action="A" id="2">
<BaseVehicle id="4935" />
<Note>M14 x 1.50 Thread</Note>
<Note>Package Quantity: 5</Note>
<Note>Dorman - AutoGrade - Boxed</Note>
<Note>Packaging Type: Box</Note>
<Qty>1</Qty>
<PartType id="5560" />
<Position id="1" />
<Part>090-053</Part>
</App>
<App action="A" id="288250">
<BaseVehicle id="16865" />
<SubModel id="20" />
<EngineBase id="5461" />
<EngineVIN id="40" />
<Note>Wheel Lock Type: Female Spline</Note>
<Note>Package Quantity: 4</Note>
<Note>Packaging Type: Card</Note>
<Note>Thread Size: 1/2-20</Note>
<Note>Chrome</Note>
<Note>Overall Length (In): 1.425</Note>
<Note>Steel</Note>
<Note>Thread Handling: Right Hand Thread</Note>
<Qty>1</Qty>
<PartType id="16214" />
<Position id="1" />
<Part>711-221</Part>
</App>
<Footer>
<RecordCount>1772522</RecordCount>
</Footer>
</ACES>';
DECLARE @tblFile TABLE(FileID INT
,ACES_Version VARCHAR(10)
,Header_Company VARCHAR(100)
,Header_SenderName VARCHAR(100)
--further Header-fields here
,Footer_RecordCount INT
,HeaderNode XML
,FooterNode XML);
INSERT INTO @tblFile
SELECT 1 AS FileID --Add something senseful here
,@x.value('/ACES[1]/@version','varchar(max)') AS ACES_Version
,@x.value('(/ACES/Header/Company)[1]','varchar(max)') AS Header_Company
,@x.value('(/ACES/Header/SenderName)[1]','varchar(max)') AS Header_SenderName
--further fields of header here
,@x.value('(/ACES/Footer/RecordCount)[1]','int') AS ACES_RecordCount
,@x.query('/ACES/Header') AS HeaderNode
,@x.query('/ACES/Footer') AS FooterNode;
DECLARE @tblApp TABLE(AppID INT
,FileID INT
,Action VARCHAR(10)
,ID INT
,BaseVehicleID INT
,Qty INT
--further App-fields here
,QualNodes XML
,NoteNodes XML
,AppNode XML);
INSERT INTO @tblApp
SELECT ROW_NUMBER() OVER(ORDER BY One.App.value('@id','int')) AS AppID
,1 AS FileID --Add something senseful here
,One.App.value('@action','varchar(10)') AS Action
,One.App.value('@id','int') AS ID
,One.App.value('BaseVehicle[1]/@id','int') AS BaseVehicleID
,One.App.value('Qty[1]','int') AS Qty
--further App-fields here
,'<Quals>' + CAST(One.App.query('Qual') AS VARCHAR(MAX)) + '</Quals>' AS QualNodes
,'<Notes>' + CAST(One.App.query('Note') AS VARCHAR(MAX)) + '</Notes>' AS NoteNodes
,One.App.query('.') AS AppNode
FROM @x.nodes('/ACES/App') AS One(App);
DECLARE @tblQual TABLE(AppID INT
,FileID INT
,QualID INT
,ID INT
,Text VARCHAR(150)
,ParamValue VARCHAR(150)
,QualNode XML);
INSERT INTO @tblQual
SELECT AppID
,FileID
,ROW_NUMBER() OVER(PARTITION BY AppID ORDER BY One.Qual.value('@id','int')) AS QualID
,One.Qual.value('@id','int') AS ID
,One.Qual.value('text[1]','varchar(max)') AS Text
,One.Qual.value('param[1]/@value','varchar(max)') AS ParamValue
,One.Qual.query('.') AS QualNode
FROM @tblApp AS tblApp
CROSS APPLY tblApp.QualNodes.nodes('/Quals/Qual') One(Qual)
DECLARE @tblNotes TABLE(AppID INT
,FileID INT
,NoteID INT
,ID INT
,NoteText VARCHAR(150)
,NoteNode XML);
INSERT INTO @tblNotes
SELECT AppID
,FileID
,ROW_NUMBER() OVER(PARTITION BY AppID ORDER BY (SELECT NULL)) AS NoteID
,One.Note.value('@id','int') AS ID
,One.Note.value('.','varchar(max)') AS NoteText
,One.Note.query('.') AS NoteNode
FROM @tblApp AS tblApp
CROSS APPLY tblApp.NoteNodes.nodes('/Notes/Note') One(Note)
SELECT *
FROM @tblFile AS f
INNER JOIN @tblApp AS a ON f.FileID=a.FileID
LEFT JOIN @tblQual AS q ON q.AppID=a.AppID
LEFT JOIN @tblNotes AS n ON n.AppID=a.AppID