首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> SQL Server 資料庫 >> 關於SqlServer

SQL Server 2008 XML 進階:Lax 驗證實作細節與日期時間時區保留機制

     編輯:關於SqlServer

Lax 驗證深度解析

processContents 三種模式對比

模式行為適用場景
strict元素必須在 Schema 中定義且驗證通過核心業務資料、嚴格契約
lax若 Schema 中有定義則驗證,否則略過可擴充介面、第三方擴展、版本演進
skip完全不驗證內容完全開放的擴充區塊、原始資料保存

實戰:訂單擴充欄位

基礎 Schema(OrderBase.xsd):

<xs:schema targetNamespace="https://example.com/order" 
           xmlns:xs="https://www.w3.org/2001/XMLSchema"
           xmlns:ord="https://example.com/order"
           elementFormDefault="qualified">
  <xs:complexType name="OrderType">
    <xs:sequence>
      <xs:element name="Buyer" type="xs:string"/>
      <xs:element name="Amount" type="xs:decimal"/>
      <xs:any namespace="##other" processContents="lax" minOccurs="0" maxOccurs="unbounded"/>
    </xs:sequence>
  </xs:complexType>
  <xs:element name="Order" type="ord:OrderType"/>
</xs:schema>

擴充 Schema(ShippingExt.xsd):

<xs:schema targetNamespace="https://example.com/shipping"
           xmlns:xs="https://www.w3.org/2001/XMLSchema"
           xmlns:shp="https://example.com/shipping"
           elementFormDefault="qualified">
  <xs:element name="DeliveryMethod" type="xs:string"/>
  <xs:element name="TrackingNo" type="xs:string"/>
</xs:schema>

XML 實例:

<ord:Order xmlns:ord="https://example.com/order"
           xmlns:shp="https://example.com/shipping">
  <ord:Buyer>John</ord:Buyer>
  <ord:Amount>199.00</ord:Amount>
  <shp:DeliveryMethod>Express</shp:DeliveryMethod>  
  <shp:TrackingNo>TRK12345</shp:TrackingNo>        
  <crm:CustomerTier>Gold</crm:CustomerTier>        
</ord:Order>

結果:前兩個擴充元素通過型別驗證,第三個 crm:CustomerTier 因無對應 Schema 而被 Lax 模式接受。

anyType 的 Lax 內容處理

XSD 規格規定 xs:anyType 等同於 processContents="lax"。SQL Server 2005 錯誤採用 Strict 處理,導致合法的混合內容被拒絕。2008 修正此行為:

<xs:element name="FreeForm" type="xs:anyType"/>

現在可接受任意 Well-formed XML 片段,若其中元素有 Schema 定義則自動驗證。

日期時間時區保留機制

儲存格式對比

-- 2005 行為
DECLARE @x2005 XML = '';
SELECT @x2005.value('(/Root/Time)[1]', 'datetime');  -- 2007-12-25 14:00:00.000 (UTC)

-- 2008 行為
DECLARE @x2008 XML = '';
SELECT @x2008.value('(/Root/Time)[1]', 'datetimeoffset');  -- 2007-12-25 06:00:00.0000000 -08:00

新資料型別對應

XSD 型別SQL Server 2008 對應型別時區保留
xs:dateTimedatetimeoffset是
xs:datedate是(可選時區)
xs:timetime是(可選時區)

注意:若目標欄位為舊型別 datetime,仍會轉換為 UTC;需明確使用 datetimeoffset 才能保留時區。

Union 與 List 型別驗證細節

List 型別空值處理

<AvailableSizes></AvailableSizes>(空內容)→ 合法(空列表)
<AvailableSizes> </AvailableSizes>(空白)→ 合法(空白會被標準化移除)

Union 型別優先順序

驗證時依 memberTypes 宣告順序嘗試匹配,首個匹配成功即通過。建議將限制較嚴格的型別放在前面。

升級測試建議

  1. 匯出現有 XML Schema 集合,於 2008 還原並執行 sys.xml_schema_collections 完整性檢查。
  2. 針對含 xs:any 的 Schema,建立測試資料集驗證 Lax 行為是否符合預期。
  3. 日期時間欄位抽樣比對 2005/2008 儲存值差異,確認業務邏輯相容性。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved