插入时的TSQL前缀字符串文字 - 对此有任何价值,还是冗余?

时间:2010-05-27 20:38:47

标签: tsql unicode casting

我刚刚继承了一个代码类似于以下(相当简单)示例的项目:

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

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

我感兴趣的是字符串文字之前的N

我知道前缀N用于指定编码(在本例中为Unicode)。但由于select仅用于插入显然已经是Unicode的字段,因此该值不会自动向上转换吗?

我在没有N的情况下运行代码,它似乎有用,但是我错过了以前程序员的意图吗?或者N是他/她的疏忽吗?

我希望行为与我将int传递给decimal字段时的行为类似(自动向上播放)。我可以摆脱那些N吗?

2 个答案:

答案 0 :(得分:10)

你的测试不是真的有效,尝试类似中文字符的东西,我记得如果你不加前缀它就不会插入正确的字符

例如,第一个显示问号而底部显示方形

select '作'

select N'作'

一个更好的例子,即使在这里输出也不一样

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

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

select @v,@v2

因为你看起来像股票表你为什么使用unicode,甚至有unicode的符号..我从来没有见过任何这包括ISIN,CUSIPS和SEDOLS

答案 1 :(得分:4)

是的,SQL Server会自动将(扩展,转换)varchar转换为nvarchar,因此在这种情况下可以删除N.当然,如果您要指定字符串文字,其中字符实际上不存在于数据库的默认排序规则中,那么您需要它。

就像你可以在C等中用“L”后缀一个数字来表示它是一个长文字而不是一个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'

因此未使用purchase_reference的索引。

相比之下,反之亦然:如果purchase_reference是nvarchar,并且应用程序在varchar参数中传递,那么重写的查询:

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

没关系。最后,我们必须禁用绑定参数作为Unicode,因此导致大量的i18n问题被认为不太严重。