SQL Server'da bir tablodaki yinelenen satırları kaldırma

Makale çevirileri Makale çevirileri
Makale numarası: 139444 - Bu makalenin geçerli olduğu ürünleri görün.
Hepsini aç | Hepsini kapa

Özet

Microsoft SQL Server tabloları hiçbir zaman yinelenen satırlar veya benzersiz olmayan birincil anahtarlar içermemelidir. Kısaltma amacıyla bu makalede birincil anahtarlar yerine zaman zaman "anahtar" veya "BA" terimi kullanılacaktır, ancak bu terimler her zaman "birincil anahtar" anlamına gelmektedir. Yinelenen BA'lar varlık tutarlılığını ihlal eder, bu nedenle ilişkisel bir sistemde yinelenen BA'lara izin verilmemelidir. SQL Server'da varlık tutarlılığı uygulanmasını zorlamak için dizinler, UNIQUE kısıtlamaları, PRIMARY KEY kısıtlamaları ve tetikleyiciler gibi çeşitli mekanizmalar kullanılır.

Buna karşın, beklenmedik durumlarda yinelenen birincil anahtarlar oluşabilir ve bunların ortadan kaldırılması gerekir. Yinelenen birincil anahtarların oluşmasına yol açan durumlardan biri de SQL Server dışındaki ilişkisel olmayan verilerde yinelenen BA'ların bulunması ve bu verilerin BA benzersizliğinin zorlanmadığı bir sırada alınmasıdır. Ayrıca, bunlar her bir tabloda varlık tutarlılığını zorlamamak gibi bir veritabanı tasarım hatası nedeniyle de oluşabilir.

Yinelenen BA'lar genellikle, benzersiz bir dizin oluşturulmaya çalışılırken yinelenen anahtarlar bulunursa yürütülen işlemin iptal edilmesi sonucunda fark edilir. Şu ileti alınır:
Msg 1505, Level 16, State 1 Create unique index aborted on duplicate key.
SQL Server 2000 veya SQL Server 2005 kullanıyorsanız, aşağıdaki hata iletisini alabilirsiniz:
Msg 1505, Level 16, State 1 CREATE UNIQUE INDEX terminated because a duplicate key was found for object name '%.*ls' and index name '%.*ls'. The duplicate key value is %ls.
Bu makalede, bir tablodaki yinelenen birincil anahtarların nasıl bulunacağı ve kaldırılacağı açıklanır. Ancak, yinelemenin oluşmasını önlemek üzere, bu kopyaların oluşmasına izin veren işlemi yakından incelemelisiniz.

Daha fazla bilgi

Bu örnekte, yinelenen BA değerleri içeren aşağıdaki tabloyu kullanacağız. Bu tabloda birincil anahtar iki sütundur (col1, col2). İki satırda yinelenen BA olduğu için benzersiz dizin veya PRIMARY KEY kısıtlaması oluşturulamaz. Bu yordamda, yinelenen kopyaların nasıl belirleneceği ve kaldırılacağı gösterilmektedir.
create table t1(col1 int, col2 int, col3 char(50))
insert into t1 values (1, 1, 'veri değeri bir')
insert into t1 values (1, 1, 'veri değeri bir')
insert into t1 values (1, 2, 'veri değeri iki')
				
Birinci adım, yinelenen birincil anahtar değerleri olan satırları belirlemektir:
SELECT col1, col2, count(*)
FROM t1
GROUP BY col1, col2
HAVING count(*) > 1
				
Bu yordam, tablodaki her yinelenen BA değeri kümesi için bir satır döndürür. Bu sonuçtaki son satır, belirli bir BA değeri için yinelenen kopya sayısıdır.

Bu tabloyu kapaBu tabloyu aç
col1col2
112


Yalnızca birkaç yinelenen BA değeri kümesi varsa, en uygun yordam, bunları el ile tek tek silmektir. Örneğin:
set rowcount 1
delete from t1
where col1=1 and col2=1
				
Rowcount değeri, belirli bir anahtar değeri için yinelenen kopya sayısına göre n-1 olmalıdır. Bu örnekte 2 yinelenen kopya olduğu için rowcount değeri 1 olarak ayarlanır. col1/col2 değerleri yukarıdaki GROUP BY sorgusu sonucundan alınır. GROUP BY sorgusu birden çok satır döndürürse, bu satırların her biri için "set rowcount" sorgusunun bir kez çalıştırılması gerekir. Her çalıştırıldığında, rowcount değerini belirli bir BA değeri için yinelenen kopya sayısına göre n-1 olarak ayarlayın.

Satırları silmeden önce, tüm satırın yinelendiğini doğrulamalısınız. nadiren de olsa, BA değerleri yinelenmekle birlikte satırın tümü yinelenmiyor olabilir. Birincil anahtar olarak Sosyal Güvenlik Numarası değerinin yer aldığı ve her biri ayrı özniteliklere sahip olan iki farklı kişinin (veya satırın) bulunduğu bir tablo bu duruma örnek olarak gösterilebilir. Bu durumda, yinelenen hataya neden olan sorun, satıra geçerli benzersiz verilerin yerleştirilmesine de neden olmuş olabilir. Bu veriler silinmeden önce, gerektiğinde araştırma ve karşılaştırma amacıyla kullanılmak üzere başka bir yere kopyalanmalıdır.

Tabloda birbirinden farklı çok sayıda yinelenen BA değeri kümesi varsa, bunların tek tek kaldırılması uzun zaman alabilir. Bu durumda, aşağıdaki yordam kullanılabilir:
  1. İlk olarak, yukarıdaki GROUP BY sorgusunu çalıştırarak, yinelenen BA değeri kümesi sayısını ve her kümedeki yinelenen kopya sayısını belirleyin.
  2. Yinelenen anahtar değerlerini ayrı bir tabloda seçin. Örneğin:
    SELECT col1, col2, col3=count(*)
    INTO holdkey
    FROM t1
    GROUP BY col1, col2
    HAVING count(*) > 1
    					
  3. Yinelenen satırları ayrı bir tabloda seçin ve bu işlem sırasında, yinelenen kopyaları kaldırın. Örneğin:
    SELECT DISTINCT t1.*
    INTO holddups
    FROM t1, holdkey
    WHERE t1.col1 = holdkey.col1
    AND t1.col2 = holdkey.col2
    					
  4. Bu aşamada, holddups tablosunda benzersiz BA'lar olmalıdır; ancak t1 tablosunda yinelenen BA'lar ve benzersiz satırlar varsa (yukarıdaki SSN tablosunda olduğu gibi) bu durum geçerli değildir. Holddups tablosundaki her anahtarın benzersiz olduğunu, yinelenen anahtar bulunmadığını ve satırların benzersiz olduğunu doğrulayın. Öyleyse, işlemi burada sonlandırmanız ve belirli bir yinelenen anahtar değeri için hangi satırları korumak istediğinizi belirlemeniz gerekir. Örneğin, şu sorgu:
    SELECT col1, col2, count(*)
    FROM holddups
    GROUP BY col1, col2
    						
    her satır için 1 değerini döndürmelidir. Öyleyse, aşağıdaki 5. adıma geçin. Öyle değilse, yinelenen anahtarlarınız olmasına karşın benzersiz satırlar bulunmaktadır ve hangi satırların kaydedileceğine karar vermeniz gerekir. Bu işlem genelde bir satırın yoksayılmasını veya bu satır için yeni bir benzersiz anahtar değeri oluşturulmasını gerektirir. Holddups tablosundaki her bir yinelenen BA için bu iki adımdan birini uygulayın.
  5. Yinelenen satırları özgün tablodan silin. Örneğin:
    DELETE t1
    FROM t1, holdkey
    WHERE t1.col1 = holdkey.col1
    AND t1.col2 = holdkey.col2
    					
  6. Benzersiz satırları özgün tabloya geri yerleştirin. Örneğin:
    INSERT t1 SELECT * FROM holddups
    					

Özellikler

Makale numarası: 139444 - Last Review: 18 Şubat 2011 Cuma - Gözden geçirme: 5.0
Bu makaledeki bilginin uygulandığı durum:
  • Microsoft SQL Server 6.0 Standard Edition
  • Microsoft SQL Server 6.5 Standard Edition
  • Microsoft SQL Server 7.0 Standard Edition
  • Microsoft SQL Server 2000 Standard Edition
  • Microsoft SQL Server 2005 Standard Edition
  • Microsoft SQL Server 2005 Express Edition
  • Microsoft SQL Server 2005 Developer Edition
  • Microsoft SQL 2005 Server Enterprise
  • Microsoft SQL 2005 Server Workgroup
Anahtar Kelimeler: 
kbsqlmanagementtools kbinfo kbusage KB139444

Geri Bildirim Ver

 

Contact us for more help

Contact us for more help
Connect with Answer Desk for expert help.
Get more support from smallbusiness.support.microsoft.com