Ali Momen
Ali Momen
خواندن ۲ دقیقه·۳ سال پیش

بهترین پیشنهاد برای تنظیم Collation فارسی در SQL Server 2019

سلام!!

در SQL Server اگر بعد از ریختن اطلاعات، Collation رو برای varchar از لاتین به فارسی اصلاح کنیم اطلاعات فارسی ما از بین میرن و قابل بازیابی نیستند و باید دوباره insert بشن. حتی بعضی موقع ها باید جدول رو drop کنیم و دوباره بسازیم و truncate یا delete کردن اون هم مشکلو حل نمیکنه و اطلاعات بعدی که ریخته میشوند (حتی با درست بودن collation) از بین میرن. البته رفتار SQL Server در مورد Collation فارسی خیلی خیلی inconsistent هست و best practice این هست که هنگام ساختن database اگر collation سرور فارسی نیست (منظور من از فارسی نبودن لاتین هست)، collation دیتابیس رو همان موقع فارسی تنظیم کنیم.

در هر صورت این را هم می دانیم که nvarchar همواره اطلاعات را به جز sort صحیح آن تحت هر Collation ای برای نوشته فارسی صحیح نگه می دارد و صحبت ما اینجا در مورد varchar است. واضح است که اگر هم همیشه از nvarchar استفاده میکنید برای sort صحیح باید تنظیم Collation صحیح را رعایت کنید.

تست اطلاعات و collation فارسی در SQL Server 2019
تست اطلاعات و collation فارسی در SQL Server 2019

اسکریپت عکس بالا:

use master

go

alter database test_collation

set single_user with rollback immediate

drop database test_collation

go


create database test_collation

go


-------- changing database collation to Latin

alter database test_collation

collate SQL_Latin1_General_CP1_CI_AS


use test_collation


drop table if exists t1

create table t1 (t1c1 uniqueidentifier primary key not null , t1c2 varchar(100) collate Persian_100_CI_AS, t1c3 varchar(100))

go


insert into t1 (t1c1,t1c2,t1c3) values (newid(),N'علی',N'رضا')

go


select DATABASEPROPERTYEX('test_collation','collation') DBCollation


select * from t1


-------- changing database collation to Persian

alter database test_collation

collate Persian_100_CI_AS


-------- insert after database collation change

insert into t1 (t1c1,t1c2,t1c3) values (newid(),N'علی',N'رضا')


select * from t1


-------- reinsert data after table truncation

truncate table t1

insert into t1 (t1c1,t1c2,t1c3) values (newid(),N'علی',N'رضا')

select * from t1


-------- Reading data with low-level data access commands to see if the original inserted unicode data can be recovered or not

create table [page] (ParentObject nvarchar(255), [Object] nvarchar(255), Field nvarchar(255), [VALUE] nvarchar(255))

declare @PageNumber int

SELECT @PageNumber = (select top 1 cast(parsename(replace(sys.fn_PhysLocFormatter(%%PhysLoc%%),':','.'),2) as int) from t1)

declare @sql nvarchar(max) = 'DBCC PAGE(''test_collation'' , 1 , '+cast(@PageNumber as nvarchar(4))+' , 3) WITH TABLERESULTS'

insert into [page]

exec (@sql)

select (select ascii(VALUE) from page where Field ='t1c2') as [t1c2], (select ascii(VALUE) from page where Field ='t1c3') as [t1c3]

-- 63 is ascii code for '?'


-------- drop and create table t1 again and reinserting the values

drop table t1

create table t1 (t1c1 uniqueidentifier primary key not null , t1c2 varchar(100) collate Persian_100_CI_AS, t1c3 varchar(100))

go

insert into t1 (t1c1,t1c2,t1c3) values (newid(),N'علی',N'رضا')

select * from t1


-------- create table t2 with identical definition

drop table if exists t2

create table t2 (t2c1 uniqueidentifier primary key not null , t2c2 varchar(100), t2c3 varchar(100))

go

insert into t2 (t2c1,t2c2,t2c3) values (newid(),N'علی',N'رضا')

select * from t2

go

موفق باشید

sql serverpersian collationmicrosoft
شاید از این پست‌ها خوشتان بیاید