Sql-Server-2008-R2

幫助處理超出範圍的值

  • May 7, 2020

我有這個查詢給我一個錯誤

將 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,因為它應該從一開始就是。

請參閱以下文章:

引用自:https://dba.stackexchange.com/questions/63859