日付の値をvarcharとして保存するのは単に間違っています。
可能であれば、テーブルを変更して日付データ型として保存する必要があります。
いくつかの簡単な手順で実行できます:
-
現在の列の名前を(ScheduleStartDateもvarcharだと思います)columnName_oldに変更します。これは、
sp_renameを使用して簡単に行うことができます 。 -
alter tableを使用する 適切なデータ型の列を追加します。 - updateステートメントを使用して、古い列から新しい列に値をコピーします。すべての日付が同じ形式で保存されるため、
convertを使用できます このように:set ScheduleStartDate = convert(date, NULLIF(ltrim(rtrim(ScheduleStartDate_old)), ''), 103)SQL Serverのバージョンが2012以降の場合は、try_convertを使用してください 。nullifを使用したことに注意してください 、ltrimおよびrtrim空白のみを含む値をnullに変換します。 - これらの列を参照しているインデックスを削除して再作成します。これを行う最も簡単な方法は、SSMSのインデックスを右クリックし、
script index asを選択することです。 ->drop and create。 -
alter tableを使用する 古い列を削除します。
注: これらの列がデータベース上の他のオブジェクトで参照されている場合は、これらのオブジェクトも変更する必要があります。これには、ストアドプロシージャ、外部キーなどが含まれます。
データ型を変更できない場合 列の数が多く、SQLサーバーのバージョンが2012よりも低い場合は、次のように変換を使用する必要があります。
SELECT * FROM tblServiceUsersSchedule
WHERE CONVERT(DATE, NULLIF(ScheduleEndDate, RTRIM(LTRIM('')), 103)
< CAST(GETDATE() As Date);
AND ScheduleEndDate IS NOT NULL
列のデータがdd/MM / yyyy形式でない行が1つでもある場合は、エラーが発生することに注意してください。
SQL Serverバージョン2012以降の場合は、Try_convertを使用します 。変換が失敗した場合、この関数は単にnullを返します:
SELECT * FROM tblServiceUsersSchedule
WHERE TRY_CONVERT(DATE, NULLIF(ScheduleEndDate, RTRIM(LTRIM('')), 103)
< CAST(GETDATE() As Date);
AND ScheduleEndDate IS NOT NULL
注: CAST(GETDATE() as Date)を使用しました 現在の日付の時間部分を削除します。これは、ScheduleEndDateのレコードのみを取得することを意味します 少なくとも1日経過しています。 ScheduleEndDateのレコードも取得したい場合 今日は<=を使用してください <の代わりに 。
最後に1つ: where句の列で関数を使用すると、SQL Serverがこれらの列のインデックスを使用できなくなります。
これが、列を適切なデータ型に変更する必要があるもう1つの理由です。