web-dev-qa-db-fra.com

Sensible à la casse et insensible comme dans SQLite

Dans SQLite, il est possible de changer le comportement de 'LIKE' en respectant la casse en utilisant les commandes:

PRAGMA case_sensitive_like=ON;
PRAGMA case_sensitive_like=OFF;

Toutefois, dans mon cas, je souhaiterais exécuter une requête dont une partie est sensible à la casse et une autre non. Par exemple:

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

Est-ce possible?

33
Richard Williams

Vous pouvez utiliser le mot clé UPPER sur votre champ non sensible à la casse, puis votre déclaration de type majuscule. par exemple.

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

Utilisez des comparaisons en clair, qui sont sensibles à la casse par défaut (à moins que vous n'ayez déclaré la colonne COLLATE NOCASE):

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

Cela ne fonctionne que si la variable LIKE d'origine recherche un préfixe, mais permet d'utiliser un index.

4
CL.

Je sais que c'est une vieille question, mais si vous codez en Java et avez ce problème, cela pourrait être utile. Vous pouvez enregistrer une fonction qui gère la même vérification. J'ai eu l'astuce de cet article: https://stackoverflow.com/a/29831950/1271573

La solution dépend de sqlite jdbc: https://mvnrepository.com/artifact/org.xerial/sqlite-jdbc

Dans mon cas, je n'avais besoin que de voir si une certaine chaîne faisait partie d'une autre chaîne (comme '% mystring%'), alors j'ai créé une fonction Contains, mais il devrait être possible de l'étendre pour faire une vérification plus semblable à SQL. en utilisant regex ou quelque chose.

Pour utiliser la fonction dans SQL pour voir si MyCol contient "searchstring", vous feriez:

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

Voici ma fonction contient:

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

Pour utiliser cette fonction, vous devez d'abord l'enregistrer. Lorsque vous avez fini de l'utiliser, vous pouvez éventuellement le détruire. Voici comment:

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());
}
1
Jarle Jacobsen

Pour effectuer des requêtes sensibles à la casse sur une colonne créée avec COLLATE NOCASE, utilisez COLLATE BINARY:

select * from myTable where name like 'Test%' COLLATE BINARY;
1
live-love