文字列として日付やタイムスタンプを格納することはお勧めできません。列に、保持するデータの正しいデータ型を作成する必要があります。オラクルの効率を向上させるだけでなく、無効なデータの格納を防止します。
あなただけ'Tue Aug 01 00:00:00 PDT 2000'
に'1965-08-01 00:00:00.0'
のような文字列を変換したい場合は、そう、彼らはあなたが、to_timestamp()
とタイムスタンプにこれらの値を変換し、彼らはfrom_tz()
で表している時間帯を指定して、戻ってそれらを変換することができ、すべて同じ文字列の形式でありますあなたが望む形式で文字列に変換します。あなたのサンプルデータで構築されたデモ・テーブルt
で:
update t set str = to_char(from_tz(to_timestamp(str, 'YYYY-MM-DD HH24:MI:SS.FF'),
'America/Los_Angeles'), 'Dy Mon DD HH24:MI:SS TZD YYYY')
where str not like '%PDT%' and str not like '%PST%';
3 rows updated.
select * from t;
STR
----------------------------
Wed Dec 12 00:00:00 PST 1973
Wed May 14 00:00:00 PDT 2003
Mon May 01 00:00:00 PDT 1950
Fri Jul 01 00:00:00 PDT 1977
Sun Feb 01 00:00:00 PST 2015
Wed May 14 00:00:00 PDT 2003
6 rows selected
あなたはそれがそれらがエラーであろうから、ターゲット形式にすでに存在するすべての行を無視するように、フィルタを適用する必要があります。ここでは、PDTまたはPSTを含むものは除外しました。表示されていない他のフォーマットをお持ちの場合は、regexp_like()
を使用して、特定のフォーマットに正確に一致する行を探してください。より一般的に
、あなたは様々な形式をしようと例外を捕捉することにより、成功裏に変換する第1の1を返す関数を作成することができ、実際のタイムスタンプにあなたの文字列のいずれかを変換します。単純なブルートフォースのアプローチは次のようなものです:
create or replace function my_to_timestamp_tz(p_str varchar2)
return timestamp with time zone as
begin
-- try each expected pattern in turn
begin
return to_timestamp_tz(p_str, 'Dy Mon DD HH24:MI:SS TZD YYYY');
exception
when others then
null;
end;
begin
-- unspecified TZ; this assumes same as server
return to_timestamp_tz(p_str, 'YYYY-MM-DD HH24:MI:SS.FF');
exception
when others then
null;
end;
-- maybe throw an exception if no conversions worked
return null;
end;
/
PDT/PSTは常に認識されません。 "ORA-01857:有効なタイムゾーンではありません"という2つのDBがあります。最初の3が想定していること
with t (str) as (
select '1973-12-12 00:00:00.0' from dual
union all select '2003-05-14 00:00:00.0' from dual
union all select '1950-05-01 00:00:00.0' from dual
union all select 'Fri Jul 01 00:00:00 PDT 1977' from dual
union all select 'Sun Feb 01 00:00:00 PST 2015' from dual
union all select 'Wed May 14 00:00:00 PDT 2003' from dual
)
select str, my_to_timestamp_tz(str) as converted
from t;
STR CONVERTED
---------------------------- ----------------------------------------------------
1973-12-12 00:00:00.0 1973-12-12 00:00:00 Europe/London
2003-05-14 00:00:00.0 2003-05-14 00:00:00 Europe/London
1950-05-01 00:00:00.0 1950-05-01 00:00:00 Europe/London
Fri Jul 01 00:00:00 PDT 1977 1977-07-01 00:00:00 America/Los_Angeles
Sun Feb 01 00:00:00 PST 2015 2015-02-01 00:00:00 America/Los_Angeles
Wed May 14 00:00:00 PDT 2003 2003-05-14 00:00:00 America/Los_Angeles
注意:この関数を使用して
-- if your DB doesn't recognise PDT/PST then force them to a region:
begin
return from_tz(to_timestamp_tz(p_str, 'Dy Mon DD HH24:MI:ss "PDT" YYYY'),
'America/Los_Angeles');
exception
when others then
null;
end;
begin
return from_tz(to_timestamp_tz(p_str, 'Dy Mon DD HH24:MI:ss "PST" YYYY'),
'America/Los_Angeles');
exception
when others then
null;
end;
-- other time zone abbreviations and matching regions if you expect any
:あなたも、あなたがそれを表している地域の固定文字列と指定するのとTZD値を処理することにより、それを回避できることを確認した場合タイムゾーン、そして私はイギリスのピック・ロンドンでこれを実行しているからです。それはあなたのために右の結果を与えるつもりはない、あなたはそれらを常に特定のタイムゾーンを表し、あなたが行う関数で最後のブロックを変更することで、そのゾーンを指定することができることを知っている場合:その意志
begin
-- unspecified TZ; assume from a specific region
return from_tz(to_timestamp(p_str, 'YYYY-MM-DD HH24:MI:SS.FF'),
'America/Los_Angeles');
exception
...
その後、取得する:あなたが保管してはならない、なぜあなたが本当に文字列に戻って生成されたタイムスタンプを変換することができますしたい場合は
STR CONVERTED
---------------------------- ----------------------------------------------------
1973-12-12 00:00:00.0 1973-12-12 00:00:00 America/Los_Angeles
2003-05-14 00:00:00.0 2003-05-14 00:00:00 America/Los_Angeles
1950-05-01 00:00:00.0 1950-05-01 00:00:00 America/Los_Angeles
Fri Jul 01 00:00:00 PDT 1977 1977-07-01 00:00:00 America/Los_Angeles
Sun Feb 01 00:00:00 PST 2015 2015-02-01 00:00:00 America/Los_Angeles
Wed May 14 00:00:00 PDT 2003 2003-05-14 00:00:00 America/Los_Angeles
が、私は本当にあなたが正しいデータ型として保存をお勧めしたい
です文字列としての日付/タイムスタンプあなたはこれらの2つの形式しか持っていませんか?また、最初のクエリで「ORA-01846:有効な曜日ではありません」と表示されますが、TZDについては何も表示されません。最初の3つの行があると仮定しているタイムゾーンと最後の3つの行をどのタイムゾーンに変換しますか? –
私はPSTがすべて正しい形式でないと予想しています – rohitchandra