我目前正在使用带有 SQL_Latin1_General_CP1_CI_AI 排序规则的 SQL Server 2016。正如预期的那样,由于排序规则的重音不敏感选项,带有字母 e 的查询将匹配带有字母 e、è、é、ê、ë 等的值。但是,带有“(U+0027)”的查询与包含“(U+2019)”的值不匹配。我想知道这种情况匹配的地方是否存在这样的排序规则,因为输入 ' 比知道 ' 是击键 Alt-0146 更容易。
我有信心说不。这里最主要的是两个角色不同(尽管相似)。对于重音符号,e 和 ê 仍然都是 e(只有一个有重音符号)。这使您(例如)能够搜索诸如
SELECT * FROM Games WHERE [Name] LIKE 'Pokémon%';
之类的内容,并且仍然有包含 Pokemon
的行返回(因为人们没有使用重音)。
我建议的最好的办法是使用
REPLACE
(至少在你的 WHERE
子句中)以便返回两行。然而,这可能会变得昂贵。
如果您知道哪些列将成为问题,您可以向该表添加计算列并对其进行适当的索引。然后您可以在
WHERE
子句中使用该列,但显示原始列。比如:
USE Sandbox;
--Create dbo.Sample table and data
CREATE TABLE dbo.Sample (String varchar(500));
INSERT INTO dbo.Sample
VALUES ('This is a string that does not contain either apostrophe'),
('Where as this string, isn''t without at least one'),
('’I have one of them as well’'),
('’Well, I''m going to use both’');
GO
--First attempt (without the column)
SELECT String
FROM dbo.Sample
WHERE String LIKE '%''%'; --Only returns 2 of the rows
GO
--Create a PERSISTED Column
ALTER TABLE dbo.Sample ADD StringRplc AS REPLACE(String,'’','''');
GO
CREATE INDEX IX_Sample_StringRplc ON dbo.Sample (StringRplc) INCLUDE (String);
GO
--Second attempt
SELECT String
FROM dbo.Sample
WHERE StringRplc LIKE '%''%'; --Returns 3 rows
GO
--Clean up
DROP TABLE dbo.Sample;
GO
另一个答案是正确的。没有这样的整理。您可以通过以下内容轻松验证这一点。
DECLARE @dynSql NVARCHAR(MAX) =
'SELECT * FROM (' +
(
SELECT SUBSTRING(
(
SELECT ' UNION ALL SELECT ''' + name + ''' AS name, IIF( NCHAR(0x0027) = NCHAR(0x2019) COLLATE ' + name + ', 1,0) AS Equal'
FROM sys.fn_helpcollations()
FOR XML PATH('')
), 12, 0+ 0x7fffffff)
)
+ ') t
ORDER BY Equal, name';
PRINT @dynSql;
EXEC (@dynSql);