Как мне избавиться от необходимости ставить префикс WHERE для запроса «N» для строк Unicode? - PullRequest
4 голосов
/ 02 апреля 2019

При поиске строки в нашей базе данных, где столбец имеет тип nvarchar, указание префикса 'N' в запросе приводит к некоторым результатам. Оставить это не так. Я пытаюсь найти строку с упрощенным китайским в базе данных, которая ранее еще не сохраняла строки на китайском.

Приложение EntityFramework, которое использует базу данных, корректно извлекает строки, и запросы LINQ также работают в приложении. Однако в SQL Server 2014 Management Studio, когда я выполняю SQL-запрос для строки, он не отображается, если я не укажу префикс «N» для юникода. (Хотя столбец имеет тип 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» при выполнении запроса?

Большое спасибо!

Ответы [ 2 ]

1 голос
/ 02 апреля 2019

Как @sworkalot упомянул ниже:

По умолчанию для .Net используется Юникод, поэтому вам не нужно указывать Это. Это не относится к Sql Manager.

Если не указано, Sql будет считать, что вы работаете с Asci в соответствии с сортировка указана в вашей БД.

Следовательно, при работе с Sql Server вам необходимо использовать N '

https://sqlquantumleap.com/2018/09/28/native-utf-8-support-in-sql-server-2019-savior-false-prophet-or-both/

Посмотрите эти примеры, обратите пристальное внимание на типы данных и присваиваемые значения:

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. Если вы попытаетесь вставить их в VARCHAR, он будет сохранен как ?, и вы потеряете исходную информацию о персонаже. Это также происходит в третьем примере, потому что литерал не имеет N, поэтому он преобразуется в VARCHAR перед тем, как присвоить значение переменной.

Из-за этого вам нужно добавить префикс N при вводе этих символов в виде литералов, поэтому механизм SQL знает, что вы печатаете символы, для которых необходимо 2-байтовое представление. Поэтому, если вы проводите сравнение со столбцом NVARCHAR, всегда добавляйте префикс N. Вы можете изменить параметры сортировки базы данных, но рекомендуется всегда использовать правильный тип данных независимо от параметров сортировки, чтобы у вас не возникало проблем при использовании кодирования в разных базах данных.

Если бы вы могли объяснить причину, по которой вы хотите опустить префикс N, мы могли бы это исправить, хотя я полагаю, что в данном конкретном случае обходных путей нет.

1 голос
/ 02 апреля 2019

По умолчанию для .Net используется Юникод, поэтому вам не нужно его указывать. Это не относится к Sql Manager.

Если не указано, Sql будет предполагать, что вы работаете с asci в соответствии с параметрами сортировки, указанными в вашей БД.

Следовательно, при работе с Sql Server вам необходимо использовать N '

https://sqlquantumleap.com/2018/09/28/native-utf-8-support-in-sql-server-2019-savior-false-prophet-or-both/

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...