次のロジックに従って、非常に大きなテーブル[server]。[dbo]。[MyTable]があり、列 'ToDateTime'(現在はNULLでいっぱい)を埋めるSQLステートメントが必要です。
AIDが123、PIDが2の行(下の行2、4、5、7)の「ToDateTime」にのみ値を追加します。それ以外の場合は、「ToDateTime」をNULLのままにします。
上記の条件が満たされ、データ(varchar)を日時に変換できない場合は、 'ToDateTime'をNULLに設定/残す(以下の行5および7には日時変換に失敗するデータがあります)
ただし、datetimeに変換できる値(行2および4)が含まれている場合は、値を変換し、その変換された値でToDateTimeの値を更新します。
前:
ID | AID | PID | ContainedData | ToDateTime
_________________________________________________
1 | 123 | 1 | xxxx | NULL
2 | 123 | 2 | 7/21/2015 8:15:06 AM | NULL
3 | 234 | 2 | xyxy | NULL
4 | 123 | 2 | 19/07/2015 12:29:42 | NULL
5 | 123 | 2 | NULL | NULL
6 | 345 | 3 | zzzz | NULL
7 | 123 | 2 | badTimeString | NULL
後:
ID | AID | PID | ContainedData | ToDateTime
_________________________________________________
1 | 123 | 1 | xxxx | NULL
2 | 123 | 2 | 7/21/2015 8:15:06 AM | 2015-07-21 08:15:06.000
3 | 234 | 2 | xyxy | NULL
4 | 123 | 2 | 19/07/2015 12:29:42 | 2015-07-19 12:29:42.000
5 | 123 | 2 | NULL | NULL
6 | 345 | 3 | zzzz | NULL
7 | 123 | 2 | badTimeString | NULL
以下に似たクエリを試しましたが、ToDateTimeにすべての行の同じ値が入力されています(実際のデータの場合はNULL)。このクエリに似たものが適切なアプローチかどうかはわかりません、または私が道を外れている場合。
UPDATE MyTable SET ToDateTime =
CASE
WHEN ISDATE(myT.cd)= 1
THEN CONVERT(DATETIME, myT.cd)
ELSE NULL END
FROM (
SELECT ContainedData cd
FROM MyTable
WHERE [AID] = 123 AND [PID] = 2
) myT
少なくとも2つの異なる地域の日付形式(おそらく米国とヨーロッパ)があるようです。更新を言語ごとに分割することもできます...
このようなもので、言語設定を使用してisdateと変換を制御します。
set language english;
update test_dates
set ToDateTime = convert(datetime,ContainedData)
where AID='123' and PID='2' and isdate(ContainedData)=1;
set language british;
update test_dates
set ToDateTime = convert(datetime,ContainedData)
where AID='123' and PID='2' and isdate(ContainedData)=1;
テーブルが大きすぎて大きなチャンクで更新できない場合は、行の制限と更新ごとのトランザクションを含むループでそれをラップして、行が更新されなくなるまで繰り返す必要があります。
これはどう:
UPDATE [dbo].[MyTable]
SET [ToDateTime] = [ContainedData]
WHERE aid = 123
and pid = 2
and isdate([ContainedData] ) = 1