KB2715289 - 修正:當您在 SQL Server 2008 R2 或 SQL Server 2012 中將 datetimeOffset 欄轉換為 smalldatetime 欄時,當 datetimeoffset 欄上有索引時,結果會不正確

Applies To
SQL Server 2008 R2 Datacenter SQL Server 2008 R2 Developer SQL Server 2008 R2 Enterprise SQL Server 2008 R2 Standard SQL Server 2008 R2 Web SQL Server 2008 R2 Workgroup SQL Server 2012 Business Intelligence SQL Server 2012 Developer SQL Server 2012 Enterprise SQL Server 2012 Standard SQL Server 2012 Web SQL Server 2012 Enterprise Core

Microsoft 會將 Microsoft SQL Server 2008 R2 Service Pack 1 (SP1) 修正程式作為一個可下載的檔案進行發佈。 由於修正程式是累積的,因此每個新版本都包含先前的 SQL Server 2008 R2 Service Pack 1 (SP1) 修正程式版本中包含的所有 Hotfix 和所有安全性修正程式。

症狀

請考慮以下案例:

  • 您在 Microsoft SQL Server 2008 R2 或 Microsoft SQL Server 2012 的資料表中有 MicrosoftTimeOffset 資料類型資料行。
  • 您在 datetimeoffset 資料行上建立索引。
  • 您可以使用 CAST 或 CONVERT 函數將日期時間偏移資料類型轉換為 smalldatetime 資料類型,而不使用樣式引數,或者當樣式引數的值為 0 時。
  • CAST 或 CONVERT 函數的結果會用於 Transact-SQL 查詢的篩選。
  • 執行 Transact-SQL 查詢。

在此案例中,查詢傳回的結果不正確,因為篩選未正確運作。 例如,假設名為 “Date” 的 datetimeoffset 欄包含下列值:

  • 2011-05-21 23:00:00 -01:00
  • 2011-05-21 23:00:00 +00:00
  • 2011-05-21 23:00:00 +01:00

您執行下列查詢:

SELECT Date FROM TestTable WHERE CAST(Date AS smalldatetime)= '2011-05-21 23:00:00'

查詢結果只會傳回一列。 不過,預期的結果應該會傳回這三個值的資料列。

解決方式

累積更新資訊

SQL Server 2012

此問題的修正程式最初在 SQL Server 2012 的累積更新 3 中發行。 如需有關此累積更新套件的詳細資訊,請按一下下面的文章編號,檢視「Microsoft 知識庫」中的文章:

2723749 適用於 SQL Server 2012 的累積更新套件 3 注意:由於這些組建是累積的,因此每個新發行的修正程式都包含所有 Hotfix 和所有安全性修正程式,這些都包含在先前的 SQL Server 2012 修正程式版本中。 Microsoft 建議您考慮套用包含此 Hotfix 的最新修正版本。 如需詳細資訊,請按一下下面的文章編號,檢視「Microsoft 知識庫」中的文章:

2692828 SQL Server 2012 發行之後所發行的 SQL Server 2012 組建 您必須將 SQL Server 2012 Hotfix 套用至 SQL Server 2012 的安裝。

SQL Server 2008 R2 Service Pack 2

此問題的修正程式最初在 SQL Server 2008 R2 Service Pack 2 的累積更新 1 中發行。 如需有關如何取得此累積更新套件的詳細資訊,請按一下下面的文件編號,檢視「Microsoft 知識庫」中的文件:

2720425 SQL Server 2008 R2 Service Pack 2 的累積更新套件 1 注意:由於這些組建是累積的,因此每個新發行的修正程式都包含所有 Hotfix 和先前的 SQL Server 2008 R2 修正程式版本中包含的所有安全性修正程式。 建議您考慮套用包含此 Hotfix 的最新修正版本。 如需詳細資訊,請按一下下面的文章編號,檢視「Microsoft 知識庫」中的文章:

2730301 發行 SQL Server 2008 R2 Service Pack 2 之後所發行的 SQL Server 2008 R2 組建

SQL Server 2008 R2 SP1

此問題的修正程式最初在累積更新 7 中發行。 如需有關如何取得此 SQL Server 2008 R2 Service Pack 1 累積更新套件的詳細資訊,請按一下下面的文件編號,檢視「Microsoft 知識庫」中的文件:

2703282 SQL Server 2008 R2 SP1 的累積更新套件 7 注意 由於這些組建是累積的,因此每個新發行的修正程式都包含先前的 SQL Server 2008 R2 Service Pack 1 修正程式版本中包含的所有 Hotfix 和所有安全性修正程式。 建議您考慮套用包含此 Hotfix 的最新修正版本。 如需詳細資訊,請按一下下面的文章編號,檢視「Microsoft 知識庫」中的文章:

2567616 SQL Server 2008 R2 SP1 發行之後所發行的 SQL Server 2008 R2 組建

更多資訊

若要重現問題,請依照下列步驟執行:

  1. 執行下列查詢以建立含有 datetimeoffset 資料行的資料表,並插入一些記錄:

    CREATE TABLE #TestTimeZones (dto datetimeoffset (0) ) ;移至 插入 #TestTimeZones (DTO) 值 ('2011-05-21 23:00:00 -01:00') , ('2011-05-21 23:00:00 +00:00') , ('2011-05-21 23:00:00 +01:00') ;GO

  2. 執行下列查詢,您會看到這三個值都正確列在傳回的結果中:

    DECLARE @t smalldatetime = '2011-05-21 23:00:00' SELECT dto AS withoutIndex FROM #TestTimeZones WHERE CAST (dto AS smalldatetime) =@t;

  3. 執行下列查詢,以便在 “dto” 欄上建立索引,並重複相同的查詢:

    在 #TestTimeZones (DTO) 上建立索引IX_testTimeZones_Dto;GO -- 重複相同的查詢 DECLARE @t smalldatetime = '2011-05-21 23:00:00' SELECT dto AS withIndex FROM #TestTimeZones WHERE CAST (dto A smalldatetime) =@t;GO

  4. 再次執行步驟 2 中的查詢。 這次,查詢只會傳回一列。

  5. 執行下列查詢以刪除您建立的索引和資料表:

    在 #TestTimeZones 上下降指數IX_testTimeZones_Dto;去掉塔爾貝 #TestTimeZones;GO

參考資料

如需有關 CAST 和 CONVERT 函數的詳細資訊,請前往下列 MSDN 網站:

關於 SQL Server 中 CAST 和 CONVERT 函數的一般資訊

狀態

Microsoft 已確認這是「適用對象」一節中列出的 Microsoft 產品中的問題。