我已经看到并阅读了几个类似的问题,但我仍然没有找到我的问题的答案。我已经阅读了 MS 的各种文档,但无济于事。
有没有一种方法可以在 SQL Server 中执行区分重音、区分大小写、“填充敏感”(注意尾随空格)查询,而无需调整两个操作数? 以下脚本来自
db<>fiddle:
create table users (
id int,
name varchar(255)
);
insert into users (id, name)
values
(1, 'bar'),
(2, 'bar ');
2 rows affected
在这里我希望只找到记录#2,它找到了两个:填充不敏感。
select * from users where name = 'bar ';
名字 | |
---|---|
酒吧 | |
酒吧 |
select * from users where name = 'BAR';
名字 | |
---|---|
酒吧 | |
酒吧 |
select * from users where name = 'bàz';
名字 |
---|
_BIN2
似乎没有什么区别,尽管(我的理解)文档所说的(并且指定“Latin 1”感觉令人不安:我不想将我的限制限制为唯一的 ISO-8859-1片段,我想要完整的 UTF-8 覆盖)。应该什么也找不到!
select * from users
where (name collate Latin1_General_BIN2) in ('bàr', 'BAR', 'bar ');
名字 | |
---|---|
酒吧 | |
酒吧 |
select * from users
where (name collate Latin1_General_CS_AS) in
('bàr' collate Latin1_General_CS_AS,
'BAR' collate Latin1_General_CS_AS,
'bar ' collate Latin1_General_CS_AS);
名字 | |
---|---|
酒吧 | |
酒吧 |
select * from users where cast(name as binary) = 'bar';
名字 |
---|
select * from users where cast(name as binary) = cast('bar' as binary);
名字 | |
---|---|
酒吧 |
in
。但话又说回来,我想避免这种情况。
select * from users
where cast(name as binary) in
(cast('bàr' as binary),
cast('BAR' as binary),
cast('bar ' as binary));
名字 |
---|
binary name = 'bar'
。
提前致谢!
(var)binary
。由于
name
是 varchar(255)
我将在这里使用 varbinary(255)
。然后您可以 INDEX
该列,以便您可以进行适当的查询。但是,您仍然需要 CONVERT
您的输入值。因此,您最好使用参数,因为这样您就可以明确数据类型,因此不会最终有人传递 varchar
并导致 implicit_convert
。 Thuis 给出了一些 DDL 和 DML,如下所示:CREATE TABLE dbo.users (id int CONSTRAINT PK_users PRIMARY KEY CLUSTERED,
name varchar(255));
INSERT INTO dbo.users (id,
name)
VALUES (1, 'bar'),
(2, 'bar ');
GO
ALTER TABLE dbo.users ADD BinaryName AS CONVERT(varbinary(255),name);
GO
CREATE INDEX IX_users_BinaryName ON dbo.users (BinaryName) INCDUDE (name);
GO
那么对单个值的查询可能如下所示:
DECLARE @name varbinary(255) = CONVERT(varbinary(255),'bàr'); --Implicit conversion isn't allowed
SELECT u.id,
u.name
FROM dbo.users u
WHERE BinaryName = @name;
如果您需要多个值,那么最好使用表类型变量/参数和类似的东西:
DECLARE @Names table (name varbinary(255));
INSERT INTO @Names (name)
SELECT CONVERT(varbinary(255),v.name)
FROM (VALUES('bàr'),('BAR'),('bar '))V(name);
SELECT u.id,
u.name,
u.BinaryName
FROM dbo.users u
WHERE EXISTS (SELECT 1
FROM @Names n
WHERE n.name = u.BinaryName);