اگر ديتابيس خود را در طي چند سال از يك نگارش به نگارشي ديگر يا از يك سرور به سروري ديگر منتقل كرده باشيد، به احتمال زياد به مشكلات Collations هم برخوردهايد. يكي از فيلدها Arabic_CI_AS است (بجا مانده از دوران قبل از SQL Server 2008) در يك جدول و در جدولي ديگر فيلدي تازهاي با Collation از نوع Persian_100_CI_AS تعريف شده است. Collations نحوه ذخيره سازي و مقايسه رشتهها را كنترل ميكنند. زمانيكه يك جدول جديد را در SQL Server ايجاد ميكنيم، اگر Collation فيلدها به صورت صريح ذكر نگردند، بر مبناي همان Collation پيش فرض ديتابيس تعريف خواهند شد.
بنابراين اگر پس از استفاده از SQL Server 2008 و تنظيم Collation پيش فرض ديتابيس به Persian_100_CI_AS ، به اين موارد دقت نكنيم، دير يا زود دچار مشكل خواهيم شد.
عمليات مرتب سازي با وجود تداخلات Collations مشكل ساز نميشود (خطايي دريافت نميكنيد)، اما ممكن است الزاما صحيح عمل نكند. مشكل از آنجايي آغاز ميشود كه قصد داشته باشيم دادهها را مقايسه كنيم يا join ايي بين اين دو جدول با فيلدهاي ناهمگون از لحاظ Collation ايجاد نمائيم. در اين حالت حتما خطاهاي تداخل Collation را دريافت كرده و كوئريهاي ما اجرا نخواهند شد.
Cannot resolve collation conflict for equal to operation
يك راه حل اين است كه در حين join به صورت صريح collation هر دو فيلد ذكر شده را به صورت يكسان ذكر كنيم كه بيشتر يك مرهم موقتي است تا راه حل اصولي. براي مثال:
SELECT ID
FROM ItemsTable
INNER JOIN AccountsTable
WHERE ItemsTable.Collation1Col COLLATE DATABASE_DEFAULT
= AccountsTable.Collation2Col COLLATE DATABASE_DEFAULT
اسكريپت زير تمام فيلدهاي ناهمگون از لحاظ Collation ديتابيس جاري را براي شما ليست خواهد كرد:
DECLARE @defaultCollation NVARCHAR(1000)
SET @defaultCollation = CAST(
DATABASEPROPERTYEX(DB_NAME(), 'Collation') AS NVARCHAR(1000)
)
SELECT C.Table_Name,
Column_Name,
Collation_Name,
@defaultCollation DefaultCollation
FROM Information_Schema.Columns C
INNER JOIN Information_Schema.Tables T
ON C.Table_Name = T.Table_Name
WHERE T.Table_Type = 'Base Table'
AND RTRIM(LTRIM(Collation_Name)) <> RTRIM(LTRIM(@defaultCollation))
AND COLUMNPROPERTY(OBJECT_ID(C.Table_Name), Column_Name, 'IsComputed') = 0
ORDER BY
C.Table_Name,
C.Column_Name
ALTER TABLE [tblArchive] ALTER COLUMN [Serial] nvarchar(200) COLLATE Persian_100_CI_AS not null