DBCC CHECKIDENT (table_name, NORESEED | RESEED, [new_reseed_value])
DBCC CHECKIDENT ('myTableName',NORESEED) şeklinde çalıştırılsa, ilgili tablonun mevcut ve en yüksek identity değerini getirir. Eğer hatalı insert nedeniyle identity alanının değeri artmış, ancak tabloya yazılmamışsa bu tarz durumlar olabilir. Bu durumda DBCC CHECKIDENT, reseed parametresi ile çağrılarak, identity alanı istenilen değere geri çekilebilir.
DBCC CHECKIDENT ('myTableName',RESEED, 50) ile identity değeri 50 ye alınır, bundan sonra oluşacak identity değerleri 51 den başlar.
DBCC CHECKIDENT ('myTableName',RESEED) ise mevcut identity değerini maximum identity değeri ile eşitler.
İçinde identity alanı olan bir tablonun içindeki tüm kayıtları sildiğinizde identity alanı sıfırlanmaz. Sıfırlanması için truncate table kullanabilirsiniz ancak tablo üzerinde foreign key ler tanımlı ise, truncate table kodu çalışmaz. Bu durumda tablodaki kayıtları sildikten sonra reseed ile identity alanını baştan başlatabilirsiniz.
29 Ekim 2010 Cuma
Son eklenen kayıtda oluşan otomatik sayıyı öğrenmek
CREATE TABLE Table1(ID int identity(1,1), Name nvarchar(50))
INSERT INTO @Table1(Name) VALUES('Test')
SELECT @@IDENTITY , SCOPE_IDENTITY(), IDENT_CURRENT('Table1')
Identity tanımlanmış bir alanı olan bir tabloya kayıt eklediğimizde, en son eklediğimiz kayıt ile birlikte oluşan Identity alanının değerini öğrenmek ihtiyacımız olduğunda 3 farklı yöntem kullanabiliriz.
@@IDENTITY : Son oturumda oluşan son identity numarasını döndürür. Eğer bu tablo üzerinde bir trigger olsaydı ve trigger da üzerinde identity olan bir tabloya kayıt ekliyor olsaydı, @@Identity bize, Table1 tablosuna eklediğimiz kaydın identity değerini değil, trigger da kayıt eklenen tablonun identity değerini getirecekti.
SCOPE_IDENTITY : Adından anlaşılacağı üzere, scope_identity fonksiyonu, mevcut oturumda ve mevcut kapsamda (scope) son oluşan identity değerini döndürür. Table1 üzerinde trigger olsa, ve başka bir identity alanı olan bir tabloya insert yapılsa bile, Table1 ile ilgili iş yaptığımız için, Table1 üzerinde oluşan son identity değerini bize verecektir.
IDENT_CURRENT : Bu fonksiyon ise hem oturumdan, hem de kapsamdan bağımsız çalışır. Bu nedenle bir tablo adı parametresi ister. Verilen tabloda oluşmuş son identity değerini getirir.
INSERT INTO @Table1(Name) VALUES('Test')
SELECT @@IDENTITY , SCOPE_IDENTITY(), IDENT_CURRENT('Table1')
Identity tanımlanmış bir alanı olan bir tabloya kayıt eklediğimizde, en son eklediğimiz kayıt ile birlikte oluşan Identity alanının değerini öğrenmek ihtiyacımız olduğunda 3 farklı yöntem kullanabiliriz.
@@IDENTITY : Son oturumda oluşan son identity numarasını döndürür. Eğer bu tablo üzerinde bir trigger olsaydı ve trigger da üzerinde identity olan bir tabloya kayıt ekliyor olsaydı, @@Identity bize, Table1 tablosuna eklediğimiz kaydın identity değerini değil, trigger da kayıt eklenen tablonun identity değerini getirecekti.
SCOPE_IDENTITY : Adından anlaşılacağı üzere, scope_identity fonksiyonu, mevcut oturumda ve mevcut kapsamda (scope) son oluşan identity değerini döndürür. Table1 üzerinde trigger olsa, ve başka bir identity alanı olan bir tabloya insert yapılsa bile, Table1 ile ilgili iş yaptığımız için, Table1 üzerinde oluşan son identity değerini bize verecektir.
IDENT_CURRENT : Bu fonksiyon ise hem oturumdan, hem de kapsamdan bağımsız çalışır. Bu nedenle bir tablo adı parametresi ister. Verilen tabloda oluşmuş son identity değerini getirir.
LOCK Türleri
Veritabanında satır, sayfa veya tablo düzeyinde locklar oluşabilir. Bu locklar iki gruba ayrılırlar.
Basic Locks :
Shared Lock : Bir tablo üzerinde select sorgusu çalışırken oluşur. Bu lock, okuma yapacak diğer sorguların çalışmasına izin verir. Ancak shared lock çözülene kadar hiç bir transaction okunan kayıtları güncelleyemez.
Update lock : Bir tablo üzerinde update işleri yapılırken oluşur. SQL Server, güncellenen verileri okumaya kalktığında kullanılır. Güncelleme sırasında, update lock, exclusive lock a dönüşür. Exclusive lock, birden fazla transaction ın aynı satırları güncellemeye çalışıp, deadlock oluşturmasını engeller.
Exclusive lock : Diğer işlemlerin kilitlenmiş kaynaklara ulaşmasını engeller. Okuma işlemi sırasında, tabloda NOLOCK kullanıldıysa veya Isolation Level, READ UNCOMMITTED olarak ayarlandıysa, exclusive lock konulmuş olsa da veri okunur. Ancak diğer işlemler, exclusive lock kalkana kadar yapılamaz.
Intent Lock : 6 farklı türde intent lock vardır.
Intent shared (IS) lock istekleri veya shared lock ları korur. Bir kayıtda bir shared lock oluşmuş ise, ilgili kaydın bulunduğu page üzerinde intent shared lock oluşur.
Intent exclusive (IX) lock Intent shared lock ın bir üstü seviyesidir. Bir kayıtda exclusive lock varsa, ilgili kaydın bulunduğu page üzerinde Intent Exclusive Lock konulur.
Shared with intent exclusive (SIX) lock kilitleme hiyerarşisinde daha alt seviyede duran shared lock ları korur. Bir tabloda shared with intent exclusive lock oluşursa, değişiklik yapılan page üzerinde intent exclusive lock da yer alır.
Intent update (IU) lock güncellenen tablonun bulunduğu pagelerdeki, shared ve istenilelen diğer lockları korur.
Shared intent update lock, shared ve intent update locklarının birleşimininden oluşur. Bir transaction bir tablodan okuma yaptığında shared lock oluşur, daha sonra aynı transaction bir update işlemi yaparsa o zaman shared intent update lock a dönüşür. Bir tabloda select cümlesi çalıştırılırken, PAGLOCK hint i kullanılarak çekildiğinde de oluşan lock türüdür.
Birbirini kapsayan birden fazla lock olmasının nedeni, SQL Server'ın aynı anda bir tablo üzerinde oluşan birçok lock yerine, tek bir lock ile çalışmasının daha verimli olmasındandır.
Basic Locks :
- S:Shared
- U:Update
- X:Exclusive
- I : Intent
- Sch: Schema
- BU: Bulk Update
- KR : Key Range
Shared Lock : Bir tablo üzerinde select sorgusu çalışırken oluşur. Bu lock, okuma yapacak diğer sorguların çalışmasına izin verir. Ancak shared lock çözülene kadar hiç bir transaction okunan kayıtları güncelleyemez.
Update lock : Bir tablo üzerinde update işleri yapılırken oluşur. SQL Server, güncellenen verileri okumaya kalktığında kullanılır. Güncelleme sırasında, update lock, exclusive lock a dönüşür. Exclusive lock, birden fazla transaction ın aynı satırları güncellemeye çalışıp, deadlock oluşturmasını engeller.
Exclusive lock : Diğer işlemlerin kilitlenmiş kaynaklara ulaşmasını engeller. Okuma işlemi sırasında, tabloda NOLOCK kullanıldıysa veya Isolation Level, READ UNCOMMITTED olarak ayarlandıysa, exclusive lock konulmuş olsa da veri okunur. Ancak diğer işlemler, exclusive lock kalkana kadar yapılamaz.
Intent Lock : 6 farklı türde intent lock vardır.
Intent shared (IS) lock istekleri veya shared lock ları korur. Bir kayıtda bir shared lock oluşmuş ise, ilgili kaydın bulunduğu page üzerinde intent shared lock oluşur.
Intent exclusive (IX) lock Intent shared lock ın bir üstü seviyesidir. Bir kayıtda exclusive lock varsa, ilgili kaydın bulunduğu page üzerinde Intent Exclusive Lock konulur.
Shared with intent exclusive (SIX) lock kilitleme hiyerarşisinde daha alt seviyede duran shared lock ları korur. Bir tabloda shared with intent exclusive lock oluşursa, değişiklik yapılan page üzerinde intent exclusive lock da yer alır.
Intent update (IU) lock güncellenen tablonun bulunduğu pagelerdeki, shared ve istenilelen diğer lockları korur.
Shared intent update lock, shared ve intent update locklarının birleşimininden oluşur. Bir transaction bir tablodan okuma yaptığında shared lock oluşur, daha sonra aynı transaction bir update işlemi yaparsa o zaman shared intent update lock a dönüşür. Bir tabloda select cümlesi çalıştırılırken, PAGLOCK hint i kullanılarak çekildiğinde de oluşan lock türüdür.
Birbirini kapsayan birden fazla lock olmasının nedeni, SQL Server'ın aynı anda bir tablo üzerinde oluşan birçok lock yerine, tek bir lock ile çalışmasının daha verimli olmasındandır.
Etiketler:
LOCK,
sql server
TRY - CATCH ve TRANSACTION kullanımı
Try Catch yapısını, transactionlar ile kullanmak hem yapılan kontrol sayısını azaltır, hem de daha anlaşılır bir kod yazmanızı sağlar.
Try Catch kullanılmazsa (SQL 2005 öncesi versiyonlarda zaten try catch olmadığı için mecburan) her bir statementdan sonra @@Error den gelen hata kodunu bir değişkene atmanız, bir sorun varsa rollback yoksa kodun devam etmesi veya commit etmesi için if cümleleri ile uğraşmanız gerekir.
TRY/CATCH ile hataları yönetmek ve transactionlar ile çalışmak daha da kolaylaştı.
İşte birkaç örnek.
DECLARE @ErrorNumber int = 0 , @ErrorMessage nvarchar(max)
BEGIN TRANSACTION
BEGIN TRY
…
END TRY
BEGIN CATCH
SELECT @ErrorNumber = ERROR_NUMBER(), @ErrorMessage = ERROR_MESSAGE()
END CATCH
IF @ErrorNumber<>0
ROLLBACK TRANSACTION
ELSE
COMMIT TRANSACTION
-------------------------------
DECLARE @ErrorNumber int = 0 , @ErrorMessage nvarchar(max)
BEGIN TRANSACTION
BEGIN TRY
…
COMMIT TRANSACTION
END TRY
BEGIN CATCH
SELECT @ErrorNumber = ERROR_NUMBER(), @ErrorMessage = ERROR_MESSAGE()
IF @@TRANCount>0 ROLLBACK TRANSACTION
END CATCH
Try Catch kullanılmazsa (SQL 2005 öncesi versiyonlarda zaten try catch olmadığı için mecburan) her bir statementdan sonra @@Error den gelen hata kodunu bir değişkene atmanız, bir sorun varsa rollback yoksa kodun devam etmesi veya commit etmesi için if cümleleri ile uğraşmanız gerekir.
TRY/CATCH ile hataları yönetmek ve transactionlar ile çalışmak daha da kolaylaştı.
İşte birkaç örnek.
DECLARE @ErrorNumber int = 0 , @ErrorMessage nvarchar(max)
BEGIN TRANSACTION
BEGIN TRY
…
END TRY
BEGIN CATCH
SELECT @ErrorNumber = ERROR_NUMBER(), @ErrorMessage = ERROR_MESSAGE()
END CATCH
IF @ErrorNumber<>0
ROLLBACK TRANSACTION
ELSE
COMMIT TRANSACTION
-------------------------------
DECLARE @ErrorNumber int = 0 , @ErrorMessage nvarchar(max)
BEGIN TRANSACTION
BEGIN TRY
…
COMMIT TRANSACTION
END TRY
BEGIN CATCH
SELECT @ErrorNumber = ERROR_NUMBER(), @ErrorMessage = ERROR_MESSAGE()
IF @@TRANCount>0 ROLLBACK TRANSACTION
END CATCH
Etiketler:
catch,
error,
TRANSACTION,
try
İsimlendirilmiş Transactionlar
İsimlendirilmiş transactionlar, bir transactiona belli bir isim atanmış transactionlardır. İçiçe transactionlar ile çalışıldığında, hangi transactionın, ne durumda olduğunu bulabilirsiniz. Ayrıca lockları izlemek kolaylaşır, hangi transaction uzun süreli locklara neden olduğu tespit edilebilir.
BEGIN TRANSACTION myTranName
-- Transaction içinde çalışacak kodlar.
COMMIT TRANSACTION myTranName
şeklinde kullanılır.
Transactiona verilen isim, SQL Server'ın objelere isim verme kurallarına uygun olmalıdır ve 32 karakterden uzun olamaz.
BEGIN TRANSACTION myTranName
-- Transaction içinde çalışacak kodlar.
COMMIT TRANSACTION myTranName
şeklinde kullanılır.
Transactiona verilen isim, SQL Server'ın objelere isim verme kurallarına uygun olmalıdır ve 32 karakterden uzun olamaz.
Etiketler:
TRANSACTION
TRANSACTION Türleri
SQL Server 2 tür transaction yapısını destekler.
Local Transaction : Aynı server üzerinde kalan transactionlardır. BEGIN TRANSACTION veya daha kısa yazımıyla BEGIN TRAN ifadesi ile başlatırlar.
Distributed Transaction : BEGIN DISTRIBUTED TRANSACTION veya BEGIN DISTRIBUTED TRAN ifadesi ile başlatırlar. Bu tür transaction türleri, eğer bir transaction içerisinde server dışına çıkılacak ise kullanılır. Bu daha çok bir query, linked server ile başka bir servera bağlanıyorsa veya OPENROWSET kullanılıyorsa oluşur. Bu transactionlar sadece SQL Server için değil, distributed transaction yapısını destekleyen Oracle, DB2 gibi veri tabanlarına bağlanılıyorsa da kullanılabilir.
Local Transaction : Aynı server üzerinde kalan transactionlardır. BEGIN TRANSACTION veya daha kısa yazımıyla BEGIN TRAN ifadesi ile başlatırlar.
Distributed Transaction : BEGIN DISTRIBUTED TRANSACTION veya BEGIN DISTRIBUTED TRAN ifadesi ile başlatırlar. Bu tür transaction türleri, eğer bir transaction içerisinde server dışına çıkılacak ise kullanılır. Bu daha çok bir query, linked server ile başka bir servera bağlanıyorsa veya OPENROWSET kullanılıyorsa oluşur. Bu transactionlar sadece SQL Server için değil, distributed transaction yapısını destekleyen Oracle, DB2 gibi veri tabanlarına bağlanılıyorsa da kullanılabilir.
Etiketler:
distributed,
sql server,
TRANSACTION
Transactionlar Hakkında Doğru Bilinen Yanlışlar
Eğer transaction içerisinde bir komut hata verirse, diğer komutların dataları da işlenmez.
Eğer bir hata yakalama mekanizması kullanmadıysanız ve hata durumunda rollback yapmadıysanız, commit cümlesi çalıştığında sorun olmayan komutlar çalışır ve işlemlerini yaparlar.
Bir stored procedure zaten bir transaction dır.
Bir prosedür içerisindeki her bir kod tek başına bir transaction dır. Aslında bu stored procedure içinde olmasa da, tüm yazılan insert, update ve delete kodları otomatik commit edilen bir transaction olarak çalışırlar. Ancak stored procedure kodunun tümü tek bir transaction değildir. Eğer bir stored procedure, tek bir transaction olarak çalıştırılmak isteniyorsa, Begin Transaction ve Commit Transaction bloğu içine yazılmalıdır. Ancak unutmamak gerekir ki, transaction isolation levela göre bu tablolarda uzun süreli lock oluşmasına, bu arada diğer kullanıcıların hiç bir işlem yapamamasına neden olabilir.
Bir transaction yaratılırsa ve bu transaction içinde bir select ifadesi çalıştırılırsa, kimse select ile çekilen satırlara ulaşamaz.
Bu transaction isolation level'a göre doğru da olabilir, yanlış da. Bunun için Transaction Isolation Level ile ilgili yazıma bakabilirsiniz.
Eğer bir hata yakalama mekanizması kullanmadıysanız ve hata durumunda rollback yapmadıysanız, commit cümlesi çalıştığında sorun olmayan komutlar çalışır ve işlemlerini yaparlar.
Bir stored procedure zaten bir transaction dır.
Bir prosedür içerisindeki her bir kod tek başına bir transaction dır. Aslında bu stored procedure içinde olmasa da, tüm yazılan insert, update ve delete kodları otomatik commit edilen bir transaction olarak çalışırlar. Ancak stored procedure kodunun tümü tek bir transaction değildir. Eğer bir stored procedure, tek bir transaction olarak çalıştırılmak isteniyorsa, Begin Transaction ve Commit Transaction bloğu içine yazılmalıdır. Ancak unutmamak gerekir ki, transaction isolation levela göre bu tablolarda uzun süreli lock oluşmasına, bu arada diğer kullanıcıların hiç bir işlem yapamamasına neden olabilir.
Bir transaction yaratılırsa ve bu transaction içinde bir select ifadesi çalıştırılırsa, kimse select ile çekilen satırlara ulaşamaz.
Bu transaction isolation level'a göre doğru da olabilir, yanlış da. Bunun için Transaction Isolation Level ile ilgili yazıma bakabilirsiniz.
Etiketler:
sql server,
TRANSACTION