sql >> データベース >  >> RDS >> Sqlserver

varcharとして保存された日付の比較

    日付の値をvarcharとして保存するのは単に間違っています。

    可能であれば、テーブルを変更して日付データ型として保存する必要があります。
    いくつかの簡単な手順で実行できます:

    1. 現在の列の名前を(ScheduleStartDateもvarcharだと思います)columnName_oldに変更します。これは、sp_renameを使用して簡単に行うことができます 。

    2. alter tableを使用する 適切なデータ型の列を追加します。

    3. updateステートメントを使用して、古い列から新しい列に値をコピーします。すべての日付が同じ形式で保存されるため、convertを使用できます このように:set ScheduleStartDate = convert(date, NULLIF(ltrim(rtrim(ScheduleStartDate_old)), ''), 103) SQL Serverのバージョンが2012以降の場合は、try_convertを使用してください 。 nullifを使用したことに注意してください 、ltrim およびrtrim 空白のみを含む値をnullに変換します。
    4. これらの列を参照しているインデックスを削除して再作成します。これを行う最も簡単な方法は、SSMSのインデックスを右クリックし、script index asを選択することです。 ->drop and create
    5. 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つの理由です。



    1. PostgreSQL 9.1以降でモジュールをインポートしたり拡張機能をインストールしたりするにはどうすればよいですか?

    2. 前月または前年度の欠落データを累積的に追加する

    3. SQLServerのすべてのデータベースのすべてのテーブルの列名を見つける方法

    4. 信号処理データモデルを使用して信号を追跡する