Aracılığıyla paylaş


Kapsanan veritabanı harmanlamaları

Şunlar için geçerlidir:SQL ServerAzure SQL Yönetilen Örneği

Büyük/küçük harf duyarlılığı, vurgu duyarlılığı ve kullanılan temel dil gibi çeşitli özellikler metin verilerinin sıralama düzenini ve eşitlik semantiğini etkiler. Bu nitelikler, veriler için harmanlama seçimi aracılığıyla SQL Server'a ifade edilir. Harmanlamaların daha ayrıntılı bir tartışması için bkz. Harmanlama ve Unicode desteği.

Harmanlamalar yalnızca kullanıcı tablolarında depolanan veriler için değil, meta veriler, geçici nesneler, değişken adları vb. dahil olmak üzere SQL Server tarafından işlenen tüm metinler için de geçerlidir. Bunların işlenmesi, kapsanan ve içerilmeyen veritabanlarında farklılık gösterir. Bu değişiklik birçok kullanıcıyı etkilemez, ancak örneğin bağımsızlığını ve tekdüzeliğini sağlamaya yardımcı olur. Ancak bu, hem kapsanan hem de içerilmeyen veritabanlarına erişen oturumlarda bazı karışıklıklara ve sorunlara neden olabilir.

Kapsanan veritabanlarının harmanlama davranışı, kapsanmayan veritabanlarındaki davranıştan çok farklıdır. Bu davranış genellikle faydalıdır ve örnek bağımsızlığı ve basitliği sağlar. Bazı kullanıcılar, özellikle oturum hem kapsanan hem de kapsanmayan veritabanlarına eriştiğinde sorunlarla karşılaşabilir.

Bu makale, değişikliğin içeriğini açıklar ve değişikliğin sorunlara neden olabileceği alanları inceler.

Uyarı

Azure SQL Veritabanı için, kapsanan veritabanlarının harmanlamaları farklıdır. Veritabanı harmanlaması ve katalog harmanlaması veritabanı oluşturma işleminde ayarlanabilir ve güncelleştirilemez. Veriler için bir sıralama düzeni (COLLATE) ve sistem meta verileri ile nesne tanımlayıcıları için bir katalog sıralama düzeni (CATALOG_COLLATION) belirtin. Daha fazla bilgi için bkz . CREATE DATABASE.

Bağımsız veritabanları

Tüm veritabanlarının varsayılan harmanlaması vardır (veritabanı oluşturulurken veya değiştirildiğinde ayarlanabilir). Bu harmanlama, veritabanındaki tüm meta veriler için ve veritabanı içindeki tüm dize sütunları için varsayılan olarak kullanılır. Kullanıcılar, yan tümcesini COLLATE kullanarak herhangi bir sütun için farklı bir harmanlama seçebilir.

Örnek 1

Örneğin Pekin'de çalışıyor olsaydık Çince harmanlama kullanabilirdik:

ALTER DATABASE MyDB
    COLLATE Chinese_Simplified_Pinyin_100_CI_AS;

Şimdi bir sütun oluşturursak varsayılan harmanlaması şu Çince harmanlamadır, ancak isterseniz başka bir sütun seçebiliriz:

CREATE TABLE MyTable
(
    mycolumn1 NVARCHAR,
    mycolumn2 NVARCHAR COLLATE Frisian_100_CS_AS
);
GO

SELECT name, collation_name
FROM sys.columns
WHERE name LIKE 'mycolumn%';
GO

Sonuç kümesi aşağıdadır.

name            collation_name
--------------- ----------------------------------
mycolumn1       Chinese_Simplified_Pinyin_100_CI_AS
mycolumn2       Frisian_100_CS_AS

Bu nispeten basit görünür, ancak birkaç sorun ortaya çıkar. Bir sütunun harmanlaması, tablonun oluşturulduğu veritabanına bağlı olduğundan, içinde tempdbdepolanan geçici tabloların kullanılmasıyla ilgili sorunlar ortaya çıkar. harmanlaması tempdb genellikle örneğin harmanlaması ile eşleşir, ancak veritabanı harmanlaması ile eşleşmek zorunda değildir.

Örnek 2

Örneğin, Latin1_General karşılaştırması ile bir örnekte kullanıldığında daha önce gösterilen Çince veritabanını göz önünde bulundurun.

CREATE TABLE T1 (T1_txt NVARCHAR (MAX));
GO

CREATE TABLE #T2 (T2_txt NVARCHAR (MAX));
GO

İlk bakışta, bu iki tablo aynı şemaya sahip gibi görünür, ancak veritabanlarının harmanlamaları farklı olduğundan, değerler uyumsuz:

SELECT T1_txt, T2_txt
FROM T1
     INNER JOIN #T2
         ON T1.T1_txt = #T2.T2_txt;

Sonuç kümesi aşağıdadır.

Msg 468, Düzey 16, Durum 9, Satır 2

Eşittir işleminde "Latin1_General_100_CI_AS_KS_WS_SC" ile "Chinese_Simplified_Pinyin_100_CI_AS" arasındaki harmanlama çakışması çözülemiyor.

Geçici tabloyu açıkça harmanlayarak bunu düzeltebiliriz. SQL Server, COLLATE ifadesi için DATABASE_DEFAULT anahtar sözcüğünü sağlayarak bunu kolaylaştırır.

CREATE TABLE T1 (T1_txt NVARCHAR (MAX));
GO

CREATE TABLE #T2 (T2_txt NVARCHAR (MAX) COLLATE DATABASE_DEFAULT);
GO

SELECT T1_txt, T2_txt
FROM T1
     INNER JOIN #T2
         ON T1.T1_txt = #T2.T2_txt;

Bu sorgu artık hatasız çalıştırılır.

Değişkenlerle harmanlama bağımlı davranışı da görebiliriz. Aşağıdaki işlevi göz önünde bulundurun:

CREATE FUNCTION f (@x INT)
RETURNS INT
AS
BEGIN
    DECLARE @I AS INT = 1;
    DECLARE @İ AS INT = 2;
    RETURN @x * @i;
END

Bu oldukça tuhaf bir işlevdir. Büyük/küçük harfe duyarlı bir harmanlamada, @i, dönüş ifadesi @I veya öğesine bağlanamaz. Büyük/küçük harfe duyarsız Latin1_General harmanlamada, @i, @I ile bağlanır ve işlev 1 döndürür. Ancak büyük/küçük harfe duyarsız bir Türkçe sırasız harmanlamada, @i öğesi ile eşleşir ve işlev 2 sonucunu döndürür. Bu, farklı harmanlamalara sahip örnekler arasında hareket eden bir veritabanında hasara neden olabilir.

İçerilen veritabanları

Kapsanan veritabanlarının tasarım amacı, bunları bağımsız hale getirmek olduğundan, örneğe ve tempdb harmanlamalara bağımlılığın kesilmesi gerekir. Bunu yapmak için, içerilen veritabanları katalog sıralaması kavramını tanıtır. Katalog harmanlaması, sistem meta verileri ve geçici nesneler için kullanılır. Ayrıntılar aşağıdaki gibi sağlanır.

Kapsanan veritabanında katalog harmanlaması şeklindedir Latin1_General_100_CI_AS_WS_KS_SC. Bu harmanlama, SQL Server'ın tüm örneklerindeki tüm kapsanan veritabanları için aynıdır ve değiştirilemez.

Veritabanı harmanlaması korunur, ancak yalnızca kullanıcı verileri için varsayılan harmanlama olarak kullanılır. Varsayılan olarak, veritabanı harmanlaması veritabanı harmanlamasına model eşittir, ancak kullanıcı tarafından içerilmeyen veritabanlarında olduğu gibi bir CREATE veya ALTER DATABASE komutu aracılığıyla değiştirilebilir.

CATALOG_DEFAULT anahtar sözcüğü, COLLATE yan tümcesinde kullanılabilir. Bu, hem kapsanan hem de kapsam dışı veritabanlarındaki meta verilerin mevcut harmanlamasının kısayolu olarak kullanılır. Yani, bağımsız bir veritabanında meta CATALOG_DEFAULT veriler veritabanı harmanlamasında harmanlandığından geçerli veritabanı harmanlamasını döndürür. Kapsanan veritabanında bu iki değer farklı olabilir, çünkü kullanıcı veritabanı harmanlamasını katalog harmanlaması ile eşleşmemesi için değiştirebilir.

Hem bağımsız hem de kapsanan veritabanlarındaki çeşitli nesnelerin davranışı şu tabloda özetlenmiştir:

Ürün İzole edilmemiş veritabanı Barındırılan veritabanı
Kullanıcı verileri (varsayılan) DATABASE_DEFAULT DATABASE_DEFAULT
Geçici veriler (varsayılan) tempdb Harmanlama DATABASE_DEFAULT
Meta veriler DATABASE_DEFAULT / CATALOG_DEFAULT CATALOG_DEFAULT
Geçici meta veriler tempdb Harmanlama CATALOG_DEFAULT
Variables Örnek harmanlama CATALOG_DEFAULT
Goto etiketleri Örnek harmanlama CATALOG_DEFAULT
İmleç adları Örnek harmanlama CATALOG_DEFAULT

Daha önce açıklanan geçici tablo örneğinde, bu harmanlama davranışının çoğu geçici tablo kullanımlarında açık COLLATE yan tümce gereksinimini ortadan kaldırdığını görebiliriz. Kapsanan bir veritabanında, veritabanı ve örnek harmanlamaları farklı olsa bile bu kod artık hatasız çalışır:

CREATE TABLE T1 (T1_txt NVARCHAR (MAX));
GO

CREATE TABLE #T2 (T2_txt NVARCHAR (MAX));
GO

SELECT T1_txt, T2_txt
FROM T1
     INNER JOIN #T2
         ON T1.T1_txt = #T2.T2_txt;

Bu sorgu çalışır çünkü hem T1_txt hem de T2_txt içerdiği veritabanı düzenlemesinde harmanlanır.

Sınırlı ve sınırsız bağlamlar arasında geçiş

Kapsanan veritabanındaki bir oturum kapsandığı sürece, bağlandığı veritabanı içinde kalmalıdır. Bu durumda, davranış basittir. Ancak bir oturum, kapsanan ve olmayan bağlamlar arasında kesişirse, iki kural kümesinin köprülenmiş olması gerektiğinden davranış daha karmaşık hale gelir. Bu, kısmen kapsanan bir veritabanında gerçekleşebilir, çünkü bir kullanıcı başka bir veritabanına gidebilir USE . Bu durumda harmanlama kurallarındaki fark aşağıdaki ilke tarafından ele alınır.

  • Toplu iş için harmanlama davranışı, toplu işlemin başladığı veritabanı tarafından belirlenir.

Bu karar, başlangıçtaki USEkomutlar da dahil olmak üzere herhangi bir komut verilmeden önce verilir. Başka bir ifadeyle, bir toplu iş kapsanan bir veritabanında başlıyorsa, ancak ilk komut bağımsız bir veritabanına yönelikse USE , toplu iş için kapsanan harmanlama davranışı hala kullanılır. Bu senaryo göz önünde bulundurulduğunda, örneğin bir değişkene yapılan başvuru birden çok olası sonuca sahip olabilir:

  • Referans tam olarak bir eşleşme bulabilir. Bu durumda, referans hatasız işler.

  • Başvuru, önceden bir eşleşme bulunduğu halde, mevcut harmanlamada bulunamayabilir. Bu, görünüşe göre oluşturulmuş olsa bile değişkenin mevcut olmadığını belirten bir hataya neden olur.

  • Referans, başlangıçta farklı olan birden fazla eşleşme bulabilir. Bu da bir hataya neden olur.

Bunu birkaç örnekle göstereceğiz. Bunlar için, adı MyCDB olan ve varsayılan harmanlama Latin1_General_100_CI_AS_WS_KS_SC olarak ayarlanmış kısmen kapsanan bir veritabanı olduğunu varsayıyoruz. Örnek karşılaştırmasının Latin1_General_100_CS_AS_WS_KS_SC olduğunu varsayıyoruz. İki sıralama yalnızca büyük/küçük harf duyarlılığı açısından farklılık gösterir.

Örnek 1

Aşağıdaki örnek, referansın tam olarak bir eşleşme bulduğunda durumu göstermektedir.

USE MyCDB;
GO

CREATE TABLE #a (x INT);

INSERT INTO #a VALUES (1);
GO

USE master;
GO

SELECT * FROM #a;
GO

Results:

Sonuç kümesi aşağıdadır.

x
-----------
1

Bu durumda, tanımlanan #a hem büyük/küçük harfe duyarlı olmayan katalog harmanlamasında hem de büyük/küçük harfe duyarlı örnek harmanlamasında bağlanır ve kod çalışır.

Örnek 2

Aşağıdaki örnek, başvurunun daha önce bir eşleşme bulunduğu bir harmanlamada, mevcut harmanlamada eşleşme bulamadığı durumu gösterir.

USE MyCDB;
GO

CREATE TABLE #a (x INT);

INSERT INTO #A VALUES (1);
GO

Burada, #A büyük/küçük harfe duyarlı olmayan varsayılan harmanlamada #a ile bağlanır ve ekleme başarılı olur,

Sonuç kümesi aşağıdadır.

(1 row(s) affected)

Ancak kodu devam ettirirsek...

USE master;
GO

SELECT * FROM #A;
GO

Büyük/küçük harfe duyarlı örnek harmanlamasında bağlanmaya #A çalışılırken bir hatayla karşılaşırız;

Sonuç kümesi aşağıdadır.

Msg 208, Level 16, State 0, Line 2
Invalid object name '#A'.

Örnek 3

Aşağıdaki örnekte, başvurunun özgün olarak farklı olan birden çok eşleşmeyi bulduğu durum gösterilmektedir. İlk olarak, örneğimizle aynı büyük/küçük harfe duyarlı harmanlamaya sahip olan tempdb içinde başlıyoruz ve aşağıdaki ifadeleri çalıştıracağız.

USE tempdb;
GO

CREATE TABLE #a (x INT);
GO

CREATE TABLE #A (x INT);
GO

INSERT INTO #a VALUES (1);
GO

INSERT INTO #A VALUES (2);
GO

Tablolar bu harmanlamada ayrı olduğundan bu sorgu başarılı olur:

Sonuç kümesi aşağıdadır.

(1 row(s) affected)
(1 row(s) affected)

Kendi veritabanımıza geçtiğimizde, artık bu tablolara bağlanamayacağımızı fark ediyoruz.

USE MyCDB;
GO

SELECT * FROM #a;
GO

Sonuç kümesi aşağıdadır.

Msg 12800, Level 16, State 1, Line 2
The reference to temp table name #a is ambiguous and cannot be resolved. Possible candidates are #a and #A.