2012-05-17 3 views
1

У меня есть документ XML, который в значительной степени структурирован как электронная таблица Excel на основе схемы. В этом файле есть два листа. Как я могу вставить все данные со второго листа в таблицу SQL? Я в основном хочу прямой импорт, но OPENXML продолжает рассказывать мне о поврежденных строках. Ниже приведен пример XML-документа:SQL Server 2008 OPENXML Insert

<Worksheet ss:Name="Product Level Data"> 
<x:WorksheetOptions xmlns="urn:schemas-microsoft-com:office:excel"> 
<Print> 
<ValidPrinterInfo/> 
<PaperSizeIndex>1</PaperSizeIndex> 
<Scale>100</Scale> 
<FitWidth>1</FitWidth> 
<FitHeight>1</FitHeight> 
<HorizontalResolution>300</HorizontalResolution> 
<VerticalResolution>300</VerticalResolution> 
</Print> 
<Zoom>100</Zoom> 
<x:PageSetup> 
<x:Header ss:StyleID="systemtitle" Data="The SAS System" 
/> 
</x:PageSetup> 
<Selected/> 
<FreezePanes/> 
<FrozenNoSplit/> 
<SplitHorizontal>1</SplitHorizontal> 
<TopRowBottomPane>1</TopRowBottomPane> 
<ActivePane>2</ActivePane> 
<Panes> 
<Pane> 
<Number>3</Number> 
</Pane> 
<Pane> 
<Number>2</Number> 
</Pane> 
</Panes> 
<ProtectObjects>False</ProtectObjects> 
<ProtectScenarios>False</ProtectScenarios> 
</x:WorksheetOptions> 
<AutoFilter x:Range="R1C1:R545C10" xmlns="urn:schemas-microsoft-com:office:excel"></AutoFilter><Table ss:StyleID="_body"> 
<ss:Column ss:AutoFitWidth="1" ss:Width="90"/> 
<ss:Column ss:AutoFitWidth="1" ss:Width="270"/> 
<ss:Column ss:AutoFitWidth="1" ss:Width="90"/> 
<ss:Column ss:AutoFitWidth="1" ss:Width="90"/> 
<ss:Column ss:AutoFitWidth="1" ss:Width="90"/> 
<ss:Column ss:AutoFitWidth="1" ss:Width="90"/> 
<ss:Column ss:AutoFitWidth="1" ss:Width="90"/> 
<ss:Column ss:AutoFitWidth="1" ss:Width="90"/> 
<ss:Column ss:AutoFitWidth="1" ss:Width="108"/> 
<ss:Column ss:AutoFitWidth="1" ss:Width="108"/> 
<Row ss:AutoFitHeight="1"> 
<Cell ss:StyleID="header__c" ss:Index="1"><Data ss:Type="String">ID</Data></Cell> 
<Cell ss:StyleID="header__c" ss:Index="2"><Data ss:Type="String">Company Name</Data></Cell> 
<Cell ss:StyleID="header__l" ss:Index="3"><Data ss:Type="String">Item</Data></Cell> 
<Cell ss:StyleID="header__c" ss:Index="4"><Data ss:Type="String">Type</Data></Cell> 
<Cell ss:StyleID="header__r1" ss:Index="5"><Data ss:Type="String">Total Time</Data></Cell> 
<Cell ss:StyleID="header__r1" ss:Index="6"><Data ss:Type="String">Total Amount</Data></Cell> 
<Cell ss:StyleID="header__r1" ss:Index="7"><Data ss:Type="String">Count Product</Data></Cell> 
<Cell ss:StyleID="header__r" ss:Index="8"><Data ss:Type="String">Percentage Time</Data></Cell> 
<Cell ss:StyleID="header__r" ss:Index="9"><Data ss:Type="String">Product Time</Data></Cell> 
<Cell ss:StyleID="header__r" ss:Index="10"><Data ss:Type="String">Invalid Product Time</Data></Cell> 
</Row> 
<Row ss:AutoFitHeight="1"> 
<Cell ss:StyleID="data__l" ss:Index="1"><Data ss:Type="String">DF</Data></Cell> 
<Cell ss:StyleID="data__l" ss:Index="2"><Data ss:Type="String">Dan's Fruit Company</Data></Cell> 
<Cell ss:StyleID="data__l" ss:Index="3"><Data ss:Type="String">Apple</Data></Cell> 
<Cell ss:StyleID="data__r" ss:Index="4"><Data ss:Type="String">Fruit</Data></Cell> 
<Cell ss:StyleID="data__r1" ss:Index="5"><Data ss:Type="Number">2034004</Data></Cell> 
<Cell ss:StyleID="data__r1" ss:Index="6"><Data ss:Type="Number">23423</Data></Cell> 
<Cell ss:StyleID="data__r1" ss:Index="7"><Data ss:Type="Number">15789</Data></Cell> 
<Cell ss:StyleID="data__r" ss:Index="8"><Data ss:Type="Number">100.0</Data></Cell> 
<Cell ss:StyleID="data__r" ss:Index="9"><Data ss:Type="Number">0.000</Data></Cell> 
<Cell ss:StyleID="data__r" ss:Index="10"><Data ss:Type="Number">0.000</Data></Cell> 
</Row> 

Вот код, который я пытаюсь. Это первый раз, когда я пытался использовать OPENXML:

DECLARE @XMLDocPointer INT 
, @strXML VARCHAR(10000) 

SET @strXML = <large code block up there> 

EXEC sp_xml_preparedocument @XMLDocPointer OUTPUT, @strXML 

BEGIN TRANSACTION 
INSERT INTO xml_staging_table 
(
id 
, company_name 
, item 
, type 
, total_time 
, total_amount 
, count_product 
, percent_time 
, product_time 
, invalid_product_time 
) 
SELECT id 
, company_name 
, item 
, type 
, total_time 
, total_amount 
, count_product 
, percentage_time 
, product_time 
, invalid_product_time 
FROM OPENXML(@XMLDocPointer,'/WORKSHEET/TABLE/ROW/CELL', 4) --What is the correct syntax here? 
WITH 
(
id VARCHAR(10) 'id/.' 
, company_name VARCHAR(500) 'company_name/.' 
, item VARCHAR(10) 'item/.' 
, type VARCHAR(50) 'type/.' 
, total_time BIGINT 'total_time/.' 
, total_amount BIGINT 'total_amount/.' 
, count_product BIGINT 'count_product/.' 
, percentage_time DECIMAL(5,2) 'percentage_time/.' 
, product_time BIGINT 'product_time/.' 
, invalid_product_time BIGINT 'invalid_product_time/.' 
) 
COMMIT 

EXEC sp_xml_removedocument @XMLDocPointer 

ответ

2

Не знаете, как сделать это с OPENQUERY - это не рекомендуется, вы должны использовать XQuery support in SQL Server 2005 и новее непосредственно.

также: ваш XML является неполным в том, что он не показывает определение пространства имен XML ss: где угодно - но не обращая внимания, что - вы должны быть в состоянии получить данные с SQL заявление что-то вроде этого:

-- reduced huge XML to the actual relevant parts... 
-- defined "dummy" XML namespace for ss: prefix 
DECLARE @input XML = '<Worksheet ss:Name="Product Level Data" xmlns:ss="urn:test"> 
<Table ss:StyleID="_body"> 
    <Row ss:AutoFitHeight="1"> 
    <Cell ss:StyleID="data__l" ss:Index="1"><Data ss:Type="String">DF</Data></Cell> 
    <Cell ss:StyleID="data__l" ss:Index="2"><Data ss:Type="String">Dan''s Fruit Company</Data></Cell> 
    <Cell ss:StyleID="data__l" ss:Index="3"><Data ss:Type="String">Apple</Data></Cell> 
    <Cell ss:StyleID="data__r" ss:Index="4"><Data ss:Type="String">Fruit</Data></Cell> 
    <Cell ss:StyleID="data__r1" ss:Index="5"><Data ss:Type="Number">2034004</Data></Cell> 
    <Cell ss:StyleID="data__r1" ss:Index="6"><Data ss:Type="Number">23423</Data></Cell> 
    <Cell ss:StyleID="data__r1" ss:Index="7"><Data ss:Type="Number">15789</Data></Cell> 
    <Cell ss:StyleID="data__r" ss:Index="8"><Data ss:Type="Number">100.0</Data></Cell> 
    <Cell ss:StyleID="data__r" ss:Index="9"><Data ss:Type="Number">0.000</Data></Cell> 
    <Cell ss:StyleID="data__r" ss:Index="10"><Data ss:Type="Number">0.000</Data></Cell> 
    </Row> 
</Table> 
</Worksheet>' 

SELECT 
    XmlCell.value('(.)[1]', 'varchar(50)') 
FROM 
    @Input.nodes('/Worksheet/Table/Row/Cell/Data') AS Nodes(XmlCell) 

Это дает мне выход:

DF 
Dan's Fruit Company 
Apple 
Fruit 
2034004 
23423 
15789 
100.0 
0.000 
0.000 

Update: обрабатывать «полный» входной XML, и просто извлечения клеток, которые имеют StyleID, что что-то Лик e data...., вы можете использовать этот оператор T-SQL - опять же, он должен знать определение пространства имен XML ss: - я просто «подделал» его здесь на то, что я выбрал, - замените это своим фактическим пространством имен XML для префикса ss::

;WITH XMLNAMESPACES('urn:test' AS ss), 
XmlParsedData AS 
(
SELECT 
    CellStyle = XmlCell.value('@ss:StyleID', 'varchar(50)'), 
    CellIndex = XmlCell.value('@ss:Index', 'int'), 
    CellValue = XmlCell.value('(Data)[1]', 'varchar(50)') 
FROM 
    @Input.nodes('/Worksheet/Table/Row/Cell') AS Nodes(XmlCell) 
) 
SELECT * 
FROM XmlParsedData 
WHERE 
    CelLStyle LIKE 'data%' 

Это даст вам выход, как:

CellStyle CellIndex CellValue 
data__l  1  DF 
data__l  2  Dan's Fruit Company 
data__l  3  Apple 
data__r  4  Fruit 
data__r1  5  2034004 
data__r1  6  23423 
data__r1  7  15789 
data__r  8  100.0 
data__r  9  0.000 
data__r  10  0.000 
+0

будет добавлять эти ненужные части назад до сих пор делает эту работу? Причина, по которой я спрашиваю, заключается в том, что я хочу напрямую ссылаться на файл. – eek142

+1

@ eek142: да, он также будет работать с вашим полным XML, если вы дадите правильное определение префикса пространства имен ss: 'XML –

+0

. Не является ли пространство имен XML в этой строке: eek142

Смежные вопросы