Строковый литерал префикса TSQL при вставке - любое значение для этого или избыточное - PullRequest
11 голосов
/ 28 мая 2010

Я только что унаследовал проект с кодом, подобным следующему (довольно простому) примеру:

DECLARE @Demo TABLE
(
    Quantity INT,
    Symbol NVARCHAR(10)
)

INSERT INTO @Demo (Quantity, Symbol)
SELECT 127, N'IBM'

Меня интересует N перед строковым литералом.

Я понимаю, что префикс N предназначен для указания кодировки (в данном случае Unicode). Но так как выбор только для вставки в поле, которое, очевидно, уже является Unicode, не будет ли это значение автоматически повышаться?

Я запустил код без N, и он, кажется, работает, но я что-то упустил, что задумал предыдущий программист? Или N был оплошностью с его / ее стороны?

Я ожидаю, что поведение будет похоже на то, когда я передаю int в поле decimal (автоматическое обновление). Можно ли избавиться от этих N с?

Ответы [ 2 ]

10 голосов
/ 28 мая 2010

Ваш тест недействителен, попробуйте что-то вроде китайского иероглифа, я помню, если вы не добавите префикс, он не вставит правильный символ

пример, первый показывает знак вопроса, а нижний показывает квадрат

select '作'

select N'作'

Лучший пример, даже здесь вывод не тот же

declare @v nvarchar(50), @v2 nvarchar(50)

select @v = '作', @v2 = N'作'

select @v,@v2

Так как вы выглядите как биржевая таблица, почему вы используете юникод, есть ли даже символы, которые являются юникодом? Я никогда не видел их, включая ISIN, CUSIPS и SEDOLS

4 голосов
/ 28 мая 2010

Да, SQL Server автоматически преобразует (расширяет, преобразует) varchar в nvarchar, поэтому в этом случае вы можете удалить N. Конечно, если вы указываете строковый литерал, где символы на самом деле отсутствуют в сопоставлении по умолчанию для базы данных, тогда вам это нужно.

Как будто вы можете добавить суффикс числа к «L» в C et al, чтобы указать, что это длинный литерал вместо целого. Написание 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'

и, следовательно, индекс purchase_reference не использовался.

И наоборот, все в порядке: если purchase_reference был nvarchar и приложение передавало параметр varchar, то переписанный запрос:

select * from purchase where purchase_reference = CONVERT(NVARCHAR, 'AB1234')

было бы хорошо. В конце концов нам пришлось отключить параметры привязки как Unicode, что вызвало массу проблем с i18n, которые считались менее серьезными.

...