Jawaban @ GordonLinoff berfungsi dengan data sampel yang Anda tunjukkan, tetapi akan terjadi kesalahan dengan ORA-01722 "nomor tidak valid" jika Anda memiliki nilai apa pun yang tidak mewakili angka. Data sampel Anda hanya memiliki nilai yang baik, tetapi Anda mengatakan bahwa untuk bidang sebenarnya "segala jenis tipe data diharapkan seperti tanggal, angka, alfa numerik, dll."
Anda dapat menyiasatinya dengan fungsi yang mencoba mengonversi nilai string yang disimpan menjadi angka, dan mengembalikan null jika mendapat pengecualian tersebut. Contoh sederhana:
create function safe_to_number (p_str varchar2) return number is
begin
return to_number(p_str);
exception
when value_error then
return null;
end;
/
Anda kemudian dapat melakukannya
select *
from test
where safe_to_number(val) not between 0 and 128;
VAL
----------
129
200
Apa pun yang tidak dapat dikonversi dan menyebabkan pengecualian kesalahan nilai ORA-06502 akan dianggap nol, yang bukan berada di antara atau tidak di antara nilai apa pun yang Anda berikan.
Jika Anda perlu memeriksa rentang tanggal, Anda dapat melakukan hal serupa, tetapi kemungkinan kesalahan lebih banyak, dan Anda mungkin memiliki tanggal dalam berbagai format; Anda perlu mendeklarasikan pengecualian dan menginisialisasinya ke nomor kesalahan yang diketahuiuntuk menangkap yang Anda harapkan untuk dilihat. Ini belum lengkap, tapi Anda bisa mulai dengan sesuatu seperti:
create function safe_to_date (p_str varchar2) return date is
l_formats sys.odcivarchar2list;
format_ex_1 exception;
format_ex_2 exception;
format_ex_3 exception;
format_ex_4 exception;
format_ex_5 exception;
pragma exception_init(format_ex_1, -1840);
pragma exception_init(format_ex_2, -1841);
pragma exception_init(format_ex_3, -1847);
pragma exception_init(format_ex_4, -1858);
pragma exception_init(format_ex_5, -1861);
-- add any others you might get
begin
-- define all expected formats
l_formats := sys.odcivarchar2list('YYYY-MM-DD', 'DD/MM/YYYY', 'DD-MON-RRRR'); -- add others
for i in 1..l_formats.count loop
begin
return to_date(p_str, l_formats(i));
exception
when format_ex_1 or format_ex_2 or format_ex_3 or format_ex_4 or format_ex_5 then
-- ignore the exception; carry on and try the next format
null;
end;
end loop;
-- did not match any expected formats
return null;
end;
/
select *
from test
where safe_to_date(val) not between date '2016-02-01' and date '2016-02-29';
Meskipun saya biasanya tidak menggunakan between
untuk tanggal; jika Anda tidak memilikinya dengan waktu yang ditentukan maka Anda akan lolos begitu saja di sini.
Anda dapat menggunakan when others
untuk menangkap pengecualian apa pun tanpa harus mendeklarasikan semuanya, namun bahkan untuk pengecualian ini, hal tersebut berpotensi berbahaya - jika ada sesuatu yang rusak dengan cara yang tidak Anda duga, Anda ingin mengetahuinya, bukan Sembunyikan itu.
Tentu saja, ini adalah pelajaran penting mengapa Anda harus menyimpan data numerik di kolom NUMBER dan tanggal di bidang DATE atau TIMESTAMP - mencoba mengekstrak informasi berguna ketika semuanya disimpan sebagai string adalah hal yang berantakan, menyakitkan, dan tidak efisien.
person
Alex Poole
schedule
21.03.2016