#sql #sql-server #entity-framework #linq #chinese-locale
#sql #sql-сервер #entity-framework #linq #китайский-locale
Вопрос:
При поиске строки в нашей базе данных, где столбец имеет тип nvarchar, указание префикса ‘N’ в запросе приводит к некоторым результатам. Исключение этого не делает. Я пытаюсь выполнить поиск упрощенной китайской строки в базе данных, которая ранее еще не хранила никаких китайских строк.
Приложение EntityFramework, которое использует базу данных, правильно извлекает строки, и запросы LINQ также работают в приложении. Однако в SQL Server 2014 Management Studio, когда я выполняю SQL-запрос для строки, он не отображается, если я не укажу префикс ‘N’ для unicode. (Даже если столбец имеет тип nvarchar)
Работает:
var text = from asd in Translations.TranslationStrings
where asd.Text == "嗄法吖无上几"
select asd;
MessageBox.Show(text.FirstOrDefault().Text);
Не работает:
SELECT *
FROM TranslationStrings
where Text = '嗄法吖无上几'
Если я добавлю в префикс китайских символов ‘N’, это сработает.
Работает:
SELECT *
FROM TranslationStrings
where Text = N'嗄法吖无上几'
Пожалуйста, извините за китайские символы, я просто набрал что-то случайное. Мой вопрос в том, могу ли я что-нибудь сделать, чтобы не включать префикс ‘N’ при выполнении запроса?
Большое вам спасибо!
Комментарии:
1. Привет, пожалуйста, поделитесь конфигурацией сортировки экземпляра SQL и версией SQL Server
2. В чем проблема с префиксом, почему вы не хотите его использовать? Это всего лишь второстепенный элемент синтаксиса в виде одинарных кавычек вокруг литерала, я не вижу никакого вреда или особых усилий в его размещении.
3. (N) литералы varchar используют кодовую базу базы данных по умолчанию, если префикс N не используется. Вы можете изменить параметры сортировки базы данных с помощью команды ALTER DATABASE […] COLLATE .
4. 1) Почему вам нужно избавиться от
N
префикса? 2) Вы передаете строку в качестве параметра или просто объединяете строку? 3) Если вы используете параметры, каков тип данных этого параметра?5. Не думайте об этом как о каком-то префиксе. Подумайте о
N'
как о другом виде открывающей кавычки . Вы, предположительно , не задали бы вопрос о том, как вы могли бы опустить открывающие кавычки из строк, не так ли?
Ответ №1:
Как упоминал @sworkalot ниже:
По умолчанию для .Net используется Unicode, поэтому вам не нужно его указывать. Это не относится к Sql Manager.
Если не указано, Sql будет считать, что вы работаете с asci в соответствии с параметрами сортировки, указанными в вашей БД.
Следовательно, при работе с Sql Server вам необходимо использовать N’
Ознакомьтесь с этими примерами, обратите пристальное внимание на типы данных и присваиваемые значения:
DECLARE @Varchar VARCHAR(100) = '嗄'
DECLARE @VarcharWithN VARCHAR(100) = N'嗄' -- Has N prefix
DECLARE @NVarchar NVARCHAR(100) = '嗄'
DECLARE @NVarcharWithN NVARCHAR(100) = N'嗄' -- Has N prefix
SELECT
Varchar = @Varchar,
VarcharWithN = @VarcharWithN,
NVarchar = @NVarchar,
NVarcharWithN = @NVarcharWithN
SELECT
Varchar = CONVERT(VARBINARY, @Varchar),
VarcharWithN = CONVERT(VARBINARY, @VarcharWithN),
NVarchar = CONVERT(VARBINARY, @NVarchar),
NVarcharWithN = CONVERT(VARBINARY, @NVarcharWithN)
Результаты:
Varchar VarcharWithN NVarchar NVarcharWithN
? ? ? 嗄
Varchar VarcharWithN NVarchar NVarcharWithN
0x3F 0x3F 0x3F00 0xC455
NVARCHAR
тип данных хранит 2 байта для каждого символа, в то время как VARCHAR
хранит только 1 (вы можете видеть это при VARBINARY
приведении ко 2-му SELECT
). Поскольку для хранения представления китайских символов требуется 2 байта, вы должны использовать NVARCHAR
для их хранения. Если вы попытаетесь вставить их в a, VARCHAR
это будет сохранено как ?
, и вы потеряете исходную информацию о символах. Это также происходит в 3-м примере, потому что литерал не имеет N
поэтому он преобразуется в VARCHAR
перед фактическим присвоением значения переменной.
Именно из-за этого вам нужно добавить N
префикс при вводе этих символов в виде литералов, чтобы механизм SQL знал, что вы вводите символы, которым требуется представление в 2 байта. Поэтому, если вы проводите сравнение с NVARCHAR
столбцом, всегда добавляйте N
префикс. Вы можете изменить параметры сортировки базы данных, но рекомендуется всегда использовать правильный тип данных независимо от параметров сортировки, чтобы у вас не возникало проблем при использовании кодирования в разных базах данных.
Если бы вы могли объяснить причину, по которой вы хотите опустить N
префикс, мы могли бы обратиться к этому, хотя я считаю, что в этом конкретном случае нет обходного пути.
Комментарии:
1. Спасибо за ответ! Я искал способ избавиться от этого, чтобы упростить работу для других, которым нужно будет работать с базой данных. В прошлом нам не приходилось этого делать, поэтому с этого момента людям нужно будет помнить об этом. К счастью, большая часть взаимодействия с базой данных происходит через . СЕТЬ, которая будет работать. (Как указано в ответе от srworksalot)
2. @bluiska и EzLo: Привет. Разница между
VARCHAR
иNVARCHAR
заключается в размере «единиц», которые используются в комбинациях для создания символов в определенной кодировке.VARCHAR
, 8-разрядный тип, создает символы в комбинациях от 1 до 4 байт, но всегда в 1 байтовых единицах.NVARCHAR
, 16-разрядный тип, создает символы в 2 или 4 байтах, но всегда в 2 байтовых единицах. Для получения подробной информации, пожалуйста, прочитайте мой пост: Сколько байт на символ в SQL Server: полностью полное руководство
Ответ №2:
По умолчанию для .Net используется Unicode, поэтому вам не нужно его указывать. Это не относится к Sql Manager.
Если не указано, Sql будет считать, что вы работаете с asci в соответствии с параметрами сортировки, указанными в вашей БД.
Следовательно, при работе с Sql Server вам необходимо использовать N’
Комментарии:
1. Большое спасибо! Предполагая, что это ASCII, я мог бы понять, почему это не сработает.