EKİ
9

Bir Sorguyu Tüm Tablolar Veya Veritabanları Üzerinde Çalıştırmak

0 yorum | Kategori: Web Programlama | 09 Ekim 2009 Cuma

SQL Server kullanan web uygulamaları geliştiriyorken, herhangi bir sorguyu uygulamaya ait olan tüm tablolar veya tüm veritabanları üzerinde çalıştırmayı istemek çok seyrek karşılaşılan bir durum değil. Buna verilebilecek en yaygın iki örnek muhtemelen bir veritabanı içerisindeki tüm tabloları silmek ve tüm tabloların collation değerini değiştirmektir. Benzer şeyleri bir SQL Server instance üzerindeki tüm veritabanları için yapmak da istenebilir.

Bir çok kişinin böyle durumlarda çözüm olarak gördüğü şey söz konusu sorguyu her tablo/veritabanı için bir kez çalıştırmaktır. Ancak bu yöntemin aslında bir çözüm olmadığı tablo/veritabanı sayısı arttıkça gittikçe kullanılamaz bir hal al almasından belli olmaktadır.

Konu hakkında biraz daha bilgi sahibi olan kişilerin aklına ise büyük ihtimalle cursor kullanmak ya da verdikleri sorguyu söz konusu olan her tablo/veritabanı için bir kez çalıştıracak olan bir stored procedure yazmak gelecektir. Her iki çözüm de yukarıdaki paragrafta bahsettiğim çözüme göre çok daha mantıklı olmakla birlikte, basit işler için karmaşık ve gereksizdir. Öyle olmasının sebebi ise SQL Server'daki master veritabanı içerisinde bu tür işlemlerin kolaylıkla yapılmasını sağlayacak stored procedure'lerin  zaten tanımlanmış olmasıdır. Bu yazımda, bahsetmiş olduğum işlemleri tek komutla yapmanızı sağlayan, çok işe yarar bulduğum sp_Msforeachtable ve sp_MSforeachdb prosedürlerinden bahsedeceğim.

sp_MSforeachtable

Bu prosedür, adından da anlaşılabileceği üzere parametre olarak verilen bir sorguyu veritabanındaki tüm tablolar üzerinde çalıştırmak için kullanılır. Prosedürün alabildiği parametreler hakkında bilgi alabilmek için yine master veritabanı içerisinde tanımlı olan sp_helptext adlı prosedürü aşağıdaki şekilde kullanabilirsiniz.

EXEC sp_helptext sp_MSForEachTable

Ancak yukarıdaki prosedürü kullanmanız şart değil çünkü ben burada gerekli bilgileri zaten vereceğim. Prosedürü çağrırken kullanmanız gereken sentaks aşağıdaki şekilde.

EXEC @RETURN_VALUE=sp_MSforeachtable
 @command1, @replacechar, @command2, @command3, @whereand, @precommand, @postcommand

Burada görünen parametrelerden biraz bahsetmem gerekirse:

@RETURN_VALUE: Prosedürün çalıştıktan sonra geri döndüreceği değer.

@command1: Prosedürün çalıştıracağı ilk sorgu.

@replacechar: Sorgu katarında o anda işlenmekte olan tablo adı ile değiştirilecek olan karakter. Varsayılan karakter soru işaretidir (?).

@command2 ve @command3: İlk sorgu çalıştırıldıktan sonra sırayla çalıştırılacak olan diğer iki sorgu. Eğer her tablo için birden fazla sorgu çalıştırmak istiyorsanız bu iki parametreyi kullanabilirsiniz.

@whereand: - Sorguya koşul eklemek için kullanabileceğiniz parametre.

@precommand: Herhangi bir tablo üzerinde işlem yapılmadan önce çalıştırılacak olan sorgu.

@postcommand: Sorgular tüm veritabanları üzerinde çalıştırıldıktan sonra en son olarak çalıştırılacak olan sorgu.

Parametrelerin fazlalığı gözünüzü korkutmasın, çünkü büyük ihtimalle çoğunu kullanma ihtiyacı duymayacaksınız. Aşağıdaki örneklerin prosedürü kullanmayı öğrenmeniz için yeterli olacağını düşünüyorum.

EXEC sp_MSforeachtable 'DROP TABLE ?'
EXEC sp_MSforeachtable 'DELETE FROM ?'
EXEC sp_MSforeachtable 'ALTER TABLE ? NOCHECK CONSTRAINT ALL'

Yukarıdaki sorgulardan ilki veritabanındaki tüm dosyaları silmek için, ikincisi veritabanındaki tüm tabloların içini boşaltmak için, üçüncüsü de veritabanındaki tüm tablolardaki constraint'leri disable etmek için kullanılabilir.

Biraz daha karmaşık bir örnek için, veritabanındaki tüm tablolardaki satır sayısını öğrenip başka bir tabloya yazmak istediğimizi varsayalım. Bunun için önce satır sayılarını yazacağımız bir tablo yaratalım.

CREATE TABLE deneme (tablo_adi varchar(50), satir_sayisi int)

Aşağıdaki sorguyu kullanarak amacımıza ulaşabiliriz.

EXEC sp_MSforeachtable 'INSERT INTO deneme SELECT ''?'',COUNT(*) FROM ?'

Şimdi de sorguyu sadece adları a veya b harfleri ile başlayan veritabanlarını seçecek şekilde değiştirelim.

EXEC sp_MSforeachtable 
 @command1 = 'INSERT INTO deneme SELECT ''?'', COUNT(*) FROM ?',
 @whereand = 'and ad LIKE ''a%'' or ad LIKE ''b%'''

Gördüğünüz üzere bu sefer parametre adlarını da gösterdim. Bunu yapmam şart değildi, sadece daha anlaşılır olsun diye öyle yazdım. Daha önce yazmış olduğum sorgularda sadece tek parametre (@command1 parametresini) kullandığım için parametre adını yazma gereği duymamıştım. Yazıp yazmamak kişinin tercihine kalmış bir şey.

sp_MSforeachdb

Bu prosedürün sentaksı ve kullanımı sp_MSforeachtable prosedürü ile tamamen aynı. Aradaki tek fark önceki prosedür parametre olarak verilen işlemleri veritabanındaki her tablo için yaparken, bu prosedürün aynı işlemleri söz konusu SQL Server Instance içerisindeki tüm veritabanları için yapması.

Örneğin aşağıdaki sorguyu kullanarak hangi veritabanının ne kadar yer tuttuğunu öğrenebiliriz. Bu örnekte prosedüre parametre olarak verdiğiniz sorguda başka bir prosedür çağırabileceğinizi de görüyorsunuz.

EXEC sp_MSforeachdb 'EXEC sp_spaceused'

Bu prosedür ile ilgili daha fazla bir şey söylememe gerek olduğunu sanmıyorum. Daha önce de söylediğim gibi kullanımı sp_MSforeachdb ile çok benzer, hatta aynı.

Etiketler: Programlama, SQL, SQL Server

Yorumlar

Bu yazı hakkında yorum bulunmamaktadır. İlk yorumu siz yazabilirsiniz.

Yorum Yazın

İsim ve soyadınız : E-Posta adresiniz : Güvenlik kodu : Güvenlik Kodu Yorumunuz : Gönder