Sql-Server-2008-R2
幫助處理超出範圍的值
我有這個查詢給我一個錯誤
將 varchar 數據類型轉換為 datetime 數據類型導致值超出範圍。
詢問:
select COUNT(*) from dbo.patient INNER JOIN dbo.study on dbo.patient.pk = dbo.study.patient_fk and dbo.study.study_datetime IS NOT NULL and dbo.patient.pat_birthdate IS NOT NULL and dbo.study.study_datetime <= DATEADD(D, -2192, GETDATE()) and dbo.patient.pat_birthdate <= DATEADD(D, -7670, GETDATE());
我讀到這可能有助於轉換為“DATETIME2”,但我不太清楚如何正確轉換列“s.study_datetime”,因為該列很可能有一些錯誤的值作為條目。
您的 varchar 列中包含錯誤數據,並且您無法真正控制 SQL Server 何時嘗試評估它們(在任何過濾發生之前或之後)。因此,您可以添加 where 子句來阻止它們被包含(通過僅檢查值為日期的行),但仍然不能保證 where 子句的評估順序(這意味著您可能仍然會得到一個錯誤)。因此,除了那些過濾器(可以在邏輯上替換您的 NOT NULL 過濾器)之外,您還可以確保僅在它們實際上是有效日期時才評估謂詞。
SELECT COUNT(*) FROM dbo.patient AS p INNER JOIN dbo.study AS s ON s.patient_fk = p.pk WHERE ISDATE(p.pat_birthdate) = 1 AND ISDATE(s.study_datetime) = 1 AND CASE WHEN ISDATE(s.study_datetime) = 1 THEN s.study_datetime END <= DATEADD(DAY, -2192, GETDATE()) AND CASE WHEN ISDATE(p.pat_birthdate) = 1 THEN p.pat_birthdate END <= DATEADD(DAY, -7670, GETDATE());
接下來,請修復表格,使隨機垃圾無法再進入這些列。首先使用以下方法辨識不良數據:
SELECT * FROM dbo.study WHERE ISDATE(study_datetime) = 0; SELECT * FROM dbo.patient WHERE ISDATE(pat_birthdate) = 0;
然後相應地更正(它們可能都是相同模式的“日期”,或者它實際上可能是一堆隨機垃圾,您只需將其設置為 NULL)。一旦那裡沒有錯誤的值,您可以將數據類型更改為 DATE 或 DATETIME,因為它應該從一開始就是。
請參閱以下文章: