SQLite
 sql >> Teknologi Basis Data >  >> RDS >> SQLite

Bagaimana ON CONFLICT Bekerja di SQLite

SQLite memiliki ON CONFLICT klausa yang memungkinkan Anda menentukan cara menangani konflik kendala. Ini berlaku untuk UNIQUE , NOT NULL , CHECK , dan PRIMARY KEY batasan (tetapi bukan FOREIGN KEY kendala).

Ada lima opsi yang dapat Anda gunakan dengan klausa ini:

  • ABORT
  • FAIL
  • IGNORE
  • REPLACE
  • ROLLBACK

Artikel ini memberikan contoh dan penjelasan dari masing-masing opsi ini.

ON CONFLICT klausa digunakan dalam CREATE TABLE pernyataan, tetapi juga dapat digunakan saat memasukkan atau memperbarui data dengan mengganti ON CONFLICT dengan OR .

Saat Membuat Tabel

Seperti yang disebutkan, Anda dapat menggunakan ON CONFLICT saat Anda membuat tabel atau saat Anda memasukkan/memperbarui data.

Berikut ini contoh penggunaan ON CONFLICT pada saat membuat tabel.

CREATE TABLE Products( 
    ProductId INTEGER PRIMARY KEY, 
    ProductName NOT NULL ON CONFLICT IGNORE, 
    Price
); 

Saat Anda menggunakan ON CONFLICT klausa, Anda menerapkannya pada batasan spesifik yang ingin Anda tangani. Dalam hal ini, saya menambahkan klausa ke NOT NULL kendala.

Dalam hal ini saya menentukan IGNORE , yang berarti, jika ada pelanggaran batasan, SQLite akan melewati baris tersebut dan melanjutkan pemrosesan.

Sekarang jika saya mencoba memasukkan NULL ke dalam ProductName kolom baris itu dilewati.

INSERT INTO Products VALUES 
  (1, 'Hammer', 9.99),
  (2, NULL, 1.49),
  (3, 'Saw', 11.34),
  (4, 'Wrench', 37.00),
  (5, 'Chisel', 23.00),
  (6, 'Bandage', 120.00);

SELECT * FROM Products; 

Hasil:

ProductId ProductName Harga ---------- ----------- ----------1 Palu 9,99 3 Gergaji 11,34 4 Kunci Pas 37,0 5 Pahat 23,0 6 Perban 120.0 

Saat Memasukkan Data

Anda juga dapat menggunakan klausa ini saat memasukkan dan memperbarui data. Bedanya, Anda mengganti ON CONFLICT dengan OR .

Untuk mendemonstrasikannya, saya akan membuang tabel sebelumnya dan membuatnya lagi, tetapi tanpa ON CONFLICT klausa:

DROP TABLE IF EXISTS Products;

CREATE TABLE Products( 
    ProductId INTEGER PRIMARY KEY, 
    ProductName NOT NULL, 
    Price
); 

Sekarang saya akan memasukkan data yang sama dan menggunakan OR IGNORE untuk melewati baris yang melanggar batasan.

INSERT OR IGNORE INTO Products VALUES 
  (1, 'Hammer', 9.99),
  (2, NULL, 1.49),
  (3, 'Saw', 11.34),
  (4, 'Wrench', 37.00),
  (5, 'Chisel', 23.00),
  (6, 'Bandage', 120.00);

SELECT * FROM Products; 

Hasil:

ProductId ProductName Harga ---------- ----------- ----------1 Palu 9,99 3 Gergaji 11,34 4 Kunci Pas 37,0 5 Pahat 23,0 6 Perban 120.0 

Jadi kita mendapatkan hasil yang sama seperti pada contoh sebelumnya.

Dalam contoh ini saya menggunakan IGNORE pilihan. Ini hanyalah salah satu dari lima opsi yang mungkin untuk klausa ini.

Di bawah ini adalah contoh penggunaan masing-masing dari lima opsi.

Batalkan

Opsi ini membatalkan pernyataan SQL saat ini dengan kesalahan SQLITE_CONSTRAINT dan membatalkan semua perubahan yang dibuat oleh pernyataan SQL saat ini; tetapi perubahan yang disebabkan oleh pernyataan SQL sebelumnya dalam transaksi yang sama dipertahankan dan transaksi tetap aktif.

Ini adalah perilaku default. Dengan kata lain, inilah yang terjadi selama pelanggaran batasan ketika Anda tidak menggunakan kode ON CONFLICT klausa.

Berikut adalah contoh yang terjadi saat Anda menentukan ABORT .

DELETE FROM Products;

INSERT OR ABORT INTO Products VALUES 
  (1, 'Hammer', 9.99),
  (2, NULL, 1.49),
  (3, 'Saw', 11.34),
  (4, 'Wrench', 37.00),
  (5, 'Chisel', 23.00),
  (6, 'Bandage', 120.00);

SELECT * FROM Products; 

Hasil:

 

Tidak ada hasil yang dikembalikan karena INSERT operasi dibatalkan, dan tabel karena itu kosong.

Inilah yang terjadi jika saya meletakkan setiap baris di INSERT-nya sendiri pernyataan dalam suatu transaksi.

BEGIN TRANSACTION;
INSERT OR ABORT INTO Products VALUES (1, 'Hammer', 9.99);
INSERT OR ABORT INTO Products VALUES (2, NULL, 1.49);
INSERT OR ABORT INTO Products VALUES (3, 'Saw', 11.34);
INSERT OR ABORT INTO Products VALUES (4, 'Wrench', 37.00);
INSERT OR ABORT INTO Products VALUES (5, 'Chisel', 23.00);
INSERT OR ABORT INTO Products VALUES (6, 'Bandage', 120.00);
COMMIT;
  
SELECT * FROM Products; 

Hasil:

ProductId ProductName Harga ---------- ----------- ----------1 Palu 9,99 3 Gergaji 11,34 4 Kunci Pas 37,0 5 Pahat 23,0 6 Perban 120.0 

Gagal

FAIL opsi membatalkan pernyataan SQL saat ini dengan kesalahan SQLITE_CONSTRAINT. Tapi itu tidak membatalkan perubahan sebelumnya dari pernyataan SQL yang gagal dan juga tidak mengakhiri transaksi.

Ini contohnya.

DELETE FROM Products;

INSERT OR FAIL INTO Products VALUES 
  (1, 'Hammer', 9.99),
  (2, NULL, 1.49),
  (3, 'Saw', 11.34),
  (4, 'Wrench', 37.00),
  (5, 'Chisel', 23.00),
  (6, 'Bandage', 120.00);

SELECT * FROM Products; 

Hasil:

ProductId ProductName Harga ---------- ----------- ----------1 Hammer 9.99 

Ini dia dengan INSERT yang terpisah pernyataan dalam suatu transaksi.

DELETE FROM Products;

BEGIN TRANSACTION;
INSERT OR FAIL INTO Products VALUES (1, 'Hammer', 9.99);
INSERT OR FAIL INTO Products VALUES (2, NULL, 1.49);
INSERT OR FAIL INTO Products VALUES (3, 'Saw', 11.34);
INSERT OR FAIL INTO Products VALUES (4, 'Wrench', 37.00);
INSERT OR FAIL INTO Products VALUES (5, 'Chisel', 23.00);
INSERT OR FAIL INTO Products VALUES (6, 'Bandage', 120.00);
COMMIT;
  
SELECT * FROM Products; 

Hasil:

ProductId ProductName Harga ---------- ----------- ----------1 Palu 9,99 3 Gergaji 11,34 4 Kunci Pas 37,0 5 Pahat 23,0 6 Perban 120.0 

Abaikan

IGNORE opsi melewatkan satu baris yang berisi pelanggaran batasan dan terus memproses baris berikutnya dari pernyataan SQL seolah-olah tidak ada yang salah. Baris lain sebelum dan sesudah baris yang berisi pelanggaran kendala disisipkan atau diperbarui secara normal. Tidak ada kesalahan yang dikembalikan untuk keunikan, NOT NULL , dan UNIQUE kendala kesalahan saat opsi ini digunakan. Namun, opsi ini berfungsi seperti ABORT untuk kesalahan batasan kunci asing.

Contoh pertama di halaman ini menggunakan IGNORE , tapi ini dia lagi.

DELETE FROM Products;

INSERT OR IGNORE INTO Products VALUES 
  (1, 'Hammer', 9.99),
  (2, NULL, 1.49),
  (3, 'Saw', 11.34),
  (4, 'Wrench', 37.00),
  (5, 'Chisel', 23.00),
  (6, 'Bandage', 120.00);

SELECT * FROM Products; 

Hasil:

ProductId ProductName Harga ---------- ----------- ----------1 Palu 9,99 3 Gergaji 11,34 4 Kunci Pas 37,0 5 Pahat 23,0 6 Perban 120.0 

Ganti

REPLACE opsi bekerja secara berbeda tergantung pada pelanggarannya:

  • Bila UNIQUE atau PRIMARY KEY pelanggaran kendala terjadi,, REPLACE opsi menghapus baris yang sudah ada sebelumnya yang menyebabkan pelanggaran batasan sebelum menyisipkan atau memperbarui baris saat ini dan perintah terus dijalankan secara normal.
  • Jika NOT NULL pelanggaran kendala terjadi, itu menggantikan NULL nilai dengan nilai default untuk kolom tersebut, atau jika kolom tidak memiliki nilai default, maka ABORT algoritma yang digunakan.
  • Jika CHECK kendala atau pelanggaran batasan kunci asing terjadi, lalu REPLACE bekerja seperti ABORT .

Selain itu, jika menghapus baris untuk memenuhi batasan, hapus pemicu diaktifkan jika dan hanya jika pemicu rekursif diaktifkan.

Berikut adalah contoh yang menggunakan REPLACE pilihan.

DELETE FROM Products; 

INSERT OR REPLACE INTO Products VALUES 
  (1, 'Hammer', 9.99),
  (2, 'Nails', 1.49),
  (3, 'Saw', 11.34),
  (1, 'Wrench', 37.00),
  (5, 'Chisel', 23.00),
  (6, 'Bandage', 120.00);

SELECT * FROM Products; 

Hasil:

ProductId ProductName Harga ---------- ----------- ----------1 Kunci Pas 37,0 2 Paku 1,49 3 Gergaji 11,34 5 Pahat 23,0 6 Perban 120.0 

Dalam contoh ini, konfliknya adalah dengan kunci utama (saya mencoba memasukkan dua baris dengan ProductId yang sama ). REPLACE opsi menyebabkan yang kedua menggantikan yang pertama.

Kembalikan

Pilihan lain adalah menggunakan ROLLBACK .

Opsi ini membatalkan pernyataan SQL saat ini dengan kesalahan SQLITE_CONSTRAINT dan mengembalikan transaksi saat ini. Jika tidak ada transaksi yang aktif (selain transaksi tersirat yang dibuat pada setiap perintah) maka cara kerjanya sama dengan ABORT algoritma.

Berikut adalah contoh yang menggunakan beberapa INSERT OR ROLLBACK pernyataan dalam suatu transaksi.

DELETE FROM Products;

BEGIN TRANSACTION;
INSERT OR ROLLBACK INTO Products VALUES (1, 'Hammer', 9.99);
INSERT OR ROLLBACK INTO Products VALUES (2, NULL, 1.49);
INSERT OR ROLLBACK INTO Products VALUES (3, 'Saw', 11.34);
INSERT OR ROLLBACK INTO Products VALUES (4, 'Wrench', 37.00);
INSERT OR ROLLBACK INTO Products VALUES (5, 'Chisel', 23.00);
INSERT OR ROLLBACK INTO Products VALUES (6, 'Bandage', 120.00);
COMMIT;
  
SELECT * FROM Products; 

Inilah output lengkap dari terminal saya ketika saya menjalankan ini:

sqlite> HAPUS DARI Produk;sqlite> sqlite> MULAI TRANSAKSI;sqlite> INSERT OR ROLLBACK INTO Products VALUES (1, 'Hammer', 9.99);sqlite> INSERT OR ROLLBACK INTO Products VALUES (2, NULL, 1.49); Kesalahan:batasan NOT NULL gagal:Products.ProductNamesqlite> INSERT OR ROLLBACK INTO Products VALUES (3, 'Saw', 11.34);sqlite> INSERT OR ROLLBACK INTO Products VALUES (4, 'Wrench', 37.00);sqlite> INSERT OR ROLLBACK INTO Products VALUES (5, 'Pahat', 23.00);sqlite> INSERT OR ROLLBACK INTO Products VALUES (6, 'Bandage', 120.00);sqlite> COMMIT;Error:tidak dapat melakukan - tidak ada transaksi yang aktifsqlite> sqlite> SELECT * FROM Produk;ProductId ProductName Harga ---------- ----------- ----------3 Saw 11,34 4 Kunci Pas 37.0 5 Pahat 23.0 6 Perban 120.0  

Jadi sampai pada pelanggaran batasan, lalu dibatalkan transaksinya. Kemudian baris berikutnya diproses dan kemudian COMMIT kata kunci ditemukan. Saat itu, transaksi telah dibatalkan dan kami mendapatkan kesalahan lain yang memberi tahu kami bahwa tidak ada transaksi yang aktif.

Inilah yang terjadi jika saya menghapusnya dari transaksi.

DELETE FROM Products;

INSERT OR ROLLBACK INTO Products VALUES (1, 'Hammer', 9.99);
INSERT OR ROLLBACK INTO Products VALUES (2, NULL, 1.49);
INSERT OR ROLLBACK INTO Products VALUES (3, 'Saw', 11.34);
INSERT OR ROLLBACK INTO Products VALUES (4, 'Wrench', 37.00);
INSERT OR ROLLBACK INTO Products VALUES (5, 'Chisel', 23.00);
INSERT OR ROLLBACK INTO Products VALUES (6, 'Bandage', 120.00);
  
SELECT * FROM Products; 

Inilah output lengkap dari terminal saya ketika saya menjalankan ini:

sqlite> DELETE FROM Products;sqlite> sqlite> INSERT OR ROLLBACK INTO Products VALUES (1, 'Hammer', 9.99);sqlite> INSERT OR ROLLBACK INTO Products VALUES (2, NULL, 1.49);Error:NOT NULL constraint gagal:Products.ProductNamesqlite> INSERT OR ROLLBACK INTO Products VALUES (3, 'Saw', 11.34);sqlite> INSERT OR ROLLBACK INTO Products VALUES (4, 'Wrench', 37.00);sqlite> INSERT OR ROLLBACK INTO Products VALUES (5 , 'Pahat', 23.00);sqlite> INSERT OR ROLLBACK INTO Products VALUES (6, 'Bandage', 120.00);sqlite> sqlite> SELECT * FROM Products;ProductId ProductName Price ---------- -- --------- ----------1 Palu 9,99 3 Gergaji 11,34 4 Kunci Pas 37.0 5 Pahat 23.0 6 Perban 120.0 

Dalam hal ini, ini berfungsi seperti ABORT .

Untuk mengonfirmasi, berikut pernyataan yang sama menggunakan ABORT bukannya ROLLBACK .

DELETE FROM Products;

INSERT OR ABORT INTO Products VALUES (1, 'Hammer', 9.99);
INSERT OR ABORT INTO Products VALUES (2, NULL, 1.49);
INSERT OR ABORT INTO Products VALUES (3, 'Saw', 11.34);
INSERT OR ABORT INTO Products VALUES (4, 'Wrench', 37.00);
INSERT OR ABORT INTO Products VALUES (5, 'Chisel', 23.00);
INSERT OR ABORT INTO Products VALUES (6, 'Bandage', 120.00);
  
SELECT * FROM Products; 

Inilah output lengkap dari terminal saya ketika saya menjalankan ini:

sqlite> DELETE FROM Products;sqlite> sqlite> INSERT ATAU ABORT INTO Products VALUES (1, 'Hammer', 9.99);sqlite> INSERT ATAU ABORT INTO Products VALUES (2, NULL, 1.49);Error:NOT NULL constraint gagal:Products.ProductNamesqlite> INSERT OR ABORT INTO Products VALUES (3, 'Saw', 11.34);sqlite> INSERT OR ABORT INTO Products VALUES (4, 'Wrench', 37.00);sqlite> INSERT OR ABORT INTO Products VALUES (5 , 'Pahat', 23.00);sqlite> INSERT OR ABORT INTO Products VALUES (6, 'Bandage', 120.00);sqlite> sqlite> SELECT * FROM Products;ProductId ProductName Price ---------- -- --------- ----------1 Palu 9,99 3 Gergaji 11,34 4 Kunci Pas 37,0 5 Pahat 23,0 6 Perban 120,0 


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Hapus beberapa baris menggunakan ID?

  2. Cara mengembangkan aplikasi Android asli offline-pertama

  3. SQLite JSON_SET()

  4. Hitung Jumlah Detik Sejak Tanggal/Waktu Tertentu di SQLite

  5. SQLite pilih baris jika stempel waktu cocok dengan tanggal hari ini