How to use collation for pattern matching in sqlite? - sqlite

For example if in the sqlite database have entries Resume, Résumé ,RESUME and if we enter
select Name from NAME_TABLE where Name like 'Re%%'
It should return all
But like does not support collation , any-other way to do pattern matching using collation ?

In SQLite, LIKE always uses the NOCASE or BINARY collations.
You could redefine LIKE by install a user-defined like() function, but you could just as well use your own function with a different name.

Related

concatenate strings with atomic update in peewee using sqlite db

I would like to update a text field in an sqlite database created using the peewee python library. Specifically I would like to use peewee's atomic updates something like:
query = Table.update(textfield = Table.textfield + 'string').where(some condition)
query.execute()
This type of update works fine for numeric fields but not for text fields. I'm guessing there may be a way to do this with the sqlite || operator, but as sql in general is somewhat new to me I am unable to figure it out.
You can use the concat operator:
query = Table.update(textfield=Table.textfield.concat('string')).where(whatever)
query.execute()
The concat operator will use || under-the-hood.

Using COLLATE on peewee queries

I found in the peewee documentation how to create custom collations, but I wasn't able to find how to use the built-in sqlite collating sequences.
Ho do I create the following query in peewee (it is the last one in the above mentioned sqlite documentation page)?
SELECT x FROM t1 ORDER BY c COLLATE NOCASE, x;
And how do I specify the collation for an index?
CREATE INDEX i1 ON t1(f1 COLLATE NOCASE);
EDIT
The answer from coleifer addresses the question about the query.
For the index creation I am using the following trick, which works well when you create the indexes only once at startup (like in my app).
The case insensitive unique index on two columns on the table LockedFiles prevents duplicated entries.
class LockedFiles(PeeweeModel):
folder = peewee.CharField(index=True)
file = peewee.CharField(index=True)
#classmethod
def custom_init(cls):
db.execute_sql('create unique index if not exists lockedfiles_unique '
'on lockedfiles(folder collate nocase, file collate nocase)', {})
def create_tables(drop_existing_tables):
for table in [LockedFiles, Model2, Model3]:
if drop_existing_tables:
table.drop_table(True)
table.create_table(True)
try:
table.custom_init()
except:
pass
create_tables(drop_existing_tables=False)
You can specify a collation by building up the SQL clause and passing it to order_by().
For example:
collated = Clause(MyModel.field, SQL('COLLATE NOCASE'))
MyModel.select().order_by(collated, MyModel.other_field)
For the index unfortunately you will need to create that by hand as peewee does not know how to add collation information to the CREATE INDEX SQL. If you'd like to open a pull-request I would definitely consider merging that feature, though.

Can we force SQL Server for case sensitivity

What if I want to authenticate user using Stored Procedure using ADO.Net? Is there any way to do this or directly authenticate or find other way?
You can use database collation for your idea.
you must use SQL_Latic1_General_CP1_CS_AS instead of you must use SQL_Latic1_General_CP1_CI_AS
Also you can apply your collation on the special columns.
For example :
CREATE TABLE yourtable
(Name NvarChar(100) COLLATE SQL_Latic1_General_CP1_CI_AS, ...

My sqlite3 database/queries are very slow. Switch or fix queries?

I have a large sqlite db. Its 185mb.
This query is taking about 5seconds and it returns 2 rows. I added an index to user.name than Content.user_id. It stills take many seconds. Can sqlite handle large files like this? Is there a simple fix for a private app like telling sqlite to put everything in ram on app startup? (Its C#.NET for dev use only).
select Content.*,name from user
join Content on Content.user_id=user.id
where user.name like 'some_name' order by some_col ASC;
Try the following:
Replace LIKE 'some_name' with = 'some_name'. LIKE queries with underscore or percent sign will not perform as well as equality checks. Depending on the position of the first percentage sign or underscore they might be unable to use your index on user.name.
Launch ANALYZE.
Followup to your answer:
I think you have case-insensitive LIKE pragma enabled. This means that:
You should recreate your database and use name COLLATE NOCASE in the definition of the name column of table users. Thus, all comparison tests on user names will be case insensitive, and so will your index be. This way, a case-insensitive LIKE can use the index also.
Perhaps you should check your indexes

Syntax for using collate nocase in a SQLite replace function

I have an existing database where they created theiw own unicode collation sequence. I'm trying to use the following code and get a "no such collation sequence" exception. Can anybdy hlep with the the syntax to use "collate nocase" with this code?
update Songs set
SongPath = replace (SongPath, 'Owner.Funkytown', 'Jim');
Dump database (via shell), edit output SQL (find and change column definitions, set COLLATION NOCASE). Recreate database.

Resources