Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android Sqlite INSERT error when table contains only _id

Tags:

android

sqlite

I have a SQLite table that contains only the _id:

"create table rule (_id integer primary key);";

When running this set of commands:

ContentValues initialValues = new ContentValues();
mDb.insert(TABLE, null, initialValues)

I obtain the following exception:

android.database.sqlite.SQLiteException: near "null": syntax error (code 1): , while compiling: INSERT INTO rule(null) VALUES (NULL)

The initial error occurs because ContentValues cannot be empty. Android provides a convenience parameter called nullColumnHack that allows you to pass a single column with the value null, to bypass this problem.

However this doesn't apply in my case because the row id (_id) cannot be null! Based on the syntax found in the SQLite language docs, I would like to be able to run the SQLite code:

INSERT INTO rule DEFAULT VALUES;  

How can i achieve something like this using the android insert method? Or is there something I need to add to my create statement?

UPDATE: In the situation where a table contains ONLY a rowid, the proper syntax is to use INSERT INTO __ DEFAULT VALUES.

The sqlite insert method listed in android does not support DEFAULT VALUES as an option.

A bug has been filed with google and to get support for default values the following commands would need to be executed:

mDb.execSQL("INSERT INTO rule DEFAULT VALUES;");
Cursor c = mDb.rawQuery("SELECT last_insert_rowid()",null);
c.moveToFirst();
int rowid = c.getInt(0);

As stated in the accepted answer, we can get around this (and DEFAULT VALUES) by using nullHackColumn and assigning the row id (_id) to null and letting SQLite make the conversion from null to the auto-incremented value.

like image 489
steve-gregory Avatar asked Feb 14 '26 02:02

steve-gregory


2 Answers

As jeet mentioned you can provide nullColumnHack as a second parameter. And as you yourself mentioned autoincrement isn't necessary to increment a value of primary key. So the syntax:

insert into rule (_id) values(null)

where _id is primary key and autoincremented value is correct for sql. I think most SQL databases will replace null with new incremented value, at least MySQL, SQLite and Oracle can do this

Thus:

ContentValues cv = new ContentValues();
db.insert("rule", "_id", cv);

should give you desired results.

like image 123
lia ant Avatar answered Feb 16 '26 14:02

lia ant


You need to add autoincrement to your create table query like:

"create table rule (_id integer primary key autoincrement);";

In your case you need to manually set the ID of the row with each insert. this way it will increment it automatically when you insert an empty row as you did in your case.

like image 41
DArkO Avatar answered Feb 16 '26 15:02

DArkO



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!