Jak skonstruować zapytanie SQL (MS SQL Server), w którym w klauzuli „where” nie jest rozróżniana wielkość liter?
SELECT * FROM myTable WHERE myField = 'sOmeVal'
Chcę, aby wyniki wróciły, ignorując sprawę
Jak skonstruować zapytanie SQL (MS SQL Server), w którym w klauzuli „where” nie jest rozróżniana wielkość liter?
SELECT * FROM myTable WHERE myField = 'sOmeVal'
Chcę, aby wyniki wróciły, ignorując sprawę
Odpowiedzi:
W domyślnej konfiguracji bazy danych SQL Server w porównaniach ciągów nie jest rozróżniana wielkość liter. Jeśli Twoja baza danych zastępuje to ustawienie (poprzez użycie alternatywnego sortowania), musisz określić, jakiego rodzaju sortowania użyć w zapytaniu.
SELECT * FROM myTable WHERE myField = 'sOmeVal' COLLATE SQL_Latin1_General_CP1_CI_AS
Zwróć uwagę, że zestawienie, które podałem, to tylko przykład (chociaż najprawdopodobniej będzie działać dobrze dla Ciebie). Bardziej szczegółowy opis sortowania SQL Server można znaleźć tutaj .
UPPER
lub wielkość LOWER
liter, a następnie używając LIKE
do wyszukiwania?
Zazwyczaj porównania ciągów nie uwzględniają wielkości liter. Jeśli twoja baza danych jest skonfigurowana do sortowania z rozróżnianiem wielkości liter, musisz wymusić użycie tej bez rozróżniania wielkości liter:
SELECT balance FROM people WHERE email = 'billg@microsoft.com'
COLLATE SQL_Latin1_General_CP1_CI_AS
Znalazłem inne rozwiązanie gdzie indziej; to znaczy do użycia
upper(@yourString)
ale wszyscy tutaj mówią, że w SQL Server to nie ma znaczenia, ponieważ i tak ignoruje wielkość liter? Jestem prawie pewien, że w naszej bazie danych rozróżniana jest wielkość liter.
Dwie najważniejsze odpowiedzi (od Adama Robinsona i Andrejsa Cainikovsa ) są w pewnym sensie poprawne, ponieważ technicznie działają, ale ich wyjaśnienia są błędne i mogą być w wielu przypadkach mylące. Na przykład, chociaż SQL_Latin1_General_CP1_CI_AS
w wielu przypadkach sortowanie zadziała, nie należy zakładać, że jest to właściwe sortowanie bez rozróżniania wielkości liter. W rzeczywistości, biorąc pod uwagę, że OP działa w bazie danych z rozróżnianiem wielkości liter (lub prawdopodobnie binarnych), wiemy, że OP nie używa sortowania, które jest domyślne dla tak wielu instalacji (szczególnie tych zainstalowanych w systemie operacyjnym za pomocą amerykańskiego angielskiego jako języka) SQL_Latin1_General_CP1_CI_AS
. Jasne, OP może być używany SQL_Latin1_General_CP1_CS_AS
, ale podczas pracy zVARCHAR
data, ważne jest, aby nie zmieniać strony kodowej, ponieważ może to prowadzić do utraty danych, a to jest kontrolowane przez ustawienia regionalne / kulturę zestawiania (tj. Latin1_General vs francuski vs hebrajski itp.). Zobacz punkt # 9 poniżej.
Pozostałe cztery odpowiedzi są w różnym stopniu błędne.
Wyjaśnię tutaj wszystkie nieporozumienia, aby czytelnicy mogli, miejmy nadzieję, dokonać najbardziej odpowiednich / skutecznych wyborów.
Nie używaj UPPER()
. To zupełnie niepotrzebna dodatkowa praca. Użyj COLLATE
klauzuli. W obu przypadkach należy wykonać porównanie ciągów, ale za pomocą należy UPPER()
również sprawdzić, znak po znaku, czy występuje odwzorowanie na duże litery, a następnie je zmienić. I musisz to zrobić po obu stronach. Dodawanie COLLATE
po prostu kieruje przetwarzanie do generowania kluczy sortowania przy użyciu innego zestawu reguł niż domyślnie. Używanie COLLATE
jest zdecydowanie bardziej wydajne (lub "wydajne", jeśli lubisz to słowo :) niż używanie UPPER()
, jak udowodniono w tym skrypcie testowym (na PasteBin) .
Jest też kwestia odnotowana przez @Ceisc w odpowiedzi @ Danny'ego:
W niektórych językach konwersje nie odbywają się w obie strony. tj. LOWER (x)! = LOWER (UPPER (x)).
Typowym przykładem jest turecka wielka litera „İ”.
Nie, sortowanie nie jest ustawieniem obejmującym całą bazę danych, a przynajmniej nie w tym kontekście. Istnieje domyślne sortowanie na poziomie bazy danych i jest używane jako domyślne dla zmienionych i nowo utworzonych kolumn, które nie określają COLLATE
klauzuli (co jest prawdopodobne, skąd pochodzi to powszechne nieporozumienie), ale nie wpływa bezpośrednio na zapytania, chyba że porównywanie literałów łańcuchowych i zmiennych z innymi literałami łańcuchowymi i zmiennymi lub odwołujesz się do metadanych na poziomie bazy danych.
Nie, sortowanie nie dotyczy zapytania.
Kolacje dotyczą predykatu (tj. Coś operandowego) lub wyrażenia, a nie zapytania. Dotyczy to całego zapytania, a nie tylko WHERE
klauzuli. Obejmuje to POŁĄCZENIA, GRUPOWANIE, ZAMÓWIENIE, PARTYCJA WEDŁUG, itp.
Nie, nie konwertuj na VARBINARY
(np. convert(varbinary, myField) = convert(varbinary, 'sOmeVal')
) Z następujących powodów:
_BIN2
jeśli używasz SQL Server 2008 lub nowszego, w przeciwnym razie nie masz innego wyboru, jak tylko użyć takiego, który kończy się na _BIN
. Jeśli dane są, NVARCHAR
to nie ma znaczenia, którego języka używasz, ponieważ w tym przypadku wszystkie są takie same, dlatego Latin1_General_100_BIN2
zawsze działają. Jeśli dane VARCHAR
, należy użyć tego samego ustawienia regionalne, że dane są obecnie (np Latin1_General
, French
, Japanese_XJIS
itp), ponieważ narodowe określa stronę kodową, która jest używana i zmianę stron kodowych może zmieniać dane (czyli utrata danych).CONVERT()
nim użyje wartości domyślnej 30. Niebezpieczeństwo polega na tym, że jeśli ciąg może mieć ponad 30 bajtów, zostanie po cichu obcięty i prawdopodobnie otrzymasz nieprawidłowe wyniki z tego predykatu.Nie, LIKE
nie zawsze jest rozróżniana wielkość liter. Używa sortowania kolumny, do której się odwołuje, lub sortowania bazy danych, jeśli zmienna jest porównywana z literałem łańcuchowym, lub sortowania określonego za pomocą COLLATE
klauzuli opcjonalnej .
LCASE
nie jest funkcją programu SQL Server. Wygląda na to, że jest to Oracle lub MySQL. A może Visual Basic?
Ponieważ kontekstem pytania jest porównanie kolumny z literałem łańcuchowym, ani sortowanie instancji (często nazywanej „serwerem”), ani sortowanie bazy danych nie mają tutaj bezpośredniego wpływu. Sortowania są przechowywane w każdej kolumnie, a każda kolumna może mieć inne sortowanie, a te sortowania nie muszą być takie same, jak domyślne sortowanie bazy danych lub sortowanie instancji. Jasne, sortowanie instancji jest domyślne dla tego, co nowo utworzona baza danych będzie używać jako domyślnego sortowania, jeśli COLLATE
klauzula nie została określona podczas tworzenia bazy danych. Podobnie, domyślne sortowanie bazy danych jest tym, czego użyje zmieniona lub nowo utworzona kolumna, jeśli COLLATE
klauzula nie zostanie określona.
Należy użyć sortowania bez rozróżniania wielkości liter, które poza tym jest takie samo jak sortowanie kolumny. Użyj następującego zapytania, aby znaleźć sortowanie kolumny (zmień nazwę tabeli i nazwę schematu):
SELECT col.*
FROM sys.columns col
WHERE col.[object_id] = OBJECT_ID(N'dbo.TableName')
AND col.[collation_name] IS NOT NULL;
Następnie wystarczy zmienić _CS
się _CI
. Tak Latin1_General_100_CS_AS
się stanie Latin1_General_100_CI_AS
.
Jeśli kolumna używa sortowania binarnego (kończącego się na _BIN
lub _BIN2
), znajdź podobne sortowanie, używając następującego zapytania:
SELECT *
FROM sys.fn_helpcollations() col
WHERE col.[name] LIKE N'{CurrentCollationMinus"_BIN"}[_]CI[_]%';
Na przykład zakładając, że kolumna używa Japanese_XJIS_100_BIN2
, wykonaj następujące czynności:
SELECT *
FROM sys.fn_helpcollations() col
WHERE col.[name] LIKE N'Japanese_XJIS_100[_]CI[_]%';
Aby uzyskać więcej informacji na temat zestawień, kodowania itp., Odwiedź: Informacje o zestawieniach
Nie, tylko używanie LIKE
nie zadziała. LIKE
wyszukuje wartości pasujące dokładnie do podanego wzorca. W tym przypadku LIKE
zostanie znaleziony tylko tekst „sOmeVal”, a nie „someval”.
Praktycznym rozwiązaniem jest użycie LCASE()
funkcji. LCASE('sOmeVal')
pobiera mały ciąg z twojego tekstu: „someval”. Jeśli użyjesz tej funkcji dla obu stron porównania, zadziała:
SELECT * FROM myTable WHERE LCASE(myField) LIKE LCASE('sOmeVal')
Instrukcja porównuje dwa ciągi napisane małymi literami, dzięki czemu „sOmeVal” będzie pasować do każdej innej notacji „someval” (np. „Someval”, „sOMEVAl” itp.).
LCASE()
w SQL Server (przynajmniej tego nie widzę). Myślę, że ta odpowiedź dotyczy zupełnie innego RDBMS. Zobacz moją odpowiedź, aby uzyskać wyjaśnienie dotyczące porównań ciągów.
Możesz wymusić rozróżnianie wielkości liter, rzutując na varbinary w ten sposób:
SELECT * FROM myTable
WHERE convert(varbinary, myField) = convert(varbinary, 'sOmeVal')
W jakiej bazie danych się znajdujesz? W przypadku MS SQL Server jest to ustawienie dotyczące całej bazy danych lub można je zastąpić słowem kluczowym COLLATE dla każdego zapytania.
WHERE
oświadczenia i wpłynie to na wszystkieWHERE
klauzule, prawda?