Case sensitive and insensitive like in SQLite

SqliteCase Sensitive

Sqlite Problem Overview


In SQLite it is possible to change the case sensitive behaviour of 'LIKE' by using the commands:

PRAGMA case_sensitive_like=ON;
PRAGMA case_sensitive_like=OFF;

However in my situation I would like to execute a query, part of which is case sensitive and part of which isn't. For example:

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

Is this possible?

Sqlite Solutions


Solution 1 - Sqlite

You can use the UPPER keyword on your case insensitive field then upper-case your like statement. e.g.

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

Solution 2 - Sqlite

Use plain comparisons, which are case sensitive by default (unless you have declared the column COLLATE NOCASE):

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

This works only if the original LIKE is searching for a prefix, but allows using an index.

Solution 3 - Sqlite

I know this is an old question, but if you are coding in Java and have this problem this might be helpful. You can register a function that handles the like checking. I got the tip form this post: https://stackoverflow.com/a/29831950/1271573

The solution i dependent on sqlite jdbc: https://mvnrepository.com/artifact/org.xerial/sqlite-jdbc

In my case I only needed to see if a certain string existed as part of another string (like '%mystring%'), so I created a Contains function, but it should be possible to extend this to do a more sql-like check using regex or something.

To use the function in SQL to see if MyCol contains "searchstring" you would do:

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

Here is my Contains function:

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

To use this function you must first register it. When you are done with using it you can optionally destroy it. Here is how:

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

Solution 4 - Sqlite

In SQLite you can use GLOB instead of LIKE for pattern search. For example:

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

With this approach you don't have to worry about PRAGMA.

Solution 5 - Sqlite

I used a regular expression to do what I needed. I wanted to identify all the occurrences of the word "In" that was not all lower case.

select [COL] from [TABLE] where [COL] REGEXP '\bIn\b';

Example:

with x as (select 'in' Diff_Ins union select 'In' Diff_Ins)
select Diff_Ins from x where Diff_Ins REGEXP '\bIn\b';

Solution 6 - Sqlite

As others mention, SQLite also offers the GLOB function which is case-sensitive.

Assume g2* is text entered by the user at the application-level. To simplify application-side grammar and make GLOB case-insensitive, the text needs to be normalised to a common case:

SELECT * FROM mytable WHERE LOWER(caseInsensitiveField) GLOB LOWER('g2*');

If UNICODE is required, carefully test LOWER and UPPER to confirm they operate as expected. GLOB is an extension function specific to SQLite. Building a general grammar engine supporting multiple database vendors is non-trivial.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionRichard WilliamsView Question on Stackoverflow
Solution 1 - SqliterbedgerView Answer on Stackoverflow
Solution 2 - SqliteCL.View Answer on Stackoverflow
Solution 3 - SqliteJarle JacobsenView Answer on Stackoverflow
Solution 4 - SqliteYoda066View Answer on Stackoverflow
Solution 5 - SqliteByBarnView Answer on Stackoverflow
Solution 6 - SqliteAlainDView Answer on Stackoverflow