Saya memiliki urutan Oracle yang didefinisikan seperti ini:
CREATE SEQUENCE "DALLAS"."X_SEQ"
MINVALUE 0
MAXVALUE 999999999999999999999999999
INCREMENT BY 1 START WITH 0 NOCACHE NOORDER NOCYCLE ;
Ini digunakan dalam prosedur tersimpan untuk memasukkan catatan:
PROCEDURE Insert_Record
(p_name IN VARCHAR2,
p_userid IN INTEGER,
cur_out OUT TYPES_PKG.RefCursor)
IS
v_id NUMBER := 0;
BEGIN
-- Get id value from sequence
SELECT x_seq.nextval
INTO v_id
FROM dual;
-- Line below is X_PKG line 40
INSERT INTO X
(the_id,
name,
update_userid)
VALUES
(v_id,
p_name,
p_userid);
-- Return new id
OPEN cur_out FOR
SELECT v_id the_id
FROM dual;
END;
Kadang-kadang, prosedur ini mengembalikan kesalahan ketika dijalankan dari kode aplikasi.
ORA-01400: cannot insert NULL into ("DALLAS"."X"."THE_ID")
ORA-06512: at "DALLAS.X_PKG", line 40
ORA-06512: at line 1
Detail yang mungkin relevan atau tidak relevan:
- Oracle Database 11g Edisi Perusahaan Rilis 11.2.0.1.0 - Produksi 64bit
- Prosedur dieksekusi melalui Microsoft.Practices.EnterpriseLibrary - Data.Oracle.OracleDatabase.ExecuteReader (perintah DbCommand)
- Aplikasi tidak membungkus panggilan dalam transaksi eksplisit.
- Sisipan gagal sebentar-sebentar - kurang dari 1%
Dalam keadaan apa bisa x_seq.nextval
nol?
v_id
hanya direferensikan dalam urutan pilih, masukkan, dan kursor akhir. Langkah kami selanjutnya adalah menambahkan kode debug. Kita mungkin harus menunggu hasil karena hanya terjadi dalam produksi dan sangat jarang. Ada pemicu yang menyisipkan ke dalam tabel audit. Saya sudah menyisirnya tanpa pistol merokok. Masalahnya juga kadang-kadang terjadi di tabel lain tanpa pemicu. Terima kasih telah melihatnya.Jawaban:
Saya cukup yakin ini pada akhirnya akan menjadi artefak dari kode Anda, atau driver .net yang Anda gunakan. Saya telah membuat demo cepat untuk Anda menggunakan SQL - PL / SQL murni dan tidak pernah mendapatkan nilai urutan yang hilang. Kebetulan kursor ref yang Anda gunakan mungkin tidak perlu dan kemungkinan berdampak pada kinerja dan keterbacaan kode - demo saya mencakup prosedur insert_record2 yang secara konsisten melakukan lebih dari 10% lebih cepat -dalam sekitar 26 detik di laptop saya vs 36 untuk versi kursor ref. Setidaknya menurut saya juga lebih mudah dimengerti. Anda jelas dapat menjalankan versi yang dimodifikasi terhadap basis data pengujian Anda lengkap dengan pemicu audit.
sumber
:new.the_id
tidak tersentuh. Saya mengerti pertanyaan saya sangat sulit. Ini tahan terhadap google-fu saya dan beberapa orang menggaruk-garuk kepala di sini. Saya baru saja membayangkan seseorang mungkin mengenali gejala (dan perawatan) yang diberikan bola mata yang cukup. Terima kasih telah melihatnya.Coba lakukan test case. Buat tabel dummy dan masukkan 100.000 catatan menggunakan urutan Anda dari database. Saya yakin Anda tidak akan memiliki masalah. Selanjutnya coba masukkan hal yang sama dari aplikasi Anda.
Mungkinkah ini disebabkan oleh masalah lain seperti ketidakcocokan klien Oracle?
Solusi lain yang akan memperbaiki masalah tetapi tidak masalah adalah menambahkan pemicu di atas meja.
Sebelum Menyisipkan pada tabel di Dallas.X JIKA: the_id adalah null THEN SELECT x_seq.nextval INTO: the_id FROM dual; BERAKHIR JIKA;
sumber
Saya belum memiliki priveldges untuk membuat komentar, jadi tulis ini sebagai jawaban: Karena Anda menggunakan versi Oracle> = 11.1, yang memungkinkan urutan dalam ekspresi PL / SQL alih-alih dalam SQL, coba ini:
Alih-alih ini:
Atau, meskipun saya pernah mendengar keraguan / jebakan saat menggunakan ".currval", mungkin menghilangkan penugasan terpisah dari v_id dan hanya menggunakan kode ini ?:
Maaf saya tidak punya instance 11g berguna sekarang untuk mencoba ini.
sumber
select into...
11 sebanyak 9i dan 10g. Satu-satunya manfaat dari 11+ adalah dapat secara eksplisit merujuknya seperti yang Anda tunjukkan.