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


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

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 字段(自动向上)。我可以摆脱那些 NS'


5227
2018-05-27 20:38


起源



答案:


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

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

select '作'

select N'作'

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

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

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

select @v,@v2

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


9
2018-05-27 20:43



我创造的桌子是纯粹的小说。我刚刚想到了第一个概念的例子(我的论文潜入了我的工作生活!)。我还没有看到Unicode中的安全符号。关于外国人物,你提出了一个很好的观点。我试图从Joel研究这个问题时碰到了类似的东西 - > joelonsoftware.com/articles/Unicode.html - SethO
出于某种原因,当我尝试使用这些SELECT语句时,SQL API的Python API只返回反斜杠。 - Max Candocia


答案:


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

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

select '作'

select N'作'

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

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

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

select @v,@v2

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


9
2018-05-27 20:43



我创造的桌子是纯粹的小说。我刚刚想到了第一个概念的例子(我的论文潜入了我的工作生活!)。我还没有看到Unicode中的安全符号。关于外国人物,你提出了一个很好的观点。我试图从Joel研究这个问题时碰到了类似的东西 - > joelonsoftware.com/articles/Unicode.html - SethO
出于某种原因,当我尝试使用这些SELECT语句时,SQL API的Python API只返回反斜杠。 - Max Candocia


是的,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问题被认为不太严重。


3
2018-05-27 20:53



我的同事已经讲过使用Unicode的应用程序和没有使用Unicode的数据库之间的类似故事。感谢您的示例和解释。 - SethO