Bagaimana cara saya menggunakan cascade delete dengan SQL Server?

332

Saya punya 2 tabel: T1 dan T2, mereka adalah tabel yang ada dengan data. Kami memiliki hubungan satu ke banyak antara T1 dan T2. Bagaimana cara mengubah definisi tabel untuk melakukan penghapusan cascading di SQL Server ketika catatan dari T1 dihapus, semua catatan terkait di T2 juga dihapus.

Kendala asing ada di antara mereka. Saya tidak ingin menjatuhkan tabel atau membuat pemicu untuk melakukan penghapusan untuk T2. Misalnya, ketika saya menghapus seorang karyawan, semua catatan ulasan juga harus hilang.

T1 - Karyawan,

Employee ID      
Name
Status

T2 - Ulasan Kinerja,

Employee ID - 2009 Review
Employee ID - 2010 Review
Bichvan Nguyen
sumber

Jawaban:

362

Kamu akan membutuhkan,

  • Jatuhkan batasan kunci asing yang ada,
  • Tambahkan yang baru dengan ON DELETE CASCADEpengaturan diaktifkan.

Sesuatu seperti:

ALTER TABLE dbo.T2
   DROP CONSTRAINT FK_T1_T2   -- or whatever it's called

ALTER TABLE dbo.T2
   ADD CONSTRAINT FK_T1_T2_Cascade
   FOREIGN KEY (EmployeeID) REFERENCES dbo.T1(EmployeeID) ON DELETE CASCADE
marc_s
sumber
3
Tim saya dan saya baru saja melakukan ini. Kami harus MENGHENTIKAN kendala kami dan menambahkannya kembali. Ini berhasil untuk kita.
Daniel L. VanDenBosch
2
Bagaimana ini mendukung penghapusan yang sulit? Penghapusan lunak tidak akan pernah memiliki masalah kendala. Tampak sebaliknya bagi saya.
Maxx
2
@ Maxx Dalam hard delete, Anda menghapus satu catatan dan tidak perlu khawatir tentang register yatim, sedangkan dalam soft delete Anda harus melakukannya secara manual.
Ronaldo Araújo Alves
319

Untuk menambahkan "Hapus kaskade" ke kunci asing yang ada di SQL Server Management Studio:

Pertama, pilih Kunci Asing Anda, dan buka "DROP dan Buat Ke .." di jendela Permintaan baru.

masukkan deskripsi gambar di sini

Kemudian, tambahkan saja ON DELETE CASCADEke ADD CONSTRAINTperintah:

n Dan tekan tombol "Execute" untuk menjalankan kueri ini.

Ngomong-ngomong, untuk mendapatkan daftar Kunci Asing Anda, dan melihat mana yang "Cascade delete" dihidupkan, Anda dapat menjalankan skrip ini:

SELECT 
   OBJECT_NAME(f.parent_object_id) AS 'Table name',
   COL_NAME(fc.parent_object_id,fc.parent_column_id) AS 'Field name',
   delete_referential_action_desc AS 'On Delete'
FROM sys.foreign_keys AS f,
     sys.foreign_key_columns AS fc,
     sys.tables t 
WHERE f.OBJECT_ID = fc.constraint_object_id
AND t.OBJECT_ID = fc.referenced_object_id
ORDER BY 1

Dan jika Anda pernah menemukan bahwa Anda tidak bisa DROPtabel tertentu karena batasan kunci asing, tetapi Anda tidak bisa mengetahui mana yang menyebabkan masalah, maka Anda dapat menjalankan perintah ini:

sp_help 'TableName'

SQL dalam artikel itu mencantumkan semua FK yang merujuk pada tabel tertentu.

Semoga semua ini bisa membantu.

Permintaan maaf untuk jari panjang. Saya hanya mencoba untuk menunjukkan maksud.

Mike Gledhill
sumber
163

Anda dapat melakukan ini dengan SQL Server Management Studio.

→ Klik kanan desain tabel dan pergi ke Relationships dan pilih kunci asing di panel sisi kiri dan di panel sisi kanan, perluas menu "INSERT and UPDATE spesifikasi" dan pilih "Cascade" sebagai Delete Rule.

Studio Manajemen SQL Server

Palanikumar
sumber
hai, apa perbedaan antara 4, apakah mengaktifkan kaskade membuatnya mudah untuk menghapus semua data dalam sebuah tabel. Bagaimana saya bisa melihat semua dependensi / tombol fk pada tabel ini, bukan dari tabel ini. Bahkan setelah menghapus semua FK saya masih mendapatkan kesalahan
aggie
@aggie - Anda dapat memeriksa dependensi dengan - Klik kanan tabel -> "Lihat Dependensi" Juga server sql akan memberi Anda kesalahan terperinci dengan nama tabel dan nama kolom seperti ini "Pernyataan DELETE bertentangan dengan batasan REFERENSI" FK_Child1_Parent1 ". Konflik terjadi di database "TESTDB", tabel "dbo.Child1", kolom 'Parent1ID'. "
Palanikumar
@aggie - Juga kasus ke-4 "Tetapkan Default" adalah, Anda harus menetapkan batasan default di kolom Kunci Asing, ketika kami menghapus induk maka nilai default akan diganti dalam tabel anak. (Catatan: Nilai default harus sesuai dengan tabel induk.) Untuk info lebih lanjut kunjungi mssqltips.com/sqlservertip/2365/…
Palanikumar
Ini sangat membantu. Saya bertanya-tanya, mengapa tidak ada Aturan Sisipan? Dengan kata lain, ketika saya menambahkan baris ke T1, saya ingin entri yang sesuai di T2 dibuat secara otomatis.
Robert M.
@RobertM. Karena itu tidak masuk akal. Bagaimana ia tahu nilai apa yang dimasukkan ke INSERT? Anda mungkin dapat menggunakan pemicu INSERT untuk menghasilkan baris anak-anak, cobalah meneliti itu.
Dan Bechard
47

Gunakan sesuatu seperti

ALTER TABLE T2
ADD CONSTRAINT fk_employee
FOREIGN KEY (employeeID)
REFERENCES T1 (employeeID)
ON DELETE CASCADE;

Isi nama kolom yang benar dan Anda harus ditetapkan. Seperti yang dinyatakan dengan tepat oleh mark_s, jika Anda sudah memiliki batasan kunci asing, Anda mungkin perlu menghapus yang lama terlebih dahulu lalu membuat yang baru.

Hyperboreus
sumber
41
@marc_s - sebenarnya, Anda dapat menambahkan kunci asing kedua terhadap kolom yang persis sama di kedua sisi, dan itu akan berfungsi dengan benar. Jika bekerja di lingkungan produksi tanpa downtime, mungkin lebih baik untuk memperkenalkan FK baru dengan kaskade, dan kemudian menjatuhkan FK yang lebih lama, daripada meninggalkan jendela di atas meja ketika tidak ada FK di tempat. (Baru diuji pada SQL 2008)
Damien_The_Unbeliever
Ini benar. Saya mencoba ini, dan itu berhasil. Tidak perlu menghilangkan batasan kunci asing pertama. Terima kasih balasannya.
Bichvan Nguyen
15

Pertama Yang Mengaktifkan properti ONCascade:

1.Drop kendala kunci asing yang ada

2. tambahkan yang baru dengan pengaturan ON DELETE CASCADE diaktifkan

Ex:

IF EXISTS(SELECT 1 FROM sys.foreign_keys WHERE parent_object_id = OBJECT_ID(N'dbo.Response'))
 BEGIN 

ALTER TABLE [dbo].[Response] DROP CONSTRAINT [FK_Response_Request]  

ALTER TABLE [dbo].[Response] WITH CHECK ADD CONSTRAINT [FK_Response_Request]  FOREIGN KEY([RequestId])
REFERENCES [dbo].[Request] ([RequestId])
ON DELETE CASCADE
END

ELSE

 BEGIN 
 ALTER TABLE [dbo].[Response] WITH CHECK ADD CONSTRAINT [FK_Response_Request]  FOREIGN KEY([RequestId])
REFERENCES [dbo].[Request] ([RequestId])
ON DELETE CASCADE
END

Properti Second To Disable ONCascade:

1.Drop kendala kunci asing yang ada

2.Tambahkan yang baru dengan pengaturan ON DELETE NO ACTION diaktifkan

Ex:

IF EXISTS(SELECT 1 FROM sys.foreign_keys WHERE parent_object_id = OBJECT_ID(N'dbo.Response'))
 BEGIN 
ALTER TABLE [dbo].[Response] DROP CONSTRAINT [FK_Response_Request]  

ALTER TABLE [dbo].[Response] WITH CHECK ADD CONSTRAINT [FK_Response_Request]  FOREIGN KEY([RequestId])
REFERENCES [dbo].[Request] ([RequestId])
ON DELETE CASCADE
END

ELSE

 BEGIN 
 ALTER TABLE [dbo].[Response] WITH CHECK ADD CONSTRAINT [FK_Response_Request]  FOREIGN KEY([RequestId])
REFERENCES [dbo].[Request] ([RequestId])
ON DELETE NO ACTION 
END
ravula sandeep
sumber
15

ON DELETE CASCADE
Ini menentukan bahwa data anak dihapus ketika data induk dihapus.

CREATE TABLE products
( product_id INT PRIMARY KEY,
  product_name VARCHAR(50) NOT NULL,
  category VARCHAR(25)
);

CREATE TABLE inventory
( inventory_id INT PRIMARY KEY,
  product_id INT NOT NULL,
  quantity INT,
  min_level INT,
  max_level INT,
  CONSTRAINT fk_inv_product_id
    FOREIGN KEY (product_id)
    REFERENCES products (product_id)
    ON DELETE CASCADE
);

Untuk kunci asing ini, kami telah menentukan ON DELETE CASCADEklausa yang memberitahu SQL Server untuk menghapus catatan yang sesuai di tabel anak ketika data di tabel induk dihapus. Jadi dalam contoh ini, jika nilai product_id dihapus dari tabel produk, catatan terkait dalam tabel inventaris yang menggunakan product_id ini juga akan dihapus.

Md Shahriar
sumber
-2

Jika hubungan satu ke banyak adalah dari T1 ke T2 maka itu tidak mewakili fungsi dan oleh karena itu tidak dapat digunakan untuk menyimpulkan atau menyimpulkan fungsi terbalik yang menjamin nilai T2 yang dihasilkan tidak menghilangkan tupel dari T1 bergabung dengan T2 yang secara deduktif valid , karena tidak ada fungsi invers yang valid secara deduktif. (mewakili fungsi adalah tujuan dari kunci primer.) Jawaban dalam SQL think adalah ya, Anda dapat melakukannya. Jawaban dalam pemikiran relasional adalah tidak, Anda tidak dapat melakukannya. Lihat poin-poin ambiguitas dalam Codd 1970. Hubungannya harus banyak ke satu dari T1 ke T2.

jujur ​​e
sumber
-10

Saya pikir Anda tidak bisa hanya menghapus properti tabel bagaimana jika ini adalah data produksi aktual, cukup hapus konten yang tidak mempengaruhi skema tabel.

Kekasih Apple
sumber