KB2715289 — POPRAWKA: Niepoprawne wyniki podczas konwertowania kolumny datetimeoffset na kolumnę smalldatetime w SQL Server 2008 R2 lub w SQL Server 2012, gdy w kolumnie datetimeoffset znajduje się indeks

Dotyczy
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

Firma Microsoft dystrybuuje poprawki dla programu Microsoft SQL Server 2008 R2 z dodatkiem Service Pack 1 (SP1) w jednym pliku do pobrania. Ponieważ poprawki są zbiorcze, każda nowa wersja zawiera wszystkie poprawki i poprawki zabezpieczeń zawarte w poprzedniej wersji poprawki programu SQL Server 2008 R2 z dodatkiem Service Pack 1 (SP1).

Objawy

Rozważmy następujący scenariusz:

  • Masz kolumnę danych datetimeoffset w tabeli w systemie Microsoft SQL Server 2008 R2 lub Microsoft SQL Server 2012.
  • Indeks jest tworzony na podstawie kolumny datetimeoffset (data/przesunięcie).
  • Typ danych datetimeoffset można przekonwertować na typ danych smalldatetime przy użyciu funkcji CAST lub CONVERT bez argumentu styl lub gdy wartość argumentu styl wynosi 0.
  • Wynik funkcji CAST lub CONVERT jest używany w filtrze w zapytaniu Transact-SQL.
  • Uruchamiane jest zapytanie Transact-SQL.

W tym scenariuszu wynik zwrócony przez zapytanie jest nieprawidłowy, ponieważ filtr nie działa poprawnie. Załóżmy na przykład, że kolumna datetimeoffset o nazwie "Date" zawiera następujące wartości:

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

Uruchamiasz następujące zapytanie:

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

W wyniku zapytania zwracany jest tylko jeden wiersz. Jednak oczekiwanym wynikiem powinny być wiersze dla wszystkich trzech wartości.

Rozwiązanie

Informacje o aktualizacji zbiorczej

SQL Server 2012

Poprawkę rozwiązującą ten problem opublikowano po raz pierwszy w aktualizacji zbiorczej 3 dla programu SQL Server 2012. Aby uzyskać więcej informacji dotyczących tego pakietu aktualizacji skumulowanych, kliknij następujący numer artykułu w celu wyświetlenia tego artykułu z bazy wiedzy Baza wiedzy Microsoft Knowledge Base:

2723749 Pakiet aktualizacji zbiorczej 3 dla SQL Server 2012Uwaga Ponieważ kompilacje są zbiorcze, każda nowa poprawka zawiera wszystkie poprawki i poprawki zabezpieczeń, które były zawarte w poprzedniej wersji poprawki SQL Server 2012. Firma Microsoft zaleca rozważenie zastosowania najnowszej wersji poprawki zawierającej tę poprawkę. Aby uzyskać więcej informacji, kliknij następujący numer artykułu w celu wyświetlenia tego artykułu z bazy wiedzy Baza wiedzy Microsoft Knowledge Base:

2692828 Kompilacje SQL Server 2012 wydane po wydaniu SQL Server 2012 Poprawkę SQL Server 2012 należy zastosować do instalacji programu SQL Server 2012.

SQL Server 2008 R2 z dodatkiem Service Pack 2

Poprawkę rozwiązującą ten problem opublikowano po raz pierwszy w aktualizacji zbiorczej 1 dla programu SQL Server 2008 R2 z dodatkiem Service Pack 2. Aby uzyskać więcej informacji dotyczących sposobu uzyskiwania tego pakietu aktualizacji zbiorczej, kliknij następujący numer artykułu w celu wyświetlenia tego artykułu z bazy wiedzy Baza wiedzy Microsoft Knowledge Base:

2720425 Pakiet aktualizacji zbiorczej 1 dla dodatku Service Pack 2 SQL Server 2008 R2Uwaga Ponieważ te kompilacje mają charakter zbiorczy, każda nowa poprawka zawiera wszystkie poprawki i poprawki zabezpieczeń z poprzednich wersji SQL Server 2008 R2. Zalecamy rozważenie zastosowania najnowszej wersji poprawki zawierającej tę poprawkę. Aby uzyskać więcej informacji, kliknij następujący numer artykułu w celu wyświetlenia tego artykułu z bazy wiedzy Baza wiedzy Microsoft Knowledge Base:

2730301 Kompilacje SQL Server 2008 R2 wydane po wydaniu dodatku Service Pack 2 SQL Server 2008 R2

SQL Server 2008 R2 z dodatkiem SP1

Poprawka rozwiązująca ten problem została po raz pierwszy opublikowana w aktualizacji zbiorczej 7. Aby uzyskać więcej informacji dotyczących sposobu uzyskania tego pakietu aktualizacji zbiorczej dla dodatku Service Pack 1 dla programu SQL Server 2008 R2, kliknij następujący numer artykułu w celu wyświetlenia tego artykułu z bazy wiedzy Baza wiedzy Microsoft Knowledge Base:

2703282 Pakiet aktualizacji zbiorczych 7 dla dodatku SP1 SQL Server 2008 R2Uwaga Ponieważ kompilacje są zbiorcze, każda nowa poprawka zawiera wszystkie poprawki i poprawki zabezpieczeń zawarte w poprzedniej wersji poprawki dodatku Service Pack 1 dla systemu SQL Server 2008 R2. Zalecamy rozważenie zastosowania najnowszej wersji poprawki zawierającej tę poprawkę. Aby uzyskać więcej informacji, kliknij następujący numer artykułu w celu wyświetlenia tego artykułu z bazy wiedzy Baza wiedzy Microsoft Knowledge Base:

2567616 Kompilacje SQL Server 2008 R2 wydane po wydaniu SQL Server 2008 R2 z dodatkiem SP1

Więcej informacji

Aby odtworzyć problem, wykonaj następujące czynności:

  1. Uruchom poniższe zapytanie, aby utworzyć tabelę z kolumną datetimeoffset i wstawić kilka rekordów:

    CREATE TABLE #TestTimeZones (dto datetimeoffset(0)); GO INSERT DO WARTOŚCI #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'); IŚĆ

  2. Uruchom poniższe zapytanie, a zobaczysz, że wszystkie trzy wartości są poprawnie wymienione w zwróconym wyniku:

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

  3. Uruchom następujące zapytanie, aby utworzyć indeks w kolumnie "dto" i powtórzyć to samo zapytanie:

    CREATE INDEX IX_testTimeZones_Dto ON #TestTimeZones(dto); GO -- Powtórz to samo zapytanie DECLARE @t smalldatetime = '2011-05-21 23:00:00' SELECT dto AS withIndex FROM #TestTimeZones WHERE CAST(dto A smalldatetime)=@t; IŚĆ

  4. Ponownie uruchom zapytanie w kroku 2. Tym razem zapytanie zwraca tylko jeden wiersz.

  5. Uruchom poniższe zapytanie, aby usunąć utworzony indeks i tabelę:

    DROP INDEX IX_testTimeZones_Dto NA #TestTimeZones; IDŹ UPUŚĆ TALBE #TestTimeZones; IŚĆ

Źródła informacji

Aby uzyskać więcej informacji o funkcjach CAST i CONVERT, odwiedź następującą witrynę MSDN w sieci Web:

Ogólne informacje o funkcjach CAST i CONVERT w programie SQL Server

Stan

Firma Microsoft potwierdziła, że jest to problem dotyczący produktów firmy Microsoft wymienionych w sekcji „Dotyczy”.