2013-02-19 18 views
64

W numerze documentation about the LIKE operator nic nie jest informowane o rozróżnianiu wielkości liter. Czy to jest? Jak włączyć/wyłączyć to?Czy operator LIKE rozróżnia wielkość liter w serwerze MSSQL?

Pytam o kolumny varchar(n), w przypadku instalacji programu Microsoft SQL Server 2005, jeśli to ma znaczenie.

+9

To zależy od pęczka kolumnie (lub bazy danych). Jeśli jest rozróżniana wielkość liter, to "LIKE" rozróżnia małe i wielkie litery, a następnie "LIKE" nie jest – Lamak

+0

Sprawdź dokumentację dotyczącą kolejek SQL-Server http://msdn.microsoft.com/en-us/library/ms144250 % 28v = sql.105% 29.aspx – GarethD

+0

Jaki jest twój cel? Czy chcesz, aby wielkość liter była rozróżniana, czy nie jest rozróżniana wielkość liter? –

Odpowiedz

69

Wielkość liter nie zależy od operatora, jest to kolumna.

Po przeprowadzeniu instalacji programu SQL Server do instancji zostanie wybrane sortowanie domyślne. O ile wyraźnie nie zaznaczono inaczej (sprawdź poniższą komendę collate), gdy tworzona jest nowa baza danych, dziedziczy ona sortowanie od instancji, a po utworzeniu nowej kolumny dziedziczy sortowanie z bazy danych, do której należy.

Zestawienie takie jak sql_latin1_general_cp1_ci_as określa sposób traktowania zawartości kolumny. CI oznacza niewrażliwe na wielkość liter, a AS oznacza wrażliwy akcent.

Pełną listę sortowania jest dostępna w https://msdn.microsoft.com/en-us/library/ms144250(v=sql.105).aspx

(a) Aby sprawdzić instancji sortowania

select serverproperty('collation') 

(b) Aby sprawdzić sortowania bazy

select databasepropertyex('databasename', 'collation') sqlcollation 

(c) Aby utworzyć bazę danych ing inny sortowania

create database exampledatabase 
collate sql_latin1_general_cp1_cs_as 

(d) w celu utworzenia kolumny stosując inny sortowania

create table exampletable (
    examplecolumn varchar(10) collate sql_latin1_general_cp1_ci_as null 
) 

(e), aby zmodyfikować pęczek Kolumna

alter table exampletable 
alter column examplecolumn varchar(10) collate sql_latin1_general_cp1_ci_as null 

ramę można zmienić instancję i sortowanie bazy danych, ale nie ma to wpływu na wcześniejsze tworzenie d obiektów.

Istnieje również możliwość zmiany sortowania kolumn w locie w celu porównania ciągów, ale jest to wysoce niezalecane w środowisku produkcyjnym, ponieważ jest niezwykle kosztowne.

select 
    column1 collate sql_latin1_general_cp1_ci_as as column1 
from table1 
+2

Wygląda na to, że zakres znaków takich jak "[A-Z]" zawsze jest niewrażliwy na wielkość znaków. "[ABCDEFGHIJKLMNOPQRSŠTUVWXYZŽÅĘÖ]" wydaje się jednak być posłusznym zestawianiu. – jumxozizi

+1

Możesz również zapytać o wielkość liter w konkretnej kolumnie z czymś podobnym: 'wybierz COLLATION_NAME, iif (cast (COLLATIONPROPERTY (COLLATION_NAME," ComparisonStyle ") jako int) i 1 = 0," wielkość liter "," wielkość liter nie ma znaczenia ') z INFORMATION_SCHEMA.COLUMNS gdzie TABLE_NAME =' exampletable 'i COLUMN_NAME =' examplecolumn'' –

2

spróbuj uruchomić,

SELECT SERVERPROPERTY('COLLATION') 

Następnie dowiedzieć się, czy sortowania jest wielkość liter, czy nie.

13

Masz możliwość zdefiniowania porządku sortowania w momencie definiowania swojej tabeli. Jeśli zdefiniujesz rozróżnianie wielkości liter, operator LIKE będzie zachowywał się w sposób uwzględniający wielkość liter; jeśli zdefiniować bez uwzględniania wielkości liter sortowania kolejności operator LIKE będzie ignorować wielkość liter, a także:

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 
); 

Oto quick demo on sqlfiddle przedstawiający wyniki kolejności zestawiania w wyszukiwaniach z LIKE.

8

Jeśli chcesz osiągnąć wrażliwe przypadek wyszukiwanie bez zmiany sortowania kolumny/database/serwer, zawsze można użyć klauzuli COLLATE, np

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; 

Działa również w drugą stronę, jeśli w kolumnie/bazie danych/serwerze jest rozróżniana wielkość liter i nie ma potrzeby uwzględniania rozróżniania wielkości liter, np.

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; 
+0

Strzeż się w ostatnim zapytaniu, jeśli użyjesz 'WHERE bar COLLATE Latin1_General_CS_AS LIKE '[jk]%'' to zwróci 'John' jak w ta wartość "J" w zestawieniu jest między małymi literami "j" i małymi literami "k". To jest jak "aAbBcC ... jJkKlLmM ...", co nie jest oczywiste. Wygląda na to, że 'Latin1_General_BIN' jest bardziej przewidywalny w przypadku wyszukiwania zakresów w/LIKE operator. – wqw

3

Operator like przyjmuje dwa ciągi. Łańcuchy te muszą mieć kompatybilne sortowanie, co wyjaśniono here.

Moim zdaniem sprawy stają się coraz bardziej skomplikowane. Następująca kwerenda zwraca błąd mówiąc, że sortowania są niezgodne:

select * 
from INFORMATION_SCHEMA.TABLES 
where 'abc' COLLATE SQL_Latin1_General_CP1_CI_AS like 'ABC' COLLATE SQL_Latin1_General_CP1_CS_AS 

na losowej maszynie tutaj, domyślnie sortowania jest SQL_Latin1_General_CP1_CI_AS. Następująca kwerenda jest udane, ale nie zwraca żadnych wierszy:

select * 
from INFORMATION_SCHEMA.TABLES 
where 'abc' like 'ABC' COLLATE SQL_Latin1_General_CP1_CS_AS 

Wartości „abc” i „ABC” nie pasują w przypadku wrażliwej świata.

Innymi słowy, istnieje różnica między brakiem sortowania i domyślnym sortowaniem. Gdy jedna strona nie ma sortowania, to "przypisuje" jawne zestawienie z drugiej strony.

(Wyniki są takie same, gdy jawne sortowania jest po lewej stronie).

+0

Czy można odtworzyć błąd w tabeli, która NIE jest obiektem systemowym, takim jak INFORMATION_SCHEMA.TABLES? –

+0

@AaronBertrand. . . Tak, mogę. Czy baza danych jest uszkodzona;)? –

+0

Nie wiem, jestem teraz na urządzeniu mobilnym i nie mogę obrócić maszyny wirtualnej Windows. Po prostu nie wiem, czy twój pełny opis jest poprawny technicznie. –

12

Całe to gadanie o zestawień wydawać się nieco zbyt skomplikowane. Dlaczego nie wystarczy użyć coś takiego:

IF UPPER(@@VERSION) NOT LIKE '%AZURE%' 

Następnie czek nie uwzględnia wielkości liter, niezależnie od sortowania

+6

Ponieważ nie jest to sargable. Twój przykład używa zmiennej i wiodącego symbolu wieloznacznego. Ale w stosunku do kolumny indeksowanej z rozróżnianiem wielkości liter "jak" a% "może używać indeksu, a" górna "wersja nie może. –

+1

Pytanie dotyczyło tego, czy operator "jak" rozróżnia wielkość liter. – jumxozizi

Powiązane problemy