Asp.net преобразование и отображение китайских иероглифов varchar на лету

#sql #asp.net

Вопрос:

Несколько лет назад я допустил ошибку и создал столбцы varchar в SQL Server для хранения URL-адресов. И поэтому мой сайт не может правильно отображать китайские URL-адреса. Теперь база данных огромна, и в ней слишком много связей, индексов, ограничений и т. Д… И поэтому было бы чрезвычайно сложно изменить столбцы varchar на nvarchar.

Я планировал добавить новые столбцы nvarchar и изменить все хранимые процедуры и asp.net классы и коды, а затем удалите существующие столбцы varchar. Но я только что понял, что Google каким-то образом может конвертировать данные varchar в nvarchar.

Например, ниже приведен URL-адрес веб-сайта в моей базе данных, который является китайским(или японским, на самом деле не уверен) веб-сайтом, и когда я выполняю поиск в Google, Google может находить и отображать китайские иероглифы.

Поэтому мне интересно, есть ли способ конвертировать символы varchar на лету с помощью C# или T-SQL. Google, вероятно, сохраняет обе версии, и, насколько я знаю, это невозможно, но я просто хотел спросить, есть ли способ разобраться в этом.

введите описание изображения здесь

Ответ №1:

 using System;
using System.Globalization;
                    
public class Program
{
    public static void Main()
    {
        var idn = new IdnMapping();
        var url = "xn--ssd-7b7fj34n.com";
        var punyCode = idn.GetAscii(url);
        var url2 = idn.GetUnicode(punyCode);
        Console.WriteLine(url2); // result is ssd換装.com
    }
}
 

Демо-версия Ideon

Комментарии:

1. Спасибо, Хан, это здорово.

Ответ №2:

Я поставил скрипт, который может легко изменять тип столбцов данных. Следующий код изменяет весь varchar столбец на nvarchar с той же длиной данных.

Примечание: Введите имя базы данных, которую вы хотите, вместо :

 Use dataBaseName
Go
 

Полный сценарий


 use dataBaseName
go

--Container to Insert Id which are to be iterated
Declare @temp Table
(
  tablename varchar(100),
  columnname varchar(100),
  columnlength varchar(100),
  columntype varchar(100)
)
--Container to Insert records in the inner select for final output

Insert into @temp

SELECT t.TABLE_NAME,c.COLUMN_NAME,c.CHARACTER_MAXIMUM_LENGTH,c.DATA_TYPE 
FROM information_schema.tables t
join INFORMATION_SCHEMA.COLUMNS c on t.TABLE_NAME = c.TABLE_NAME
WHERE DATA_TYPE = 'varchar'

-- Keep track of @temp record processing
Declare @tablename varchar(100)
Declare @columnname varchar(100)
Declare @columnlength varchar(100)
Declare @columntype varchar(100)
Declare @SQL VarChar(1000)

While((Select Count(*) From @temp)>0)
Begin
   Set @tablename=(Select Top 1 tablename From @temp)
   Set @columnname=(Select Top 1 columnname From @temp)
   Set @columnlength=(Select Top 1 columnlength From @temp)
   Set @columntype='nvarchar'


--set null value with empty value

   SELECT @SQL = 'UPDATE '   @tablename   ' SET '   @columnname   ' = 0 WHERE '   @columnname    ' IS NULL'
   Exec ( @SQL)


   SELECT @SQL = 'ALTER TABLE '
   SELECT @SQL = @SQL   @tablename
   SELECT @SQL = @SQL   ' ALTER COLUMN '   @columnname   ' '   @columntype   '('   @columnlength   ') NOT NULL'

--execute command
   Exec (@SQL)
   Delete @temp Where tablename=@tablename and columnname = @columnname
End
 

Перед запуском создайте тестовую базу данных, поместите в нее резервную копию
исходной базы данных и запустите сценарий в тестовой базе данных. Если
результат будет успешным, создайте резервную копию тестовой базы данных и
замените ее исходной базой данных.