sql
  • sql-server
  • xml
  • null
  • decimal
  • 2016-08-17 71 views 1 likes 
    1

    如何簡單地插入NULL如果節點爲空或不存在?空XML節點會導致錯誤轉換數據類型爲varchar到數字

    CREATE TABLE myxml (
        "hours" DECIMAL(11,2) 
    ); 
    
    DECLARE @xml XML = 
    '<?xml version="1.0" encoding="UTF-8"?> 
    <Data> 
        <Employee> 
         <NUMHOURS>0.5</NUMHOURS> 
        </Employee> 
        <Employee/> 
        <Employee> 
         <NUMHOURS>5</NUMHOURS> 
        </Employee> 
        <Employee> 
         <NUMHOURS/> 
        </Employee> 
    </Data>'; 
    
    INSERT INTO myxml ("hours") 
    SELECT 
        t.c.value('NUMHOURS[1]','DECIMAL(11,2)') 
    FROM @xml.nodes('/Data/Employee') t(c) 
    

    空節點<NUMHOURS/>原因:

    誤差變換數據類型爲nvarchar到數字。

    我曾嘗試:

    NULLIF(t.c.value('NUMHOURS[1]','DECIMAL(11,2)'),'') 
    

    但似乎導致同樣的錯誤在事後得到處理。

    +0

    空節點不被視爲無效,它被認爲是一個空的[B]字符串[/ B]。相反,沒有節點被認爲是空的。在你的情況下,你應該使用'CAST(NULLIF(t.c.value('NUMHOURS [1]','varchar(13)'),'')AS DECIMAL(11,2))''。你可以改變'VARCHAR(13)'更大的東西,以適應爲無效值(不適合'十進制(11,2)') –

    +0

    或者你可以嘗試'選擇tcvalue('(./文()) 1]」, 'DECIMAL(11,2)')FROM @ xml.nodes( '/數據/員工/ NUMHOURS')T(C)' – JamieD77

    回答

    2

    你可以爲無效號碼提供一個默認值:

    select case 
          when ISNUMERIC(t.c.value('NUMHOURS[1]', 'nvarchar(100)')) <> 1 then NULL 
          else t.c.value('NUMHOURS[1]', 'decimal(11,2)') 
         end 
        from @xml.nodes('/Data/Employee') t(c) 
    
    +0

    的問題是如何將'NULL'所以我編輯你的答案匹配。謝謝! –

    +0

    問題是如何爲空或缺少節點插入NULL,而不是無效值。恕我直言,無效值應該失敗,或者甚至更好的是,在交給SQL Server之前,應該針對DTD或XSD驗證xml。 –

    +0

    我喜歡這種直接的方法,+1從我身邊。您可能對另一個解決方案感興趣,在這個解決方案中,演員在內部完成。我發現這在處理XML類型安全方面非常有幫助...... – Shnugo

    1

    有可能是一個更好的方法:(應至少快了許多行...):

    SELECT t.c.value('let $x:=NUMHOURS[1] return $x cast as xs:decimal?','decimal(11,2)') 
    FROM @xml.nodes('/Data/Employee') t(c); 
    

    的如果可能的話,cast as xs:decimal?會將該值轉換爲十進制值,或返回null。因此,最後'decimal(11,2)'沒有類型轉換的問題由SQL Server中的任何更多...

    相關問題