Trong tài liệu về toán tử LIKE , không có gì nói về phân biệt chữ hoa chữ thường của nó. Là nó? Làm thế nào để bật / tắt nó?
Tôi đang truy vấn varchar(n)
các cột, trên cài đặt Microsoft SQL Server 2005, nếu điều đó quan trọng.
Trong tài liệu về toán tử LIKE , không có gì nói về phân biệt chữ hoa chữ thường của nó. Là nó? Làm thế nào để bật / tắt nó?
Tôi đang truy vấn varchar(n)
các cột, trên cài đặt Microsoft SQL Server 2005, nếu điều đó quan trọng.
Câu trả lời:
Nó không phải là toán tử phân biệt chữ hoa chữ thường, nó là chính cột.
Khi cài đặt SQL Server được thực hiện, một đối chiếu mặc định được chọn cho phiên bản. Trừ khi được đề cập rõ ràng theo cách khác (kiểm tra mệnh đề đối chiếu bên dưới) khi một cơ sở dữ liệu mới được tạo, nó kế thừa đối chiếu từ phiên bản và khi một cột mới được tạo, nó kế thừa đối chiếu từ cơ sở dữ liệu mà nó thuộc về.
Một đối chiếu như sql_latin1_general_cp1_ci_as
chỉ định cách xử lý nội dung của cột. CI là viết tắt của phân biệt chữ hoa chữ thường và AS là viết tắt của phân biệt trọng âm.
Danh sách đầy đủ các ảnh ghép có sẵn tại https://msdn.microsoft.com/en-us/library/ms144250(v=sql.105).aspx
(a) Để kiểm tra đối chiếu phiên bản
select serverproperty('collation')
(b) Để kiểm tra đối chiếu cơ sở dữ liệu
select databasepropertyex('databasename', 'collation') sqlcollation
(c) Để tạo cơ sở dữ liệu bằng cách sử dụng đối chiếu khác
create database exampledatabase
collate sql_latin1_general_cp1_cs_as
(d) Để tạo một cột bằng cách sử dụng một đối chiếu khác
create table exampletable (
examplecolumn varchar(10) collate sql_latin1_general_cp1_ci_as null
)
(e) Để sửa đổi đối chiếu cột
alter table exampletable
alter column examplecolumn varchar(10) collate sql_latin1_general_cp1_ci_as null
Có thể thay đổi một thể hiện và đối chiếu cơ sở dữ liệu nhưng nó không ảnh hưởng đến các đối tượng đã tạo trước đó.
Cũng có thể thay đổi đối chiếu cột nhanh chóng để so sánh chuỗi, nhưng điều này rất không được khuyến khích trong môi trường sản xuất vì nó cực kỳ tốn kém.
select
column1 collate sql_latin1_general_cp1_ci_as as column1
from table1
[A-Z]
luôn phân biệt chữ hoa chữ thường. [ABCDEFGHIJKLMNOPQRSŠTUVWXYZŽÅÄÖ]
tuy nhiên dường như tuân theo đối chiếu.
select COLLATION_NAME, iif(cast(COLLATIONPROPERTY(COLLATION_NAME, 'ComparisonStyle') as int) & 1 = 0, 'case sensitive', 'case insensitive') from INFORMATION_SCHEMA.COLUMNS where TABLE_NAME = 'exampletable' and COLUMN_NAME = 'examplecolumn'
Tất cả những gì nói về đối chiếu có vẻ hơi phức tạp. Tại sao không chỉ sử dụng một cái gì đó như:
IF UPPER(@@VERSION) NOT LIKE '%AZURE%'
Khi đó séc của bạn không phân biệt chữ hoa chữ thường bất kể đối chiếu
like 'a%'
có thể sử dụng chỉ mục và upper
phiên bản thì không.
like
toán tử có phân biệt chữ hoa chữ thường hay không .
Latin1_General_CI_AS
, thì thực hiện UPPER(@@VALUE) NOT LIKE '%SOMETHING%'
hoặc @@COLUMN NOT LIKE '%SOMETHING%'
không liên quan: kết quả sẽ giống nhau.
Bạn có một tùy chọn để xác định thứ tự đối chiếu tại thời điểm xác định bảng của mình. Nếu bạn xác định một thứ tự phân biệt chữ hoa chữ thường, thì LIKE
nhà điều hành của bạn sẽ hành xử theo cách phân biệt chữ hoa chữ thường; nếu bạn xác định một thứ tự đối chiếu không phân biệt chữ hoa chữ thường, LIKE
toán tử cũng sẽ bỏ qua chữ hoa chữ thường :
CREATE TABLE Test (
CI_Str VARCHAR(15) COLLATE Latin1_General_CI_AS -- Case-insensitive
, CS_Str VARCHAR(15) COLLATE Latin1_General_CS_AS -- Case-sensitive
);
Đây là bản demo nhanh trên sqlfiddle hiển thị kết quả của thứ tự đối chiếu trên các tìm kiếm với LIKE
.
Nếu bạn muốn thực hiện tìm kiếm phân biệt chữ hoa chữ thường mà không thay đổi đối chiếu của cột / cơ sở dữ liệu / máy chủ, bạn luôn có thể sử dụng COLLATE
mệnh đề, ví dụ:
USE tempdb;
GO
CREATE TABLE dbo.foo(bar VARCHAR(32) COLLATE Latin1_General_CS_AS);
GO
INSERT dbo.foo VALUES('John'),('john');
GO
SELECT bar FROM dbo.foo
WHERE bar LIKE 'j%';
-- 1 row
SELECT bar FROM dbo.foo
WHERE bar COLLATE Latin1_General_CI_AS LIKE 'j%';
-- 2 rows
GO
DROP TABLE dbo.foo;
Cũng hoạt động theo cách khác, nếu cột / cơ sở dữ liệu / máy chủ của bạn phân biệt chữ hoa chữ thường và bạn không muốn tìm kiếm phân biệt chữ hoa chữ thường, ví dụ:
USE tempdb;
GO
CREATE TABLE dbo.foo(bar VARCHAR(32) COLLATE Latin1_General_CI_AS);
GO
INSERT dbo.foo VALUES('John'),('john');
GO
SELECT bar FROM dbo.foo
WHERE bar LIKE 'j%';
-- 2 rows
SELECT bar FROM dbo.foo
WHERE bar COLLATE Latin1_General_CS_AS LIKE 'j%';
-- 1 row
GO
DROP TABLE dbo.foo;
WHERE bar COLLATE Latin1_General_CS_AS LIKE '[j-k]%'
nó sẽ trả về John
vì trong đối chiếu này vốn đối chiếu J
nằm giữa chữ thường j
và chữ thường k
. Nó giống như aAbBcC...jJkKlLmM...
điều không rõ ràng. Nó có vẻ Latin1_General_BIN
dễ đoán hơn với các tìm kiếm phạm vi với toán tử LIKE.
Các like
nhà điều hành phải mất hai chuỗi. Các chuỗi này phải có các đối chiếu tương thích, điều này được giải thích ở đây .
Theo tôi, mọi thứ sau đó trở nên phức tạp. Truy vấn sau trả về lỗi cho biết rằng các đối chiếu không tương thích:
select *
from INFORMATION_SCHEMA.TABLES
where 'abc' COLLATE SQL_Latin1_General_CP1_CI_AS like 'ABC' COLLATE SQL_Latin1_General_CP1_CS_AS
Trên một máy ngẫu nhiên ở đây, đối chiếu mặc định là SQL_Latin1_General_CP1_CI_AS
. Truy vấn sau thành công, nhưng không trả về hàng nào:
select *
from INFORMATION_SCHEMA.TABLES
where 'abc' like 'ABC' COLLATE SQL_Latin1_General_CP1_CS_AS
Các giá trị "abc" và "ABC" không khớp trong thế giới phân biệt chữ hoa chữ thường.
Nói cách khác, có sự khác biệt giữa không có đối chiếu và sử dụng đối chiếu mặc định. Khi một bên không có đối chiếu, thì nó được "gán" một đối chiếu rõ ràng từ phía bên kia.
(Kết quả giống nhau khi đối chiếu rõ ràng ở bên trái.)
Hãy thử chạy,
SELECT SERVERPROPERTY('COLLATION')
Sau đó, tìm hiểu xem đối chiếu của bạn có phân biệt chữ hoa chữ thường hay không.
Bạn có thể dễ dàng thay đổi đối chiếu trong Microsoft SQL Server Management studio.
LIKE
là trường hợp nhạy cảm, nếu nó không phải, sau đóLIKE
không