Bu makalede linked server kurulan bir ortamımızda ne gibi faydaları veya zararları olur görmüş olacağız.
Linked server tanımladıktan sonra bu linked server ile sorgu çektiğimizde sorgu çekerken iki tablomuzu joinleme işlemi yapabiliriz zaten başka bir makalede aynı işlemler openrowset içinde geçerli olmaktadır.
SELECT local.name AS LocalLogins, linked.name AS LinkedLogins
FROM master.sys.server_principals AS local
LEFT JOIN [S1\TEST].master.sys.server_principals AS linked
ON local.name = linked.name;
GO

Bir tablo içine insert yapabiliriz. Yunus tablosu linked server da tanımlanmış bir tablo Gerçek veritabanında bir değişiklik yapmıyoruz sadece verileri çekiyoruz ama delete ve update işlemleri gördüğüm kadarıyla büyük sıkıntı.
SET IDENTITY_INSERT YUNUS ON
INSERT INTO YUNUS([AddressID], [AddressLine1], [AddressLine2], [City], [StateProvinceID], [PostalCode], [SpatialLocation], [rowguid], [ModifiedDate])
SELECT
*
FROM OPENQUERY([ELAZIG], 'SELECT [AddressID], [AddressLine1], [AddressLine2], [City], [StateProvinceID], [PostalCode], [SpatialLocation], [rowguid], [ModifiedDate] FROM AdventureWorks2012.Person.Address')
GO
SET IDENTITY_INSERT YUNUS OFF

Şimdi openquery aracılığıyla linked server üzerindeki bir tablonun içindeki verileri silelim. Verilerimizi aldığımız hedef veritabanına bağlanarak paylaşım sunucusunda delete komutunu çalıştırdığımda verileri sildim. Aşağıdaki resim hedef veritabanım da bulunan tablo.

Aşağıdaki resim Linked server sunucusu üzerinde ilgili tablomu görüyorum.

Linked server kurulu ortamımızda aşağıdaki komutu çalıştırarak Person.Address tablomuzu silme işlemi gerçekleştiriyoruz.
DELETE OPENQUERY([ELAZIG], 'SELECT [AddressID], [AddressLine1], [AddressLine2], [City], [StateProvinceID], [PostalCode], [SpatialLocation], [rowguid], [ModifiedDate] FROM [AdventureWorks2012].[Person].[Address]')
Yukarıdaki komut ile Gerçek veritabanımdan ilgili tablonun içindeki tüm verileri siliyorum aşağıdaki resimdeki gibi 20 bin e yakın kayıt gitti.

Hedef sunucumuzda bulunan veritabanındaki ilgili tabloya select sorgusu çektiğimizde boş bir ekranla karşılaştım.

Sadece hedefteki veritabanımızın tablosunda constraint olmaması ve ilk kolunun primary key olmaması yeterli. Linked server’ın riskli olduğunu gösteren bir yapı. Sadece denemek için ben bu silme işlemlerimi linked server kurmuş olduğum sunucuda sa ile gerçekleştirdim. Şimdi ise ELAZIG adındaki linked server’a yetkili kullanıcı adı ve şifresiyle giriş yapıp başka bir tablonun içeriğini silmeye çalışayım bakalım olacak mı?

Person.AddressType tablosunu sileyim silmeden önce içende kaç veri var ekran çıktısını alayım. Toplamda 6 kaydımız var. Bazı arkadaşlar diyebilir linked server üzerinde kolonları görmüyoruz evet doğru ama select çekersek kolonları görebiliriz. Linked server üzerinden Silme işlemini başlıyorum A1 kullanıcı ile linked server üzerinden gerçek veritabanımızdaki verileri silme

Tabi silme işleminin olması için kolunun primary key olmaması ve herhangi bir constraint olmaması gerekiyor yoksa üzerinde bazı kısıtlamaların olduğu şeklinde hata vermektedir.

Bu kısıtlamaları kaldırıyoruz A1 kullanıcısı ile delete komutunu çalıştırıyorum.

DELETE OPENQUERY([ELAZIG], 'SELECT [AddressTypeID],[Name], [rowguid], [ModifiedDate] FROM [AdventureWorks2012].[Person].[AddressType]')
Yukarıda görmüş olduğumuz gibi kayıtları sildi şimdi Asıl database in olduğu sunucuya(S1) gidelim bakalım içindeki veriler silinmiş mi?

Evet görüldüğü gibi 6 değerimiz kaybolmuş buradan şu sonuç çıkıyor linked server’ın kurulduğu sunucuda ister SA yetkilisi olun veya linked server kullanma yetkisi olan başka bir kullanıcı olsun gerçek veritabanımızda istenmeyen bazı değişiklikler yapılabilir.
Aynı şekilde update komutuylada hedef veritabanımız üzerinde değişiklikler yapabiliriz. Tekrar linked server üzerinden bağlantı yaptığımızda hedef sunucuda(S1) veritabanımızın güncellendiğini görmüş olacağız ve bu linked server üzerinde kimler yetkiliyse hepsi aynı işlemleri yapabilecek. Yukarıda delete senaryosundaki gibi tekrar aynısını update komutu için yapmaya gerek yok Sadece bir örnek üzerinden açıklanacak.
UPDATE OPENQUERY([ELAZIG], 'SELECT * FROM AdventureWorks2012.Person .Address WHERE AddressID = 1')
SET AddressLine1 = 'YUNUSYUCEL';

Aşağıdakiler openquery’de dikkat etmemiz gereken hususlar:
Openquery ile Uzak sunucudan aldığınız veri miktarına dikkat edin. Ağ üzerinden büyük bir veri kümesinin getirilmesi performans darboğazlarına ve ağ trafiğinin artmasına neden olabilir. Yalnızca ihtiyacınız olan sütunları seçin ve yalnızca ilgili satırları getirmek için filtrelemeyi kullanın.
Veri türleri: Yerel ve uzak sunucular arasındaki veri türü dönüşümlerinden haberdar olun. Sorgular sırasında veri türlerini anında dönüştürmek ek yük oluşturabilir. Gereksiz dönüşümlerden kaçınmak için sunucular arasında uyumlu veri türlerini kullanmaya çalışın.
Sorgu karmaşıklığı: Sorgularınızın karmaşıklığını minimumda tutun. Basit ve anlaşılır sorgular, özellikle uzak veri kaynaklarıyla uğraşırken genellikle karmaşık sorgulardan daha verimlidir.
Son olarak yukarıdaki insert delete update ve select işlemlerini linked server üzerinde arayüz’dende yapabiliriz.

Not: Sorgularımızın resimde olduğu gibi select ifadesiyle çekilmesi kendi local’inde oluşturmuş olduğu execution planı kullanır. Sorgularımızın open query ile çağırılması doğru execution plan oluşmasına sebep olur. Execution planı hedefteki sunucudaki execution planı kullanır. Select * From Openquery ([S1\TEST],’select * From …. şeklinde çağrılması execution planın hedefteki bulanan planın devreye almasına sebep olur. Yoksa normal linked server üzerinden select ifadesiyle çekilmesi performans sorunları yaşayacağımızı göstermektedir.
Başka bir makalede görüşmek dileğiyle..
“Onlar ki gaybe iman edip namazı dürüst kılarlar ve kendilerine verdiğimiz rızıktan (Allah yolunda) harcarlar.”Bakara-3