SQL Server ile basamaklı silme özelliğini nasıl kullanabilirim?


332

T1 ve T2 olmak üzere 2 tablo var, bunlar veri içeren tablolardır. T1 ve T2 arasında bire çok ilişkimiz var. T1'den bir kayıt silindiğinde SQL Server'da basamaklı silme gerçekleştirmek için tablo tanımlarını nasıl değiştirebilirim, T2'deki tüm ilişkili kayıtlar da silinir.

Aralarında yabancı sınırlama var. Tabloları bırakmak veya T2 için silme işlemini yapmak için bir tetikleyici oluşturmak istemiyorum. Örneğin, bir çalışanı sildiğimde, tüm inceleme kaydı da kaldırılmalıdır.

T1 - Çalışan,

Employee ID      
Name
Status

T2 - Performans Yorumları,

Employee ID - 2009 Review
Employee ID - 2010 Review

Yanıtlar:


362

İhtiyacın olacak,

  • Mevcut yabancı anahtar kısıtlamasını bırakın,
  • ON DELETE CASCADEAyar etkin olarak yeni bir tane ekleyin .

Gibi bir şey:

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

3
Ekibim ve ben bunu yaptık. Kısıtlarımızı DAMLA ve yeniden eklememiz gerekiyordu. Bu bizim için işe yaradı.
Daniel L.VanDenBosch

2
Bu sert bir silme lehine nasıl? Yumuşak silme işleminde hiçbir zaman bir kısıtlama sorunu olmaz. Bana tam tersi görünüyor.
Maxx

2
@Maxx Sert silme işleminde, bir kaydı silersiniz ve artık kayıtlar hakkında endişelenmenize gerek kalmazken, yumuşak silme işleminde manuel olarak yapmanız gerekir.
Ronaldo Araújo Alves

319

SQL Server Management Studio'da varolan bir yabancı anahtara "Basamakla silme" eklemek için:

İlk olarak, Yabancı Anahtarınızı seçin ve yeni bir Sorgu penceresinde "DROP and To To .." açın.

resim açıklamasını buraya girin

Sonra sadece eklemek ON DELETE CASCADEiçin ADD CONSTRAINTkomutu:

n Ve bu sorguyu çalıştırmak için "Yürüt" düğmesine basın.

Bu arada, Yabancı Anahtarlarınızın bir listesini almak ve hangilerinin "Cascade delete" özelliğinin açık olduğunu görmek için şu komut dosyasını çalıştırabilirsiniz:

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

Ve DROPYabancı Anahtar kısıtlaması nedeniyle belirli bir tabloyu bulamadığınızı fark ederseniz , ancak hangi FK'nin soruna neden olduğunu bulamazsanız, bu komutu çalıştırabilirsiniz:

sp_help 'TableName'

Bu makaledeki SQL, belirli bir tabloya başvuran tüm FK'leri listeler.

Umarım tüm bunlar yardımcı olur.

Uzun parmak için özür dilerim. Sadece bir noktaya değinmeye çalışıyordum.


163

Bunu SQL Server Management Studio ile yapabilirsiniz.

→ Tablo tasarımına sağ tıklayın ve İlişkiler'e gidin ve sol taraftaki bölmede ve sağ taraftaki bölmede yabancı anahtarı seçin, "INSERT and UPDATE belirtimi" menüsünü genişletin ve Kural Sil olarak "Basamakla" yı seçin.

SQL Server Management Studio


merhaba, 4 arasındaki fark nedir, kademelendirmeyi açmak bir tablodaki tüm verileri silmeyi kolaylaştırır. Nasıl bütün bağımlılıkları / fk anahtarlarını görebilirsiniz üzerinde değil bu tablodan, bu masada. Tüm
FK'leri

@aggie - Bağımlılıkları kontrol edebilirsiniz - Tabloya sağ tıklayın -> "Bağımlılıkları Görüntüle" Ayrıca sql sunucusu tablo adı ve sütun adı gibi ayrıntılı bir hata verecektir "DELETE deyimi" FK_Child1_Parent1 "ile REFERANS kısıtlaması çakıştı. Çakışma "TESTDB", "dbo.Child1" tablosu, "Parent1ID" sütununda veritabanında oluştu.
Palanikumar

@aggie - Ayrıca "Varsayılanı Ayarla" 4. durum, Yabancı Anahtar sütununda varsayılan kısıtlamayı ayarlamanız gerekir, üst öğeyi sildiğimizde varsayılan değer alt tablolarda değiştirilir. (Not: Varsayılan değer üst tabloyla eşleşmelidir.) Daha fazla bilgi için mssqltips.com/sqlservertip/2365/…
Palanikumar

Bu çok yardımcı. Acaba, neden Ekleme Kuralı yok? Başka bir deyişle, T1'e bir satır eklediğimde, T2'deki ilgili girişin otomatik olarak oluşturulmasını istiyorum.
Robert M.

@RobertM. Çünkü bu hiç mantıklı değil. Eklenecek değerleri nasıl bilebilir? Alt satırları oluşturmak için INSERT tetikleyicilerini kullanabilirsiniz, bunu araştırmayı deneyin.
Dan Bechard

47

Gibi bir şey kullan

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

Doğru sütun adlarını doldurduğunuzda ayarlanmalıdır. Mark_s'ın doğru şekilde belirttiği gibi, halihazırda yabancı bir anahtar kısıtlamanız varsa, önce eskisini silmeniz ve sonra yenisini oluşturmanız gerekebilir.


41
@marc_s - aslında, her iki tarafta da aynı sütunlara karşı ikinci bir yabancı anahtar ekleyebilirsiniz ve doğru şekilde çalışacaktır. Kesinti olmayan bir üretim ortamında çalışıyorsanız, yeni FK'yi kademeli olarak tanıtmak ve daha sonra FK yokken masaya bir pencere bırakmak yerine eski FK'yi bırakmak tercih edilebilir. (SQL 2008'de test edildi)
Damien_The_Unbeliever

Doğru. Bunu denedim ve işe yarıyor. İlk yabancı anahtar kısıtlamalarını düşürmeye gerek yoktur. Cevap için teşekkürler.
Bichvan Nguyen

15

İlk ONCascade özelliğini etkinleştirmek için:

Mevcut yabancı anahtar kısıtlamasını azaltın

2. ON DELCE CASCADE ayarı etkinken yeni bir tane ekleyin

Ör:

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

İkinci ONCascade özelliğini devre dışı bırakmak için:

Mevcut yabancı anahtar kısıtlamasını azaltın

2. ON DELETE NO ACTION ayarı etkinken yeni bir tane ekleyin

Ör:

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

15

ON DELETE CASCADE
Üst veriler silindiğinde alt verilerin silineceğini belirtir.

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
);

Bu yabancı anahtar için, ON DELETE CASCADEüst tablodaki veriler silindiğinde SQL Server'a alt tabloda karşılık gelen kayıtları silmesini söyleyen maddeyi belirledik . Dolayısıyla bu örnekte, ürünler tablosundan bir product_id değeri silinirse, bu product_id öğesini kullanan envanter tablosundaki karşılık gelen kayıtlar da silinir.


-2

Bir ilâ birçok ilişki T1'den T2'ye ise, bir işlevi temsil etmez ve bu nedenle, sonuçta elde edilen T2 değerinin tümdengelimsel olarak geçerli olan T1 birleştirme T2 tupleslerini atlamamasını garanti eden ters bir işlevi çıkarmak veya çıkarmak için kullanılamaz. , tümdengelimli olarak geçerli bir ters fonksiyon olmadığı için. (işlevleri temsil birincil anahtarların amacı idi.) SQL cevap evet bunu yapabilirsiniz olduğunu düşünüyorum. İlişkisel düşüncenin cevabı hayır, bunu yapamazsınız. Codd 1970'teki belirsizlik noktalarına bakın. İlişkinin T1'den T2'ye çoktan bire olması gerekir.


-10

Sadece gerçek üretim verileri ise tablolar özelliğini silemezsiniz, sadece tablo şemasını etkilemeyen içeriği silin.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.