我刚刚继承了一个代码类似于以下(相当简单)示例的项目:
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
吗?
答案 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问题被认为不太严重。