SQL Server’da bazı SET seçenekleri yalnızca o anki oturumu değil, oluşturulan nesneleri de kalıcı olarak etkiler. Bir stored procedure, view ya da trigger oluşturulduğu andaki ANSI_NULLS ve QUOTED_IDENTIFIER ayarlarını kaydeder ve her çalıştırıldığında, çağıran oturumun ayarı ne olursa olsun bu kayıtlı ayarlarla çalışır. Yıllar önce yanlış ayarla oluşturulmuş bir procedure, bugün bir tabloya filtered index eklendiği anda hata vermeye başlayabilir.
Bu yazıda hangi SET seçeneklerinin önemli olduğunu, hangi özelliklerin doğru ayarları zorunlu kıldığını, sorunlu nesneleri nasıl bulacağınızı ve “SSMS’te hızlı, uygulamada yavaş” sorununun bu ayarlarla ilişkisini anlatıyoruz.
Eski kod yeni özellikleri mi engelliyor?
Aryasoft, veritabanı nesnelerinizdeki uyumsuz ayarları bulur ve filtered index, indexed view gibi özellikleri güvenle kullanabileceğiniz hale getirir.
Hangi Özellikler Doğru SET Ayarlarını Gerektirir?
Filtered index’ler, indexed view’lar, hesaplanmış kolonlardaki index’ler, XML veri tipi yöntemleri ve bazı diğer özellikler, onları kullanan tablolar üzerinde işlem yapan oturumun şu ayarlarla çalışmasını gerektirir:
| SET seçeneği | Gerekli değer |
|---|---|
| ANSI_NULLS | ON |
| ANSI_PADDING | ON |
| ANSI_WARNINGS | ON |
| ARITHABORT | ON |
| CONCAT_NULL_YIELDS_NULL | ON |
| QUOTED_IDENTIFIER | ON |
| NUMERIC_ROUNDABORT | OFF |
Bu koşul sağlanmazsa, örneğin filtered index’i olan bir tabloya insert yapan bir procedure QUOTED_IDENTIFIER OFF ile oluşturulmuşsa, işlem şu hatayla düşer:
Bu hata genellikle performans için yeni bir filtered index eklendikten hemen sonra, o tabloya yazan eski bir procedure’den gelir.
ANSI_NULLS ve QUOTED_IDENTIFIER Neden Kalıcıdır?
Diğer SET seçenekleri çalıştırma anındaki oturumdan alınır; ama bu ikisi, modül oluşturulurken kaydedilir. Yani bir procedure’ü SET QUOTED_IDENTIFIER OFF içeren bir script ile oluşturduysanız, procedure her zaman OFF ile çalışır. Bu durum genellikle eski araçlarla ya da bu ayarları açıkça kapatan script şablonlarıyla oluşturulmuş nesnelerde görülür.
Sorunlu Nesneleri Bulmak
SELECT OBJECT_SCHEMA_NAME(m.object_id) + N'.' + OBJECT_NAME(m.object_id) AS object_name,
o.type_desc,
m.uses_ansi_nulls,
m.uses_quoted_identifier
FROM sys.sql_modules AS m
JOIN sys.objects AS o ON o.object_id = m.object_id
WHERE m.uses_ansi_nulls = 0 OR m.uses_quoted_identifier = 0
ORDER BY o.type_desc, object_name;
Tablolardaki kolonlar da oluşturulduklarındaki ANSI_PADDING ayarını saklar; eski tablolarda OFF ile oluşturulmuş char ve varchar kolonlar bulunabilir:
SELECT OBJECT_NAME(c.object_id) AS table_name, c.name AS column_name,
TYPE_NAME(c.user_type_id) AS data_type, c.is_ansi_padded
FROM sys.columns AS c
JOIN sys.tables AS t ON t.object_id = c.object_id
WHERE c.is_ansi_padded = 0
AND TYPE_NAME(c.user_type_id) IN (N'char', N'varchar', N'binary', N'varbinary');
Düzeltmek
Sorunlu bir modülü düzeltmenin yolu, doğru ayarlarla yeniden oluşturmaktır:
SET ANSI_NULLS ON;
SET QUOTED_IDENTIFIER ON;
GO
CREATE OR ALTER PROCEDURE dbo.SiparisEkle
@MusteriId int, @Tutar decimal(19, 4)
AS
BEGIN
INSERT INTO dbo.Siparis (MusteriId, Tutar) VALUES (@MusteriId, @Tutar);
END
GO
QUOTED_IDENTIFIER ON ile çift tırnak artık metin değil, nesne adı sınırlayıcısıdır. Eski kodda metinler çift tırnakla yazılmışsa (WHERE Durum = "Aktif"), yeniden oluşturmadan önce bunları tek tırnağa çevirmeniz gerekir; aksi halde “Invalid column name” hatası alırsınız.
Uyarı
Toplu düzeltmeyi doğrudan üretimde yapmayın. Önce modüllerin script’ini alın, çift tırnak kullanımını kontrol edin, test ortamında yeniden oluşturup çalıştırın. Procedure’ü yeniden oluşturmak, ona verilmiş yetkileri korur (CREATE OR ALTER ya da ALTER kullanıldığında); DROP ve CREATE ise yetkileri siler.
“SSMS’te Hızlı, Uygulamada Yavaş”: ARITHABORT
SSMS, varsayılan olarak ARITHABORT ON ile bağlanır; birçok uygulama sürücüsü ise OFF ile bağlanır. SET seçenekleri plan cache anahtarının parçası olduğu için, aynı sorgu SSMS’ten ve uygulamadan çalıştırıldığında iki ayrı plan derlenir. Uygulamanın planı kötü bir parametre değeriyle derlenmişse, sorgu uygulamada yavaş, SSMS’te hızlı görünür; bu genellikle ARITHABORT’un kendisinden değil, farklı planlardan kaynaklanır.
İpucu
Bir sorgunun neden uygulamada yavaş olduğunu araştırırken, SSMS’te aynı plana ulaşmak için oturumunuzu uygulamanın ayarlarıyla eşleştirin (örneğin SET ARITHABORT OFF) ve sys.dm_exec_plan_attributes ile iki planın set_options değerlerini karşılaştırın. Kalıcı çözüm genellikle parametre hassasiyetini gidermek ya da Query Store ile iyi planı sabitlemektir.
Kontrol Listesi
- Tüm modüller ANSI_NULLS ve QUOTED_IDENTIFIER ON ile oluşturulmuş.
- Script şablonları bu ayarları kapatmıyor.
- Filtered index ya da indexed view eklemeden önce tabloya yazan nesneler kontrol edildi.
- Çift tırnakla yazılmış metinler tek tırnağa çevrildi.
- Uygulama ile SSMS arasındaki plan farkları set_options ile incelendi.
İlgili Yazılar
SQL Server Danışmanlığı
Eski kodu yeni özelliklere hazırlayın
Aryasoft’un kıdemli DBA ekibi veritabanı nesnelerinizdeki uyumsuz SET ayarlarını ve sözdizimi sorunlarını bulur, test ederek düzeltir ve filtered index, indexed view gibi özellikleri güvenle devreye alır.