日付の値を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つの理由です。