2013-03-18 13 views
26

W SQLite jest możliwa zmiana wrażliwą na sprawy zachowanie „LIKE” za pomocą polecenia:Case wrażliwe i niewrażliwe jak w SQLite

PRAGMA case_sensitive_like=ON; 
PRAGMA case_sensitive_like=OFF; 

Jednak w mojej sytuacji chciałbym wykonać kwerendy, część w tym przypadku rozróżniana jest wielkość liter, a część z nich nie. Na przykład:

SELECT * FROM mytable 
WHERE caseSensitiveField like 'test%' 
AND caseInsensitiveField like 'g2%' 

Czy to możliwe?

+0

http://stackoverflow.com/a/973777/1427878 – CBroe

Odpowiedz

26

Możesz użyć słowa kluczowego UPPER na polu niewrażliwym na wielkość liter, a następnie na dużej liczbie instrukcji podobnych. na przykład

SELECT * FROM mytable 
WHERE caseSensitiveField like 'test%' 
AND UPPER(caseInsensitiveField) like 'G2%' 
+11

Uwaga, to nie działa non-angielskich liter. –

+0

@AlexanderMalakhov Działa również dla postaci włoskich i niemieckich. Upewnij się tylko, że baza danych i dane zaimportowane do niej są kodowane w UTF-8 i działa. –

+6

@rbedger Uwaga, 'nie potrzebujesz funkcji Upper', ponieważ ** Like ** domyślnie nie uwzględnia wielkości liter. –

3

używać zwykłego porównania, które mają wielkość liter domyślnie (chyba, że ​​zostały uznane za kolumnę COLLATE NOCASE):

SELECT * 
FROM mytable 
WHERE caseSensitiveField >= 'test' 
    AND caseSensitiveField < 'tesu' 
    AND caseInsensitiveField LIKE 'g2%' 

ta działa tylko wtedy, gdy oryginał LIKE szuka prefiks, ale pozwala na wykorzystanie indeks.

1

Wiem, że to stare pytanie, ale jeśli programujesz w Javie i masz ten problem, może to być pomocne. Możesz zarejestrować funkcję, która obsługuje podobne sprawdzanie. Mam formularz końcówka tego posta: https://stackoverflow.com/a/29831950/1271573

Rozwiązanie i zależy od sqlite jdbc: https://mvnrepository.com/artifact/org.xerial/sqlite-jdbc

W moim przypadku wystarczyło, aby zobaczyć, czy dany ciąg istniał jako część innego łańcucha (jak „% mystring% "), dlatego stworzyłem funkcję Contains, ale powinno być możliwe rozszerzenie tego, aby uzyskać bardziej podobny do sql sprawdzanie za pomocą regex lub czegoś podobnego.

Aby korzystać z funkcji w SQL, aby zobaczyć czy Mycol zawiera „searchstring” zrobiłbyś:

select * from mytable where Contains(MyCol, 'searchstring') 

Oto mój Zawiera funkcja:

public class Contains extends Function { 

    @Override 
    protected void xFunc() throws SQLException { 
     if (args() != 2) { 
      throw new SQLException("Contains(t1,t2): Invalid argument count. Requires 2, but found " + args()); 
     } 
     String testValue = value_text(0).toLowerCase(); 
     String isLike = value_text(1).toLowerCase(); 

     if (testValue.contains(isLike)) { 
      result(1); 
     } else { 
      result(0); 
     } 
    } 
} 

Aby korzystać z tej funkcji, musisz się najpierw zarejestrować to. Kiedy skończysz z jej używaniem, możesz opcjonalnie go zniszczyć. Oto jak:

public static void registerContainsFunc(Connection con) throws SQLException { 
    Function.create(con, Contains.class.getSimpleName(), new Contains()); 
} 
public static void destroyContainsFunc(Connection con) throws SQLException { 
    Function.destroy(con, Contains.class.getSimpleName()); 
} 
+0

Znaleziono błąd w moim kodzie. Jeśli kolumna, w której korzystasz z funkcji Zawiera, ma dozwolone wartości null, powinieneś sprawdzić wartość parametru wartość_tekstu (n) dla wartości null przed zastosowaniem funkcji th toLowerCase. –