2016-07-26 50 views
2

有人能夠幫助我我想導入一個XML文件到SQL服務器表。我可以導入所需的數據,但在獲取所需格式時遇到了一些麻煩。導入XML到SQL表格和格式數據

declare @input XML = '<Sub> 
    <Results> 
    <Result> 
     <ids> 
     <id> 
      <type>code</type> 
      <value>9004a3d2</value> 
     </id> 
     <id> 
      <type>username</type> 
      <value>jbloggs001</value> 
      <date>20160725</date> 
     </id> 
     <id> 
     <type>EmployeeID</type> 
     <value></value> 
     <date>20160725</date> 
     </id> 
    </ids> 
    </Result> 
</Results> 
</Sub>' 
    SELECT 
    datatype = XCol.value('(type)[1]','varchar(25)'), 
    datavalue = XCol.value('(value)[1]','varchar(50)') 
    FROM 
     @input.nodes('/Sub/Results/Result/ids/id') AS XTbl(XCol) 

這給了3列,如:

datatype  datavalue 
-------------------------------- 
    code  9004a3d2 
    username jbloggs001 
    employeeID

是否有可能得到它導入爲?

EmployeeID USername  Code 
    --------------------------------- 
jbloggs 0019004a3d2 

感謝

+2

你需要使用PIVOT - 檢出:https://technet.microsoft.com/en-us/library/ms177410(v=sql.105).aspx –

回答

2

至於建議中可以做使用PIVOT評論:

SELECT * 
    FROM (
    SELECT 
    datatype = XCol.value('(type)[1]','varchar(25)'), 
    datavalue = XCol.value('(value)[1]','varchar(50)') 
    FROM 
     @input.nodes('/Sub/Results/Result/ids/id') AS XTbl(XCol) 
    ) as p 
    PIVOT (
     MAX(datavalue) FOR datatype IN (EmployeeID,username,code) 
    ) as pvt 

輸出:

EmployeeID username code 
jbloggs001 9004a3d2 

如果輸入始終與同type S:

SELECT XCol.value('(id/value)[3]','varchar(50)') as EmployeeID, 
     XCol.value('(id/value)[2]','varchar(50)') as username, 
     XCol.value('(id/value)[1]','varchar(50)') as code 
FROM @input.nodes('/Sub/Results/Result/ids') AS XTbl(XCol) 
+0

'PIVOT'解決方案是fi ne(從我這邊+1),但我不會依賴XML中的排序順序。使用XML的一個原因是不破壞現有解決方案的可擴展性。使用適當的XQuery獲得節點更加安全(請參閱我的答案...) – Shnugo

1

下面的查詢方式更適合您的解決方案

Select [EmployeeID],[Username],[Code] 
FROM #TEMP 
PIVOT 
(
MAX(DATAVALUE) FOR DATATYPE IN (code,username,employeeID) 
)A 
1

另一種選擇是XQuery中包含的功能

declare @input XML = '<Sub> 
    <Results> 
    <Result> 
     <ids> 
     <id> 
      <type>code</type> 
      <value>9004a3d2</value> 
     </id> 
     <id> 
      <type>username</type> 
      <value>jbloggs001</value> 
      <date>20160725</date> 
     </id> 
     <id> 
     <type>EmployeeID</type> 
     <value></value> 
     <date>20160725</date> 
     </id> 
    </ids> 
    </Result> 
</Results> 
</Sub>'; 
    SELECT 
    code = XCol.value('(id[contains((./type)[1],"code")]/value)[1]','varchar(50)'), 
    username = XCol.value('(id[contains((./type)[1],"username")]/value)[1]','varchar(50)'), 
    EmployeeID = XCol.value('(id[contains((./type)[1],"EmployeeID")]/value)[1]','varchar(50)') 

    FROM 
     @input.nodes('/Sub/Results/Result/ids') AS XTbl(XCol); 
0

另一個非常直和類型安全的方法是這樣的:

SELECT id.value('(id[type="code"]/value)[1]','varchar(max)') AS code 
     ,id.value('(id[type="username"]/value)[1]','varchar(max)') AS username 
     ,id.value('(id[type="EmployeeID"]/value)[1]','varchar(max)') AS EmployeeID 
FROM @input.nodes('Sub/Results/Result/ids') AS A(id)