私たちはしばらくの間SQL Server 2016を実行していますが、最初はデータベースの互換性レベルをSQL Server 2008(100)のままにしました。最近、DB互換性レベルを2016(130)に更新しましたが、そこではいくつかの問題が発生しました。クエリがdatetimeをdatetime2に変換し、値を返す必要があるときにNULLを返す特定の1つを見つけることに成功しました。CEか何かかどうかはわかりませんか?以下の例をご覧ください。
CREATE TABLE TestCE
(
Id INT IDENTITY(1,1),
CurrentDateTime DATETIME
)
GO
INSERT dbo.TestCE(CURRENTDATETIME)
SELECT GETDATE()
UNION ALL SELECT '2018-04-11 08:44:42.643'
UNION ALL SELECT '2018-04-12 09:49:45.334'
GO
SELECT * FROM TestCE
--The resultset
1 2018-04-17 16:49:02.813
2 2018-04-11 08:44:42.643
3 2018-04-12 09:49:45.333
しかし、次のクエリを実行しても結果が得られません。
SELECT * FROM TESTCE
WHERE CURRENTDATETIME = CONVERT(DATETIME2, '2018-04-12 09:49:45.333')
GO
SELECT * FROM TESTCE
WHERE CURRENTDATETIME = CONVERT(DATETIME2, '2018-04-11 08:44:42.643')
GO
SELECT * FROM TESTCE
WHERE CURRENTDATETIME = CONVERT(DATETIME2, '2018-04-17 16:49:02.813')
また、後方CEに対してQueryTraceOnオプションを試してみましたが、成功しませんでした。
SELECT * FROM TESTCE
WHERE CURRENTDATETIME = CONVERT(DATETIME2, '2018-04-12 09:49:45.333')
OPTION(QUERYTRACEON 9481);
GO
SELECT * FROM TESTCE
WHERE CURRENTDATETIME = CONVERT(DATETIME2, '2018-04-11 08:44:42.643')
OPTION(QUERYTRACEON 9481);
GO
SELECT * FROM TESTCE
WHERE CURRENTDATETIME = CONVERT(DATETIME2, '2018-04-17 16:49:02.813')
OPTION(QUERYTRACEON 9481);
また、次のDBオプションを設定しますが、いずれも成功しません。
ALTER DATABASE SCOPED CONFIGURATION
SET LEGACY_CARDINALITY_ESTIMATION = ON
互換性レベルを2008に戻すとすぐに、クエリは期待どおりにデータを返し始めます。
から このKB記事 :
SQL Server 2016とAzure SQL Database以降、データベースエンジンには、データ型変換とその他のいくつかの操作が改善されています。これらの改善のほとんどは、浮動小数点型や従来の日時型を処理するときに精度を向上させます。これらの改善点はすべて、少なくともデータベース互換性レベル130を使用している場合に利用できます。これは、データベースを互換性レベル130以上に設定した後、一部の(ほとんど一般的ではない)式で一部の入力値に対して異なる結果が表示されることを意味します.
特定の例では、次の場合に比較が機能します。
datetime2
への変換を強制しません(そして、入力の精度がそれ以上ないため、これは不要です)。datetime2
列から始めます。datetime2
に変換した後、入力をdatetime
に変換します。または、それ以外の場合は、SQL Serverに.333
= .334
などのように永久に知らせようとしています。新しいタイプはSQL Server 2008で導入され、このタイプの不正確さに正確に対処するために置き換えられました。彼らはいつか先に進む必要があると感じていると思います。
余談ですが、私は現在の動作が100%正しいとは思いませんが、今のところそれは行き詰まっています。
さらに、互換性レベルは、カーディナリティ推定モデルに影響を与える1つの方法ですが(実際に良い方法ではありません)、逆は当てはまりません。 CEモデルを変更して互換性レベルを変更することはできません。これが、クエリレベルのトレースフラグまたはデータベース構成オプションを使用して成功しなかった理由です。ただし、100
に戻る必要はありません。 120
もおそらく機能します。