Control panel with toggle switches, one set differently, representing SQL Server SET options on objects

Yanlış SET Seçenekleriyle Oluşturulan SQL Server Nesneleri: Msg 1934, Filtered Index ve ARITHABORT

QUOTED_IDENTIFIER ya da ANSI_NULLS kapalıyken oluşturulan procedure’lerin neden Msg 1934 ile filtered index ve indexed view’ları bozduğu, nasıl bulunup düzeltileceği ve SSMS ile uygulama arasındaki plan farkı.

Şubat 2, 2022

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.

SQL Server Danışmanlığı

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.

Destek Alın

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:

▤ Messages

Msg 1934, Level 16, State 1 INSERT failed because the following SET options have incorrect settings: ‘QUOTED_IDENTIFIER’. Verify that SET options are correct for use with indexed views and/or indexes on computed columns and/or filtered indexes and/or query notifications and/or XML data type methods and/or spatial index operations.

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.
Filtered index, indexed view ya da hesaplanmış kolon index’i olan bir tabloda, gerekli SET seçenekleri (örneğin QUOTED_IDENTIFIER ON) sağlanmadan işlem yapıldığında. Çoğu zaman sorunlu nesne, yanlış ayarlarla oluşturulmuş eski bir procedure’dür.
ANSI_NULLS ve QUOTED_IDENTIFIER. Modül, oluşturulduğu andaki bu ayarlarla çalışır.
sys.sql_modules görünümünde uses_ansi_nulls = 0 ya da uses_quoted_identifier = 0 olan modüller listelenir.
SSMS ve uygulama farklı SET seçenekleriyle bağlandığı için aynı sorgu için iki ayrı plan derlenir. Uygulamanın planı farklı bir parametre değerine göre derlenmiş olabilir.

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.

4.7/5