Sqlite linked tables in Access give #deleted values, again - sqlite

Situation: MS Access (happens to be 2010) using SQLite ODBC driver (0.997) to link to tables in a SQLite (3.x) database.
Problem: data values in all columns in all rows display as "#Deleted".
Solution: This is a "answer my own question" kind of post, with a solution, below.
Edited: to move solution to Answers section.

Earlier, I searched in stackoverflow, found a similar question (sqlite linked tables in Access give #deleted values) with a good answer that turns out to be inapplicable in my case. So I'm adding some info here.
Half of the problem is explained here: http://support.microsoft.com/kb/128809 '"#Deleted" errors with linked ODBC tables.'
The above link was no longer available in Jul-2021. However you may find a good explanation for '#DELETED# Records Reported by Access' in https://dev.mysql.com/doc/connector-odbc/en/connector-odbc-errors.html
This explains that Access (Jet) wants a table to have a unique index in order to be able to insert/update the table if necessary.
If your SQLite table doesn't have a unique index (or primary key), then Access will only allow read access to the table -- you can't edit the table's data in Access, but the data displays fine.
To make the table updateable you might revise your SQLite code (or using a SQLite tool) to add an index to the table.
If your PK/unique index happens to use a TEXT field, that's fine for SQLite. However, when you link to it in Access, Access will show the #Deleted indications.
The chain of events appears to be:
Access/Jet notices the unique index, and tries to use it. However, SQLite TEXT fields are variable length and possibly BLOBs. This apparently doesn't fulfill Access's requirements for a unique index field, hence the #Delete indication.
To avoid that problem, the index has to be a SQLite field type that Access will accept. I don't know the complete list of types that are acceptable, but INTEGER works.
Hope this helps someone.

Related

Is it possible to change a column without run raw sql in DbVisualizer + SQLite

Working on a SQLite database, seems DbVisualizer Pro does a lot of work very well, except one,
Changing table schema.
I often need to change column name, data type, etc, but don't want to do it through raw SQL statement. My workaround is opening Firefox's SQLite Manager to just change the schema.
Is it possible to use DbVisualizer to change the schema? many thanks!
Edit:
Alter table action mentioned below by roger, seems to be the right way to go. But somehow I can only add column, the existing column appears to be read only.
Mine is DBVisualizer Pro Evaluation. Is non-Evaluation different?
Edit2:
Using SQLite Manager is sometimes dangerous, as warned below. just learned, renaming a column may cause the foreign key loss. but workaround is here
In DbVisualizer Pro there is the Alter Table action (and Create Table for creating new tables). Select the actual table you want to change in the Databases tab, right-click and chose Alter Table. In order for this to work you need DbVisualizer Pro and the Database Type for your connection must be set to either Auto Detect (recommended) or SQLite.

Ordering results (from a search) by number of matches

I'm implementing search for an Android app using an SQLite db, and am wanting to order the results from a search according to the number of matches in a TEXT column
For example let's say that my db table is called article, the TEXT column I want to search is called article_main_text, and that the the user searches for the word "friend". Then I want the db table rows which have the highest number of occurrences of "friend" in their article_main_text column to be shown first
I already know that I can provide custom SQLite statements in the sort order in my CursorLoader (for example supplying this to the CursorLoader constructor), so I'd like to ask: How can I write SQLite code that orders the results with the help of SQLite?
Counting just the occurrences of a word might not be the most accurate or most efficient way of doing it. What you really need is full text search. Which is supported in sqlite and available in Android.
Fortunately there is a tutorial on Android Developer and I am sure there would be a full working sample in their code collections.

SQLite LIKE statement with special characters

I am trying to run a search query on my SQLite db and am having problems with special characters that are stored.
I have a column called site_name which contains records like castle, chàteau, church. When someone uses chateau as their search term I want it to pull out the chàteau record.
Is there a method for handling this in SQLite?
Thanks
See here
The link references Android development, but it appears to answer your question.

Is there any best way to implement version control for database content?

I'm currently writing a posting website that needs to have a version control on posts. I just don't know how I should implement this, in term of database and technique, in order to save and control the post.
Is there anyone experienced with this who can help me?
I've seen that Wordpress does version control only in 1 table, which is POST. I also suggest doing the same since it's trouble to write into 2 tables with the same amount of data and fields.
I know that stackoverflow stores deltas between versions. What I have seen others do is set up another table like the first one but with an author and a version or timestamp on it. You can push records over to the other table using a database trigger so you don't have to worry too much about making the change at the application level.
If you would like to use only one table then I would suggest adding the author, timestamp and a iscurrent flag. The flag isn't really needed since you can select the max version number but it will make your queries much easier. Set the flag only when the row is the highest version number. You can still use a trigger to populate the rows but watch out or you might end up in a loop of update triggers.
I would create two tables, one is "live version" table and the other is an "archive" table. When a new version is created, move the existing live version to the archive table (with appropriate timestamps and author notes) and add the new live version to the live table.
The archive table would have the same schema as the live table except that it would also have additional columns that would hold metadata about the versioning that you are supporting (version number, notes, timestamps, etc.).
Take this with a huge grain of salt, but, you could have a parent id that is joined to the primary key on the same table along with a bool that indicates whether its the current version. It's the method I used for a CMS system a while back... You might want a common id for a revision history (so that getting all historic entries for an item is non recursive). You could do this by including the first version's id with the all the subsequent versions so you could get the whole lot easily.
my .02
Sounds like you just want a record version number on the row. It's a number that identifies the latest version. Every time you update the data you actually insert a new row and bump the record version number. When you query to get the data, you just query to get the row with the max record version number. Triggers can be used to generate the record version number so you don't have to worry about generating the number when inserting.
If you want to go full-blown version control, you need some sort of status field on the row as well that tells you if this version is reverted/deleted/approved or not. When you get the latest, you select the the row with the max revision control number that has the appropriate status.
If you just want to save the history of the posts and not actually have revision control you can just use the record version number technique.
See also Implementing Version Control of DB Objects.

SQLite Query - Need Help with Full Text Search

Here's what I'm trying to do.
User (a):
Enters data in two fields (description-1) and (description-2).
User (b) Enters similar data in opposite fields.
User (a) or (b) search on both fields would find a match.
A good analogy would be a dating search. User (a) enters a description of themselves and the match they are looking for, and User (b) enters a description of themselves and the match they are looking for and Both would be able to do a search and find a match.
So in psuedo query english...
Select name from data where me = 'target' and target = 'me'
The catch would be, some of the words in the field would match, but not all.
This type of matching is hard no matter what the technology. You may have bitten off more than you can chew.
My recommendation to you is to read up on the Text Search data types in PostgreSQL.
PostgreSQL offers a flexible and powerful solution for full-text search, and it may do what you need, whereas SQLite probably won't.
Using the PostgreSQL tsquery and tsvector data types, you could turn one user's description into a form that queries the description of another user. Both tsquery and tsvector can be generated dynamically or saved in database columns and indexed.
If you still need to use SQLite, you need to learn about the various FTS virtual table types. These are all experimental and are not enabled by default. So you need to recompile SQLite, enabling FTS1, FTS2, or FTS3.
Documentation for these features is pretty sparse. Here's all I have found:
http://www.sqlite.org/cvstrac/wiki?p=FullTextIndex
http://www.sqlite.org/cvstrac/wiki?p=FtsUsage
http://www.sqlite.org/cvstrac/wiki?p=FtsOne
http://www.sqlite.org/cvstrac/wiki?p=FtsTwo
http://www.sqlite.org/cvstrac/wiki?p=CompilingFts
http://www.sqlite.org/cvstrac/wiki?p=CompilingFtsThree

Resources