TSQL Prefixing String Literal on Insert - любое значение для этого или избыточное?
Я просто унаследовал проект, который имеет код, похожий на следующий (довольно простой) пример:
DECLARE @Demo TABLE
(
Quantity INT,
Symbol NVARCHAR(10)
)
INSERT INTO @Demo (Quantity, Symbol)
SELECT 127, N'IBM'
Мой интерес к N
перед строковым литералом.
Я понимаю, что префикс N
должен указывать кодировку (в данном случае Unicode). Но так как выбор только для того, чтобы вставить в поле, которое явно уже Юникод, не будет ли это значение автоматически повышаться?
Я запустил код без N
и, похоже, работает, но не хватает ли чего-то, что предполагал предыдущий программист? Или был N
надзор над его/ее частью?
Я ожидаю поведение, подобное тому, когда я передаю поле int
в decimal
(auto-upcast). Могу ли я избавиться от этих N
s?
Ответы
Ответ 1
Ваш тест на самом деле недействителен, попробуйте что-то вроде китайского символа вместо этого, я помню, если вы его не префикс, он не будет вставлять правильный символ
Например, первый показывает знак вопроса, а нижний показывает квадрат
select '作'
select N'作'
Лучший пример, даже здесь вывод не тот же
declare @v nvarchar(50), @v2 nvarchar(50)
select @v = '作', @v2 = N'作'
select @v,@v2
Так как вы выглядите как таблица акций, почему вы используете unicode, есть даже символы, которые являются unicode. Я никогда не видел их, и это включает в себя ISIN, CUSIPS и SEDOLS
Ответ 2
Да, SQL Server автоматически преобразует (расширяет, отменяет) varchar в nvarchar, поэтому вы можете удалить N в этом случае. Конечно, если вы указываете строковый литерал, где символы фактически не присутствуют в настройке по умолчанию для базы данных, вам это нужно.
Это похоже на то, что вы можете суффикс числа с "L" в C и др., чтобы указать его длинный литерал вместо int. Написание N'IBM 'является точной или подчиненной привычкой, в зависимости от вашей точки зрения.
Одна ловушка для неосторожного: nvarchar не автоматически преобразуется в varchar, и это может быть проблемой, если ваше приложение все Unicode, а ваша база данных не является. Например, у нас это было с jTDS JDBC-драйвером, который привязывал все значения параметров как nvarchar, что приводило к таким действиям, как:
select * from purchase where purchase_reference = N'AB1234'
(где purchase_reference - столбец varchar)
Так как автоматические преобразования являются только одним способом, это стало:
select * from purchase where CONVERT(NVARCHAR, purchase_reference) = N'AB1234'
и, следовательно, индекс buy_reference не использовался.
В противоположность этому, обратное хорошо: если purchase_reference был nvarchar, а приложение передано в параметре varchar, тогда перезаписанный запрос:
select * from purchase where purchase_reference = CONVERT(NVARCHAR, 'AB1234')
будет хорошо. В конце концов, нам пришлось отключить параметры привязки как Unicode, что вызвало множество проблем i18n, которые считались менее серьезными.