tolong bantu... saya sangat membutuhkan ini...
Tidak. Saya tidak yakin Anda akan memperhatikan; dan tidak ada alasan mengapa Anda harus :-) tapi:
Jangan simpan usia di database Anda. Anda benar-benar dijamin salah sesekali. Usia berubah setiap tahun untuk setiap orang, namun, itu berubah setiap hari untuk beberapa orang. Ini pada gilirannya berarti Anda memerlukan pekerjaan batch untuk dijalankan setiap hari dan memperbarui usia. Jika ini gagal, atau tidak sangat ketat dan dijalankan dua kali, Anda dalam masalah.
Anda harus selalu menghitung usia ketika Anda membutuhkannya. Ini adalah kueri yang cukup sederhana dan menghemat banyak masalah dalam jangka panjang.
select floor(months_between(sysdate,<dob>)/12) from dual
Saya telah menyiapkan sedikit SQL Fiddle untuk didemonstrasikan
Sekarang, untuk benar-benar menjawab pertanyaan Anda
prosedur ini berfungsi dengan baik tetapi hanya untuk satu baris,,,tetapi untuk semua baris perlu pemicu tetapi jika saya memanggilnya dari pemicu maka kesalahan terjadi...
Anda tidak menyebutkan kesalahannya, harap lakukan ini di masa mendatang karena ini sangat membantu, tetapi saya menduga Anda mendapatkan
ORA-04091:tabel string.string bermutasi, pemicu/fungsi mungkin tidak melihatnya
Ini karena prosedur Anda menanyakan tabel yang sedang diperbarui. Oracle tidak mengizinkan ini untuk mempertahankan tampilan data yang konsisten-baca. Cara untuk menghindari ini adalah dengan tidak menanyakan tabel, yang tidak perlu Anda lakukan. Ubah prosedur Anda menjadi fungsi yang mengembalikan hasil yang benar berdasarkan tanggal lahir:
function get_age (pDOB date) return number is
/* Return the the number of full years between
the date given and sysdate.
*/
begin
return floor(months_between(sysdate,pDOB)/12);
end;
Perhatikan sekali lagi bahwa saya menggunakan months_between()
berfungsi karena tidak semua tahun memiliki 365 hari.
Di pemicu Anda, Anda kemudian menetapkan nilai langsung ke kolom.
CREATE OR REPLACE TRIGGER agec before INSERT OR UPDATE ON dates
FOR EACH ROW
BEGIN
:new.age := get_age(:new.dob);
END;
:new.<column>
sintaks adalah referensi ke <column>
yang sedang diperbarui. Dalam hal ini :new.age
adalah nilai aktual yang akan dimasukkan ke dalam tabel.
Ini berarti tabel Anda akan diperbarui secara otomatis, yang merupakan titik pemicu DML.
Seperti yang Anda lihat, ada sedikit gunanya fungsi itu sama sekali; pemicu Anda bisa menjadi
CREATE OR REPLACE TRIGGER agec before INSERT OR UPDATE ON dates
FOR EACH ROW
BEGIN
:new.age := floor(months_between(sysdate,:new,DOB)/12);
END;
Namun, karena itu, jika Anda akan menggunakan fungsi ini di tempat lain dalam database, pisahkan. Ini praktik yang baik untuk menyimpan kode yang digunakan di banyak tempat dalam fungsi seperti ini sehingga selalu digunakan dengan cara yang sama. Ini juga memastikan bahwa setiap kali seseorang menghitung usia, mereka akan melakukannya dengan benar.
Sebagai tambahan, apakah Anda yakin ingin mengizinkan orang berusia 9.999 tahun? Atau 0,000000000001998 (bukti)? Presisi numerik didasarkan pada jumlah signifikan angka; ini (menurut Oracle) adalah bukan nol hanya angka-angka. Anda dapat dengan mudah ditangkap oleh ini. Inti dari database adalah untuk membatasi nilai input yang mungkin hanya yang valid. Saya akan dengan serius mempertimbangkan untuk menyatakan kolom usia Anda sebagai number(3,0)
untuk memastikan bahwa hanya nilai "mungkin" yang disertakan.