在我的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选择/更新该行?
答案 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');
仅使用波兰字符更新UNICODE VALE:
SELECT #Names.Name
, #Names.Mail
FROM #Names;
显示结果:
UPDATE #Names
SET Mail = 'osiol2@test.local'
WHERE Name = N'Osioł';
SELECT #Names.Name
, #Names.Mail
FROM #Names
WHERE Name = N'Osioł';
如您所见,没有SELECT #Names.Name
, #Names.Mail
FROM #Names
WHERE Name = 'Osioł';
,服务器会查找N
值,而不是unicode VARCHAR