29 Ocak 2008 Salı

SQL Server 2008: Table Valued Parameters

Son güncelleme tarihi: 10 Nisan 2023

Merhaba arkadaşlar,

"Tablo-değerli parametreler" SQL Server 2008 ile birlikte gelen bir yeniliktir. "Tablo-değerli parametreler", User-Defined Table Type (Kullanıcı Tanımlı Tablo Tipi) kullanılarak tanımlanır. "Tablo-değerli parametreler"ı Stored Procedure ya da Function' lara geçiçi tablo kullanmadan çoklu kayıt göndermek için kullanabilirsiniz.

Şunu da yazımın başında hemen söyleyeyim, bu yazıyı hazırlarken kullandığım SQL Server 2008 versiyonu CTP5 versiyonudur. RTM versiyonunda değişiklikler olabilir. Bunu şu anda bilmek imkânsız. Bu nedenle daha sonra SQL Server 2008 ile ilgili bu ve diğer yazdığım makaleler ile kullanacağınız SQL Server 2008 RTM versiyonu arasında uyuşmazlık olursa kızmayın bana =)

Konunun örneklerle ve deneyerek daha iyi anlaşılacağını düşündüğüm için yazıma bir örnekle devam etmek istiyorum. Meselâ SQL Server 2005 ve öncesinde bir Stored Procedure kullanarak bir kerede birden çok kayıt girmek istediğimizde ne yaptığımızı hatırlayalım. Örneği yapmak için aşağıdaki kodları SQL Server Query Editor \ Query Analyzer'a kopyalayıp yapıştırarak çalıştırın ve örneğimiz için gereken yapıyı oluşturmuş olun.

Örnek Veritabanı:
CREATE DATABASE DenemeDB

Örnek Tablo:
USE DenemeDB
GO
CREATE TABLE dbo.Personeller(PersonelID int NOT NULL, PersonelAdi nvarchar(100) NOT NULL, PersonelEposta nvarchar(100) NOT NULL)

Örnek Stored Procedure:
USE DenemeDB
GO
CREATE PROCEDURE YeniPersonel
( @PersonelID int,
@PersonelAdi nvarchar(100),
@PersonelEposta nvarchar(100) )
AS
BEGIN
INSERT INTO dbo.Personeller VALUES(@PersonelID, @PersonelAdi, @PersonelEposta)
END

Eğer yukarıda örnek kodları bulunan veritabanını, tabloyu ve Stored Procedure' ü oluşturduysanız, şimdi de tablomuzun içine Stored Procedure' ümüzü kullanarak bir kaç kayıt girelim.

Örnek Kayıtlar:
USE DenemeDB
GO
EXECUTE YeniPersonel 1,'Fatma Mutlu','fatmam@xxx.com'
EXECUTE YeniPersonel 2,'Ali Satılmış','alis@xxx.com'
EXECUTE YeniPersonel 3,'Yasemin Yeter','yaseminy@xxx.com'

Örnek Kayıtları Sorgula:
USE DenemeDB
GO
SELECT * FROM Personeller


İşte SQL Server 2008 öncesinde birden fazla kayıt girmemiz gerekdiğinde (genelde) yaptığımız şey buydu. Tablo-değerli parametreler ile karşılaştırıldığında bu yöntemin aşağıdaki gibi bazı eksileri var:

- Birden çok kere gidip gelme (Round Trip)
- Stored Procedure' ün birden fazla çalıştırılması
- Verimsiz kodlama

Aynı sonucu bir de Tablo-değerli parametreler kullanarak almayı deneyelim. Ama önce, yeni örneğimiz için de kullanacak olduğumuz "Personeller" isimli tablomuzdaki kayıtları aşağıdaki kodu kullanarak temizleyelim.

"Personeller" Tablosunu Temizle:
USE DenemeDB
GO
TRUNCATE TABLE dbo.Personeller

Şimdi temiz bir "Personeller" tablomuz var. Tablo-değerli parametrelerimizi bir User Defined Table Type tanımlayarak oluşturalım:

Used Defined Data Type:
CREATE TYPE PersonellerTableType AS TABLE (PersonelID INT, PersonelAdi nvarchar(100), PersonelEposta nvarchar(100));
GO

Bu kodu çalıştırdıktan sonra "DenemeDB" veritabanınız içerisindeki Programmability\Types\User-Defined Table Type içerisinde Resim-1' deki gibi "PersonellerTableType" adında bir User Defined Table Type göreceksiniz.


Resim-1



Şimdi "PersonellerTableType" adlı bu User Defined Table Type'ı kullanarak veri kaydedeceğimiz Stored Procedure' ümüzü oluşturalım. Yalnız şuna dikkatinizi çekmek istiyorum ki bu Stored Procedure' ün adını bir önceki örnekte oluşturduğumuz Stored Procedure ile karıştırılmasın diye özellikle "YeniPersonel08" yaptım. "YeniPersonel08" isimli Stored Procedure' ü oluşturmak için aşağıdaki kodu çalıştırın:

Örnek Stored Procedure:
USE DenemeDB
GO
CREATE PROCEDURE YeniPersonel08
( @PersonelBilgileri PersonellerTableType READONLY)
AS
BEGIN
INSERT INTO dbo.Personeller SELECT * FROM @PersonelBilgileri
END


Stored Procedure de oluşturulduktan sonra sıra veri girmede. Aşağıdaki kodu kullanarak ve tabii User Defined Table Type marifetiyle veri girişi yapmış olacağız:

Örnek Kayıt Girişi:
USE DenemeDB
GO
DECLARE @YeniPersonel PersonellerTableType
INSERT INTO @YeniPersonel VALUES(1,'Zeynep Yamalı','zeynepy@xxx.com')
INSERT INTO @YeniPersonel VALUES(2,'Zeydi Kaçar','zeydik@xxx.com')
INSERT INTO @YeniPersonel VALUES(3,'Mehmet Tanrıverdi','mehmett@xxx.com')
EXECUTE YeniPersonel08 @YeniPersonel
GO

"YeniPersonel" isminde bir değişken tanımladık ve veritipini de daha önceden oluşturmuş olduğumuz "PersonellerTableType" olarak verdik. Daha sonra tanımladığımız bu değişken içerisine eklemek istediğimiz kayıtları INSERT INTO komutunu kullanarak sunucuya tekrar tekrar gidip gelmeden ekledik. Daha sonra tek seferde bu üç kaydı da "YeniPersonel08" ismiyle oluşturmuş olduğumuz Stored Procedure' ü kullanarak tek seferde veritabanımıza kaydettik. Bunu söylemeye gerek var mı ya da yok mu tam bilemiyorum, ama komutun çalışması tamamlandıktan sonra değişkene atadığınız değerler otomatik olarak silinecektir.

Bunu daha önceden şu vey bu şekilde yapıyorduk zaten diyenleriniz olabilir. Fakat SQL Server ile bütünleşik şekilde ve bu kadar kolay bir şekilde böyle bir özellik yoktu. Oldukça kullanışlı olduğuna inandığım bir yenilik. Benim çok hoşuma gitti, umarım siz de beğenirsiniz.

Kaynaklar:
Bu makaleyi hazırlarken Microsoft Virtual Labs dökümanlarından yararlandım.


Ekrem Önsoy

1 yorum:

Adsız dedi ki...

Teşekkürler. Aslında aradığım şey değil ama bi güzellik daha öğrendim. Sağolasın..