Kategori arşivi: Query Analyzer

SQL Server T-Sql seçme query örnekleri

Identity Değerini Güncellemek – CHECKIDENT

Üzerinde IDENTITY alanı bulunan bir tabloda o alandaki sayılar verilmiş ritmik değere göre ardışık gider. Her yeni kayıtta bu sayı artar. Bu kayıtlardan biri silindiği zaman o satıra ait IDENTITY değeri bir daha kullanılmaz. Dolayısıyla bir süre sonra silmelerden dolayı bu sayı dizisinde çok fazla atlamalar söz konusu olur. Bazı durumlarda bu alanı baştan numaralandırma durumumuz olabilir mi. Bu tablonun başka bir tabloyla ilişkili olması da göz önünde bulundurularak bir güncelleme işlemi yapılabilir.

Veya bir tablodaki kayıtları başka bir tabloya aktardığımızda yeni tablodaki IDENTITY alanını yeniden düzenlemek isteyebiliriz. DBCC CHECKIDENT komutu bu işlemi yapmamızı sağlar.

DBCC CHECKIDENT (‘Tablo Adı’,RESEED, Başlangıç Sayısı)

Aşağıdaki örnekte üzerinde IDENTITY alanı bulunan geçici bir tablo oluşturulmuş ve içerisine sysobjects tablosundaki kayıtlar aktarılmış ardından tablodaki satırların çoğunluğu silinmiş. ID alanı 10 üzerinde olan tüm kayıtlar silindiği için yeni bir kayıt eklendiğinde bu numara

-- IDENTITY bulunan bir tablo oluşturalım
SELECT 
     ID = IDENTITY(INT,1,1)
    ,name
INTO ##T
FROM dbo.sysobjects 
-- 87 kayıt eklendi

-- 10 üzerindeki tüm satırları silelim
DELETE FROM ##T WHERE ID > 10
--77 kayıt silindi

--Tablodaki identity kolonundaki en yüksek değeri okuyalım
SELECT IDENT_CURRENT('##T')
--Bu örnek için 87 döndü. Yani yeni bir kayıt ekleyecek olursa ona 88 değeri verilecek. 
--Oysa tabloda şu anda 10 kayıt var ve 11 ile başlaması daha mantıklı olacaktır.

-- Tabloyu table scan yapıp max identity değerini alalım. Tablodaki en yüsek ID'yi bir değişkene atayalım
DECLARE @maxIdentityValue INT = (SELECT MAX(ID) FROM ##T)
--Bu sorgu 10 değerini döndürecek

-- IDENTITY kolonunun başlangıcını 10 olarak set edeli
DBCC CHECKIDENT('##T', RESEED, @maxIdentityValue)

-- Test amaçlı yeni kayıt ekleyelim. Bu kaydın değeri 11 olarak oluşturulacak
INSERT INTO ##T VALUES('Yeni Kayıt')

SQL Server CONTEXT_INFO Kullanımı

SQL Server ile programlamada bazı durumlarda oturuma özel bir yönlendirme yapma ihtiyacı doğabilir. Bunu yapabilmek için oturumun tekilliğini sağlamak gerekiyor. Bunun yapmanın en basit mantığı o oturumu özelleştirmek için bir parametre gibi bir alan kullanılabilir. Ardından SQL Server tarafında o parametrenin değerine göre koşul yazılabilir. Fakat bunu yapabilmek için her kod parçacığında bu şekilde ek bir parametre veya alan oluşturmak gerekiyor. İşte bu noktada SQL Server’in sunduğu Session Context Information alanı kolaylık sağlamaktadır. Session context information, 128 byte boyutunda bir değer tanımlanmasına izin vererek aynı oturumda multiple batche, stored procedure, triggers veya user-defined function gibi objeler tarafından bu değere otomatik olarak erişilmesini sağlar. O an bu değeri oluşturmak için SET CONTEXT_INFO ifadesi kullanılır. Bu değere o oturumda erişmek için CONTEXT_INFO() fonksiyonu kullanılır. Ayrıca sys.dm_exec_requests, sys.sysprocesses ve sys.dm_exec_sessions DMV’lerde session context’in binary değeri okunabilir. Böylece bu değere göre arama yaparak o oturuma ait talebin yürütülme durumu takip edilebilir.
Okumaya devam et

DBCC INPUTBUFFER Kullanımı

SQL Server üzerinde sistemin durumunu izlediğimizde o anda çalıştırılan SQL ifadelerini, scriptlerini görmek isteriz. Bu amaçla genellikle sp_who veya sp_who2 komutlarını kullanarak ilgili SPID’ye erişilir. O oturumdaki SQL cümleciğine erişmek için DBCC INPUTBUFFER komutu çalıştırılır. Bu komuta SPID değeri parametre olarak verilir.

DBCC INPUTBUFFER(60)

Bu komuta alternatif olarak dm_exec_requests DMV tercih edilebilir. Böylece her iki yöntemle de bir oturumdaki en son çalıştırılan SQL ifadesini görmüş oluruz.

SELECT 
    SQLStatement       =
        SUBSTRING
        (
            qt.text,
            er.statement_start_offset/2,
            (CASE WHEN er.statement_end_offset = -1
                THEN LEN(CONVERT(nvarchar(MAX), qt.text)) * 2
                ELSE er.statement_end_offset
                END - er.statement_start_offset)/2
        )
        
FROM sys.dm_exec_requests er
CROSS APPLY sys.dm_exec_sql_text(er.sql_handle) AS qt
WHERE er.session_id = 60

SQL Server Cluster Node Sorgulama

T-SQL ile SQL Server Cluster altındaki düğüm ve paylaşılmış disklerini (Shared Drives) T-SQL komutlarıyla sorgulamak isteyebiliriz.

SQL Server’in üzerinde koştuğu mevcut node’u bulmak için

SELECT SERVERPROPERTY('ComputerNamePhysicalNetBIOS') AS [Mevcut Node Adı] 

SQL Server’in node’larını listelemek için

SELECT * FROM fn_virtualservernodes()

--Veya
SELECT * FROM sys.dm_os_cluster_nodes 

Cluster için kullanılan ortak diskleri listelemek için

SELECT * FROM fn_servershareddrives() 

--Veya
SELECT * FROM sys.dm_io_cluster_shared_drives

Stored Procedure’in Sonucunu Tabloya Aktarma

SQL Server’de bir Stored Procedure ‘ü çalıştırıp sonucunu bir tabloya aktarmak için genellikle önce o şemaya uygun tablo oluşturulur. Ardından o tabloya INSERT INTO ile data aktarılır. Aşağıdaki örnekte spGetData prosedürünün sonucuna uygun şemada bir #table1 oluşturulmuş ardından prosedürün sonucu bu tabloya aktarılmıştır.

CREATE TABLE #table1
(
   Column1 INT,
   Column2  VARCHAR(10)
)

INSERT INTO #table1 
Exec spGetData 1

Kolay bir yöntem olarak OPENROWSET fonksiyonunun kullanılmasıdır.

SELECT * INTO #table1 FROM OPENROWSET('SQLNCLI', 'server=(local)' , 
	'Exec spGetData ')

Shrink Esnasında “Backup, file manipulation operations” Hatası

Management Studio üzerinden veya Job aracılığıyla otomatik olarak SHRINK işlemi yapılmak istendiğinde aşağıdaki hata mesajı alınabilir.
Backup, file manipulation operations (such as ALTER DATABASE ADD FILE) and encryption changes on a database must be serialized. Reissue the statement after the current backup or file manipulation operation is completed
Bu hata mesajına veri ambarı projesinde her gece shrink Job çalışırken almıştım. Bu mesajın 2 nedeni olabilir;

      O anda veritabanına ait dosyalarda değişiklik ekleme çıkarma yapılıyorsa. Yani mevcut MDF’lerden biri kaldırılıyor veya yeni MDF ekleniyorsa bu hata mesajı alınabilir. Bunu da bilindiği gibi ALTER DATABASE komutu aracılığıyla ADD FILE veya REMOVE FILE tümceleri kullanılarak yapılmaktadır.
      İkinci neden de o esnada sistemde backup alıyor olmasıdır ki ben de bu şekilde tecrübe edindim.

O esnada bu işlemler yapılıyorsa Shrink işlemi başarısız bir şekilde sonlandırılacaktır.

SQL Server VLF (Virtual Log File) Nedir ?

VLF, SQL Server tarafından dahili olarak yönetilen LDF içerisinde bulunan sanal log dosyalarıdır. Fiziksel log dosyaları (LDF dosyaları) veritabanı sistemi tarafından iç transaction yönetimi için birden fazla mantıksal dosyalara bölümlendirilir. Bir sistemde bu dosyaların sayısı artıkça özellikle sistemin yeniden açılma durumlarında o veritabanının toparlanma süresi (recovery time) uzadığı gibi LOG dosyasına ihtiyaç duyuldukça performans sorunu yaşanır. Bu tür çok log dosyalı veritabanlarında SQL servisini restart ettiğimizde o veritabanı uzun süre “Restoring” modunda kalabiliyor. Bu veritabanının kendine gelme süresi bazen 1-2 saati bulabiliyor.
İdeal durumda VLF sayısının 50 veya altı olması beklenir. Bu rakamın üstündeki her dosya performansı olumsuz etkileyecektir. Mevcut veritabanında ne kadar VLF olduğunu anlamak için DBCC LOGINFO komutu kullanılır.
Bu sayıyı düşürmek için sık sık Transaction Log Backup alınabilir.
BACKUP LOG VeriTabaniAdi TO SurucuAdi
Veya DBCC SHRINKFILE komutu aracılığıyla Transaction Log dosyası mümkün olduğunca sıkıştırılır. Transaction Log içerisinde ne kadar boş alan olduğunu DBCC SQLPERF(LOGSPACE) komutuyla öğrenebiliriz.

Backup / Restore / Index Reorganize İşlemi Ne kadar Sürecek

Geçen gün virtual device üzerinden restore işlemi yaparken bu işlemin tahminen ne kadar süreceğini öğrenmek istedim. Veritabanı RESTORING modunda görünüyor ancak bu işlemi yapan Agent network üzerinden çalıştığın için hiçbir yerde percent değeri yazmıyord.
Konuyu biraz araştırınca sys.dm_exec_requests isimli DMV’deki percent_complete kolonunun Backup / Restore / Index Reorganize işlemleri için yüklendiğini öğrendim.

SELECT  command,
        session_id,
        percent_complete,
        DATEADD(ms, estimated_completion_time, GETDATE()) AS estimated_completion_time,
        start_time
FROM    master.sys.dm_exec_requests
WHERE   percent_complete > 0

Bu sorguda işlemin ne zaman başladığı, ne kadarının tamamlandığı ve tahmini ne zaman biteceğini döndürmektedir. Eğer o esnadan birden fazla işlem varsa aşağıdaki script aracılığıyla sadece BACKUP / RESTORE işlemi sorgulanabilir.

SELECT command, s.text, start_time,percent_complete,
CAST(((DATEDIFF(s,start_time,GetDate()))/3600) as varchar) + ' hour(s), '
+ CAST((DATEDIFF(s,start_time,GetDate())%3600)/60 as varchar) + 'min, '
+ CAST((DATEDIFF(s,start_time,GetDate())%60) as varchar) + ' sec' as running_time,
CAST((estimated_completion_time/3600000) as varchar) + ' hour(s), '
+ CAST((estimated_completion_time %3600000)/60000 as varchar) + 'min, '
+ CAST((estimated_completion_time %60000)/1000 as varchar) + ' sec' as est_time_to_go,
dateadd(second,estimated_completion_time/1000, getdate()) as est_completion_time
FROM sys.dm_exec_requests r
CROSS APPLY sys.dm_exec_sql_text(r.sql_handle) s
WHERE r.command in ('RESTORE DATABASE', 'BACKUP DATABASE', 'RESTORE LOG', 'BACKUP LOG')

SQL Server Change Data Capture (CDC) Nedir?

Kritik verilerin bulunduğu veritabanı uygulamalarında en önemli ihtiyaçlardan biri de kullanıcının yaptığı değişikliklerin kayıt altına alınıyor olmasıdır. Bu amaçla ilgili tablolara ait bir log/tarihçe tablosu oluşturulup değişiklikler bu tabloya yazılır. Bunun için ya veritabanı içerisinde ilgili tablolar üzerinde trigger oluşturulur veya uygulama içerisinde değişiklikler uygulanmadan önce değişiklikler tarihçe / arşiv tablolarına aktarılır.
SQL Server 2008 ile sunulan Change Data Capture (CDC) özelliği tablo üzerinde gerçekleşen INSERT, DELETE, UPDATE faaliyetlerinin doğrudan SQL Server tarafından izlenmesini ve kayıt altına alınmasını sağlar. Bu özelliğin en önemli anvantajı doğrudan log altyapısını kullandığı için bizim oluşturacağımız algoritmalara göre daha performanslı olmasıdır. Ayrıca tüm satırı değil sadece değişikliğin yapıldığı kolonları alması da ergonomik bir yapı sağlamaktadır.
MSDN’den alınmış aşağıdaki illustration CDC’nin temel çalışma akışını göstermektedir.

Okumaya devam et

Resource Database Nedir ?

SQL Server 2005 ile birlikte Resource isimli sistem veritabanı geldi. Salt-Okunur ve gizli olan bu veritabanı “sys” şeması altında bulunan tüm sistem nesnelerini içerir. Kullanıcı veri veya şemasıyla ilgili herhangi bir bilgi içermez. Bu veritabanın amacı upgrade işlemlerini hızlı yapılmasını sağlamaktır.
Resource veritabanının dosyaları mssqlsystemresource.mdf ve mssqlsystemresource.ldf olarak isimlendirilmiştir. Bu dosyalar “:\Program Files\Microsoft SQL Server\MSSQL10_50.\MSSQL\Binn\” altında bulunmaktadır.
SQL Server üzerindeki Resource veritabanını versiyonu ve en sonki upgrade bilgisini görmek için sunucuya ait aşağıdaki özellikler okunur.

SELECT SERVERPROPERTY('RESOURCEVERSION')
GO
SELECT SERVERPROPERTY('RESOURCELASTUPDATEDATETIME')

Gerekli durumda bu database’e ait dosyaları taşımak için SQL Server servisini -F parametresi T3608 trace flag koduyla başlatmak gerekir. Single User modunda iken “ALTER DATABASE” komutlarıyla sözkonusu mdf ve ldf dosyalarını kolayca taşıyabiliriz.

ALTER DATABASE mssqlsystemresource MODIFY FILE (NAME=data, FILENAME= 'C:\mssqlsystemresource.mdf')
ALTER DATABASE mssqlsystemresource MODIFY FILE (NAME=log, FILENAME= 'C:\mssqlsystemresource.ldf')