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 .
UPPERlub wielkość LOWERliter, a następnie używając LIKEdo 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_ASw 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 zVARCHARdata, 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 COLLATEklauzuli. 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 COLLATEpo prostu kieruje przetwarzanie do generowania kluczy sortowania przy użyciu innego zestawu reguł niż domyślnie. Używanie COLLATEjest 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ą COLLATEklauzuli (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 WHEREklauzuli. 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:
_BIN2jeś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ą, NVARCHARto nie ma znaczenia, którego języka używasz, ponieważ w tym przypadku wszystkie są takie same, dlatego Latin1_General_100_BIN2zawsze działają. Jeśli dane VARCHAR, należy użyć tego samego ustawienia regionalne, że dane są obecnie (np Latin1_General, French, Japanese_XJISitp), 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, LIKEnie 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ą COLLATEklauzuli opcjonalnej .
LCASEnie 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 COLLATEklauzula 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 COLLATEklauzula 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ć _CSsię _CI. Tak Latin1_General_100_CS_ASsię stanie Latin1_General_100_CI_AS.
Jeśli kolumna używa sortowania binarnego (kończącego się na _BINlub _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 LIKEnie zadziała. LIKEwyszukuje wartości pasujące dokładnie do podanego wzorca. W tym przypadku LIKEzostanie 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.
WHEREoświadczenia i wpłynie to na wszystkieWHEREklauzule, prawda?