日付値 (有効な日付または無効な日付) を varchar 形式で格納しています。SQLクエリで日付が有効かどうかを確認することは可能ですか.
6 に答える
はい、フォーマットを知っていて、plsqlがほとんどない場合。
format の日付があるとしましょう'yyyy-mon-dd hh24:mi:ss'
。
create function test_date(d varchar2) return varchar2
is
v_date date;
begin
select to_date(d,'yyyy-mon-dd hh24:mi:ss') into v_date from dual;
return 'Valid';
exception when others then return 'Invalid';
end;
次のことができるようになりました。
select your_date_col, test_date(your_date_col)
from your_table;
次のようなブロックで実行できます
BEGIN
select TO_DATE(your_date,'YYYYMMDD') from dual; --ADD INTO V_DUMMY IN PLSQL
EXCEPTION WHEN OTHERS THEN dbms_output.put_line('NOT A VALID DATE');
END;
ブロックを使用したり、カスタム関数やプロシージャを作成したりせずに、以下の select ステートメントのみを使用して、日付文字列から解析された真の日付値を返し、日付文字列を認識できない場合は null を返すことができます。
このアプローチには限界があります。以下の注意事項を参照してください。
select
case
when regexp_substr(DateStr,'^[[:digit:]]{2}-[[:digit:]]{2}-[[:digit:]]{4}$') is not null then
case
when to_number(regexp_substr(DateStr,'[^-]+',1,1))<=12 and to_number(regexp_substr(DateStr,'[^-]+',1,2))<=31
then add_months(to_date('01-01-1900','MM-DD-YYYY'),(to_number(regexp_substr(DateStr,'[^-]+',1,3))-1900)*12+to_number(regexp_substr(DateStr,'[^-]+',1,1))-1)+to_number(regexp_substr(DateStr,'[^-]+',1,2))-1
else null
end
else null
end RealDateVal
from MyTable
この例では、日付形式を「MM-DD-YYYY」として、「MyTable」に日付文字列列「DateStr」があると想定しています。必要に応じて調整する必要がある場合があります。
全体的なアプローチは、最初に日付文字列が ??-??-???? の形式であることを確認することです。どこに「?」は数字で、最初の ?? をチェックします。12 (月) を超えないようにし、2 番目は ?? 31 を超えないようにしてください (日付の場合)。すべてパスした場合は、「add_months()」関数を使用して年と月を作成し、「+」関数を使用して日付を作成することにより、日付型の値を組み立てます。これらの基準のいずれかが満たされない場合は、null を返します。
注 1 : 年に 2 月 29 日があるかどうかを確認する簡単な方法がなく、月に 31 日 (無効な 29 日、30 日、または 31 日として表示される日) があるかどうかを確認するのが面倒なので、有効性チェックは翌月に繰り越されます。(以下の例を参照してください。) また、クエリがエラーを返すことはありません。
注 2 : 「case when ... is not null then ... else ... end」は遅延であるため、「then ...」部分を評価してエラーを引き起こす可能性はありません。 ... は null ではありません」は満たされていません。この機能は、全体的なアプローチの基本です。代わりに、関数 nvl2() は遅延していないため、代わりに使用できません。
例:
'06-15-2015' -> 有効な日付
'06-15-2015' を返す -> null を返す
'06/15/2015' -> null を返す
'15-06-2015' -> null を返す
'06- 31-2015' -> 有効な日付を 07-01-2015 として返す
'02-30-2015' -> 有効な日付を 03-02-2015 として返す
さらに進んでください: どこまで行きたいかによって、解析された日付値を文字列に変換し直し、それを元の日付文字列値と比較することで、「注 1」に示されている制限を軽減できます。
to_date 関数を使用して、日付が有効か無効かを確認してください。
BEGIN
select TO_DATE(your_date,DateFormat) from dual;
EXCEPTION WHEN OTHERS THEN dbms_output.put_line('NOT A VALID DATE');
END;
また、このアプローチは、ブロック、カスタム関数、またはストアド プロシージャを使用しない単純な select ステートメントでもあります。
この例では、日付形式が「MM-DD-YYYY」であることを前提としています。最初に、フォーマットが「??-??-????」であることを検証します。どこ "?" 正規表現を使用して数字である場合、月 (最初の "??") が 12 より大きくないことを検証し、last_day() 関数を使用して、指定された有効な年/月の最後の日を見つけて、日の部分 (2 番目の "??") をその月の有効な部分にします。すべてが有効な場合は to_date() 関数を使用して解析し、そうでない場合は null を返します。
select
case
when regexp_substr(DateStr,'^[[:digit:]]{1,2}-[[:digit:]]{1,2}-[[:digit:]]{4}$') is not null
then case
when to_number(regexp_substr(DateStr,'[^-]+',1,1))<=12
then case
when to_number(regexp_substr(DateStr,'[^-]+',1,2)) <= extract(day from last_day(add_months(to_date('01-01-1900','MM-DD-YYYY'),(to_number(regexp_substr(DateStr,'[^-]+',1,3))-1900)*12+to_number(regexp_substr(DateStr,'[^-]+',1,1))-1)))
then to_date(DateStr,'MM-DD-YYYY')
else null
end
else null
end
else null
end InstallDate
from MyTable