Sql İle Belirli Bir Tablo İçin Stored Procedure Nasıl Yapılır?

Sql İle Belirli Bir Tablo İçin Stored Procedure Nasıl Yapılır?
Sql İle Belirli Bir Tablo İçin Stored Procedure Nasıl Yapılır?

Gereksinimler ve Ön Hazırlık

Stored Procedure oluşturmaya başlamadan önce, sisteminizde kurulu olan veritabanı yönetim sisteminin (RDBMS) prosedürleri desteklediğinden emin olmalısınız. SQL Server, PostgreSQL, MySQL veya Oracle gibi sistemlerin her biri prosedür yazımı konusunda küçük sözdizimi farklılıklarına sahiptir. Bu rehberde genel SQL standartlarına sadık kalarak, en yaygın kullanılan T-SQL (SQL Server) ve PL/pgSQL (PostgreSQL) yapılarını baz alacağız.

  • Veritabanı Erişimi: Tablo üzerinde CREATE PROCEDURE yetkisine sahip olmalısınız.
  • SQL Editörü: Azure Data Studio, pgAdmin 4 veya SQL Server Management Studio (SSMS) gibi bir araç kullanmanız önerilir.
  • Temel Bilgi: Tablo yapınızın (sütun isimleri, veri tipleri) netleşmiş olması gerekir.

Adım 1: Stored Procedure Temel Yapısını Anlamak

Bir Stored Procedure, veritabanında saklanan ve çağrıldığında çalıştırılan bir SQL kod bloğudur. Temel olarak CREATE PROCEDURE anahtar kelimesi ile başlar ve bir isim alır. Aşağıdaki örnekte, basit bir "Müşteriler" tablosundan veri çeken temel bir prosedür yapısını görebilirsiniz.

CREATE PROCEDURE GetTumMusteriler
AS
BEGIN
    SELECT MusteriID, Ad, Soyad, Email 
    FROM Musteriler;
END;

Bu kod bloğu, Musteriler tablosundaki tüm kayıtları listeler. BEGIN ve END blokları, prosedürün gövdesini temsil eder. Bu yapıyı oluşturduktan sonra veritabanınızda bu prosedürü EXEC GetTumMusteriler; komutu ile çalıştırabilirsiniz.

Adım 2: Parametreli Stored Procedure Oluşturma

Gerçek dünya uygulamalarında, prosedürlerin dinamik olması gerekir. Belirli bir ID'ye göre veri çekmek veya filtreleme yapmak için parametreler kullanılır. Parametreler, prosedür isminden hemen sonra parantez içinde tanımlanır.

CREATE PROCEDURE GetMusteriById
    @MusteriID INT
AS
BEGIN
    SELECT Ad, Soyad, Email 
    FROM Musteriler 
    WHERE MusteriID = @MusteriID;
END;

Burada @MusteriID parametresi, dışarıdan gelen değeri sorgu içine güvenli bir şekilde taşır. Bu yöntem, doğrudan sorgu birleştirme (string concatenation) yapmadığı için SQL Injection saldırılarına karşı doğal bir koruma sağlar.

Adım 3: Veri Ekleme ve Güncelleme İşlemleri (DML)

Stored Procedure yapısını sadece veri okumak için değil, aynı zamanda veri eklemek (INSERT) veya güncellemek (UPDATE) için de kullanmalısınız. Bu, veritabanı mantığınızı uygulama kodunuzdan ayırmanıza yardımcı olur.

CREATE PROCEDURE YeniMusteriEkle
    @Ad NVARCHAR(50),
    @Soyad NVARCHAR(50),
    @Email NVARCHAR(100)
AS
BEGIN
    INSERT INTO Musteriler (Ad, Soyad, Email, KayitTarihi)
    VALUES (@Ad, @Soyad, @Email, GETDATE());
END;

Bu örnekte GETDATE() fonksiyonu, verinin veritabanına kaydedildiği anı otomatik olarak yakalar. Prosedürü çağırırken sadece gerekli alanları parametre olarak göndermeniz yeterlidir.

Adım 4: Hata Yönetimi ve İşlem Güvenliği

Profesyonel bir yazılım geliştirici, veritabanı işlemlerinde hata oluşma ihtimalini her zaman göz önünde bulundurur. TRY...CATCH blokları, prosedürlerinizde beklenmedik hataları yakalamanızı sağlar.

CREATE PROCEDURE MusteriGuncelle
    @MusteriID INT,
    @Email NVARCHAR(100)
AS
BEGIN
    BEGIN TRY
        UPDATE Musteriler SET Email = @Email WHERE MusteriID = @MusteriID;
    END TRY
    BEGIN CATCH
        PRINT 'Bir hata oluştu: ' + ERROR_MESSAGE();
    END CATCH
END;

Bu yapı, işlemin başarısız olması durumunda sistemin çökmesini engeller ve geliştiriciye hata mesajını döndürür. Üretim ortamlarında bu mesajları log tablolarına kaydetmek en iyi pratiktir.

Adım 5: Stored Procedure Performans ve Karşılaştırma

Stored Procedure kullanmanın çeşitli yöntemleri ve avantajları vardır. Aşağıdaki tablo, prosedür kullanımının standart sorgulara göre karşılaştırmasını sunar.

Özellik Ad-Hoc Sorgu (Doğrudan) Stored Procedure
Güvenlik Düşük (SQL Injection riski) Yüksek (Parametreli yapı)
Performans Her seferinde derlenir Önceden derlenmiş (Execution Plan)
Bakım Zor (Kod dağılır) Kolay (Tek merkezden)
Kritik Uyarı: Stored Procedure içinde dinamik SQL (EXEC komutu ile string birleştirme) kullanmaktan kaçının. Bu, prosedürün sunduğu tüm güvenlik avantajlarını yok eder ve SQL Injection açıklarına kapı aralar. Eğer dinamik bir sorguya ihtiyacınız varsa, parametreleri mutlaka sp_executesql ile işleyin.

Adım 6: Sıkça Sorulan Sorular

Stored Procedure güncellemek için ne yapmalıyım?

Mevcut bir prosedürü güncellemek için CREATE yerine ALTER PROCEDURE komutunu kullanmalısınız. Bu, prosedürün mevcut izinlerini ve yapısını koruyarak içeriğini değiştirmenizi sağlar.

Prosedürlerde neden parametre kullanmalıyım?

Parametreler, veritabanı sorgularının önbelleğe alınmasını (Execution Plan Reuse) sağlar. Ayrıca kullanıcıdan gelen verilerin doğrudan sorguya girmesini engelleyerek veritabanı güvenliğini sağlar.

Bir prosedür içinde başka bir prosedür çağrılabilir mi?

Evet, "Nested Stored Procedure" olarak adlandırılan bu yöntemle, karmaşık iş akışlarını daha küçük ve yönetilebilir parçalara bölebilirsiniz.

Prosedürlerin performans üzerindeki etkisi nedir?

İlk çalıştırmada derleme (compilation) maliyeti olsa da, sonraki çalıştırmalarda derlenmiş plan kullanıldığı için standart sorgulara göre çok daha hızlı sonuç verirler.

Stored Procedure ne zaman tercih edilmemelidir?

Çok basit ve tek seferlik sorgular için prosedür yazmak gereksiz bir yönetim yükü getirebilir. Ayrıca, veritabanı bağımsız (vendor-agnostic) bir uygulama geliştiriyorsanız, ORM araçları daha esnek olabilir.

İleri Seviye Stored Procedure Tasarımı: Dinamik SQL ve Şema Yönetimi

Standart prosedürler genellikle statik sorgularla çalışır; ancak bazen tablonun veya sütun adının çalışma zamanında (runtime) belirlenmesi gerekebilir. Bu tür senaryolarda Dinamik SQL kullanımı kritik bir rol oynar. Dinamik SQL, prosedür içerisinde bir string değişkeni oluşturup, bu string'i EXEC veya sp_executesql komutları ile çalıştırmanıza olanak tanır.

Aşağıdaki örnekte, parametre olarak gelen tablo ismine göre dinamik bir seçim işlemi gerçekleştiren yapıyı inceleyebilirsiniz:

CREATE PROCEDURE GetDynamicTableData
    @TableName NVARCHAR(128),
    @Limit INT
AS
BEGIN
    DECLARE @SQL NVARCHAR(MAX);
    -- SQL Injection riskine karşı tablo adını QUOTENAME ile sarmalıyoruz
    SET @SQL = N'SELECT TOP ' + CAST(@Limit AS NVARCHAR(10)) + N' * FROM ' + QUOTENAME(@TableName);
    
    EXEC sp_executesql @SQL;
END;

Bu yapıyı kullanırken dikkat etmeniz gereken en önemli husus güvenliktir. Kullanıcıdan alınan tablo isimlerini doğrudan sorguya eklemek SQL Injection zafiyetine yol açar. Bu nedenle yukarıdaki örnekte olduğu gibi QUOTENAME() fonksiyonunu kullanarak nesne isimlerini güvenli hale getirmek zorunludur.

Stored Procedure İçin Birim Testi (Unit Testing) ve Hata Ayıklama

Stored Procedure'lerinizi geliştirdikten sonra, bunların farklı senaryolarda doğru çalışıp çalışmadığını doğrulamak için bir test katmanı oluşturmalısınız. Karmaşık prosedürlerde hata ayıklamak (debugging) için PRINT komutları veya geçici log tabloları kullanmak yerine, veritabanı yönetim sisteminizin sunduğu hata ayıklama araçlarını kullanmanız önerilir.

Bir prosedürün başarısını ölçmek için şu test senaryolarını uygulayabilirsiniz:

  • Geçersiz Parametre Testi: Prosedüre beklenmedik veya boş değerler gönderildiğinde hata yönetimi (TRY...CATCH) bloğunun tetiklenip tetiklenmediğini kontrol edin.
  • Sınır Değer Testi: LIMIT veya OFFSET gibi parametreler varsa, bu değerlerin 0 veya negatif olduğu durumlardaki davranışları gözlemleyin.
  • Performans Testi: SET STATISTICS IO ON komutunu kullanarak prosedürün kaç sayfa okuma yaptığını analiz edin.

Aşağıdaki örnek, bir prosedürün hata ayıklama sürecinde nasıl izlenebileceğini gösteren basit bir TRY...CATCH yapısıdır:

CREATE PROCEDURE SafeUpdateProcedure
    @ID INT,
    @NewValue NVARCHAR(100)
AS
BEGIN
    BEGIN TRY
        BEGIN TRANSACTION;
            UPDATE Products SET ProductName = @NewValue WHERE ProductID = @ID;
        COMMIT TRANSACTION;
    END TRY
    BEGIN CATCH
        IF @@TRANCOUNT > 0 ROLLBACK TRANSACTION;
        -- Hata detaylarını loglama
        SELECT 
            ERROR_NUMBER() AS ErrorNumber,
            ERROR_MESSAGE() AS ErrorMessage;
    END CATCH
END;

Bu yaklaşım, üretim ortamında oluşabilecek hataların sessizce geçiştirilmesini engeller ve geliştiriciye sorunun kaynağını doğrudan raporlar. Prosedürlerinizi bu şekilde modüler ve test edilebilir tasarlamak, uzun vadede bakım maliyetlerinizi ciddi oranda düşürecektir.

Sonuç

SQL ile belirli bir tablo için Stored Procedure oluşturmak, veritabanı yönetimini disiplin altına almanın en etkili yoludur. Bu rehberde öğrendiğiniz parametre kullanımı, hata yönetimi ve güvenlik pratikleri, projelerinizde daha stabil ve hızlı çalışan bir veritabanı mimarisi kurmanıza yardımcı olacaktır. Bir sonraki adım olarak, prosedürlerinizde Transaction (işlem birliği) yapısını kullanarak veri tutarlılığını nasıl garanti altına alabileceğinizi araştırmanızı öneririm.

Sorumluluk Reddi: Bu makaledeki kod örnekleri eğitim amaçlıdır. Üretim ortamlarında kullanmadan önce mutlaka test veritabanlarında denemeli, veritabanı yedeklerinizi almalı ve güvenlik politikalarınızı gözden geçirmelisiniz. Yazılım geliştirme süreçlerinde oluşabilecek veri kayıplarından kullanıcı sorumludur.
Bu yazıya tepkinizi paylaşın:
Kerem Tekin

Teknoloji ve yazılım kullanımı üzerine pratik kılavuzlar hazırlıyorum. Karmaşık dijital araçları, herkesin hızlıca öğrenebileceği sade rehberler haline getirmekte uzmanım.

Yorumlar (0)

Yorum Yaz