了解SQL Server密钥和比较

时间:2016-10-11 16:41:32

标签: sql sql-server

在我的SQL Server 2014中,我有一个表.CSV / varchar(测试两者,结果是相同的!)列是主键。实际上,列值必须是唯一的,并且用于大约50%的选择,因此将其作为PK似乎是有意义的。该列现在设置为排序规则nvarchar,该列应为Latin1_General_AS,不确定排序规则是否是此处的问题。

在该varchar列中,我插入一个具有特殊字符的值,在本例中为Polish(?)<database default>(但我想支持将来在LDAP CN名称中允许的所有字符):< / p>

Osioł

当我现在尝试更新该值时:

INSERT INTO Names (Name, Mail) VALUE('Osioł', 'osiol@test.local');

它返回零更改的行。对我来说,到目前为止意味着密钥尚未使用,并且我能够插入。我随后尝试了,并且错误

  

违反PRIMARY KEY约束'PK_Names'。无法在对象'dbo.Names'中插入重复键。重复键值为Osioł。

选择同样如此:

UPDATE Names SET Mail='osiol2@test.local' WHERE Name='Osioł';

不会返回该行。

如何使用带有特殊字符的PK选择/更新该行?

2 个答案:

答案 0 :(得分:2)

您需要明确声明您的字符串文字是nvarchar。注意字符串开头的N.

UPDATE Names SET Mail='osiol2@test.local' WHERE Name=N'Osioł';

答案 1 :(得分:2)

除了Sean Lange的回答,您的插入也应该是:

require

因为INSERT INTO Names (Name, Mail) VALUES(N'Osioł', 'osiol@test.local'); 将其指定为Unicode字符。

然后这将有效:

N

如果您使用的是选择,则必须是:

UPDATE #Names
  SET  Mail = 'osiol2@test.local'
WHERE  Name = N'Osioł';

下面应该解释发生了什么:

示例数据:

SELECT #Names.Name
    , #Names.Mail
FROM   #Names
WHERE  Name = N'Osioł';

在表格中显示插入的值:

IF OBJECT_ID('tempdb..#Names') IS NOT NULL
    BEGIN
       DROP TABLE #Names;
    END;

CREATE TABLE #Names(Name NVARCHAR(50)
               , Mail NVARCHAR(50));

INSERT INTO       #Names(Name
                   , Mail)
VALUES
      (N'Osioł'
     , 'osiol@test.local');


INSERT INTO       #Names(Name
                   , Mail)
VALUES
      ('Osioł'
     , 'osiol@test.local');

enter image description here

仅使用波兰字符更新UNICODE VALE:

SELECT #Names.Name 
    , #Names.Mail
FROM   #Names;

显示结果:

UPDATE #Names
  SET  Mail = 'osiol2@test.local'
WHERE  Name = N'Osioł';

enter image description here

SELECT #Names.Name
    , #Names.Mail
FROM   #Names
WHERE  Name = N'Osioł';

enter image description here

如您所见,没有SELECT #Names.Name , #Names.Mail FROM #Names WHERE Name = 'Osioł'; ,服务器会查找N值,而不是unicode VARCHAR