Question

I am using SQLite-net for accessing an SQLite database file in a WinRT app. I don't have any problems reading from the database using the ExecuteQuery (I actually use the modified version from https://github.com/praeclarum/sqlite-net/issues/82 as I don't use table mappings and want the results as dictionary which calls ExecuteDeferredQuery underneath).

When I try to insert records into my database using ExecuteNonQuery, I am getting an exception with the message "CannotOpen".

Well, just a few lines above, I can read from the database successfully. I double checked the file permissions to the sqlite database file and gave everyone on the computer full control to the file to avoid any file permission issues, but the result is the same, still getting "CannotOpen".

I just tried to do a select statement with ExecuteNonQuery (just to see if it works"), I still get an exception, this time saying "Row" as the exception message.
I tried to execute my insert with ExecuteQuery to see what happens, no exception is thrown, everything seems OK, but no rows are inserted into my database.

Well, that may be explainable as ExecuteQuery is designed for querying, not inserting, but what could be the reason for ExecuteNonQuery throwing exceptions?

Here is my code (removed actual table names and parameters with generic ones for privacy):

SQLiteCommand cmd = conn.CreateCommand("insert into mytable(myfields...) values (?,?,?,?,?,?,?)", my parameters...);
cmd.ExecuteNonQuery(); //throws SQLiteException

However this code doesn't throw exception:

SQLiteCommand cmd = conn.CreateCommand("select * from mytable where some condition...", some parameters...);
var result = cmd.ExecuteToDictionary(); //renamed ExecuteQuery method from https://github.com/praeclarum/sqlite-net/issues/82

UPDATE: I've further tracked the issue down to something even simpler (and weird). This code is the very first call to SQLite framework after initialization of the connection. This very code, when executed, throws an exception in the fourth line:

 SQLiteCommand cmd = conn.CreateCommand("select * from mytable");
 cmd.ExecuteNonQuery();
 cmd = conn.CreateCommand("select * from mytable"); //yes, the same simple query as above
 cmd.ExecuteNonQuery();//getting error

UPDATE 2: If I call ExecuteToDictionary instead of ExecuteNonQuery, it works.

UPDATE 3: If I try a direct query (from the conn object such as conn.Execute("query...")) before all these calls it fails. If it's an insert query, I get CannotOpen error, if it's a select query, I get a Row error.

Why am I getting an exception on the second call to ExecuteNonQuery?

Why am I getting a different error message "Row" when I try SELECT with ExecuteNonQuery? And lastly, why are these exceptions so user-unfriendly?

Was it helpful?

Solution

Found out the answer. The SQLite file was in a directory that didn't have write access (the file DID have all the access in file properties, but I think it's a WinRT security model issue as the file was outside the sandbox of WinRT's storage folders. I could read the file, but not write. Thanks to SQLite-net's extremely helpful exception messages such as "Row" and "CannotOpen", without giving any real details about the problem, it took me days to realize that it was a file access issue rather than an SQLite configuration/query issue.

If anyone has any similar problems in the future, first, check that the SQLite database is in the storage directory of the WinRT app.

OTHER TIPS

try to close and open the connection object before executing any other operations

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top