سلام!!
در 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 صحیح را رعایت کنید.
اسکریپت عکس بالا:
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
موفق باشید