I just want to insert values into a table if the value provided does not exists in that table, I mean I have provided a column as UNIQUE, so sqlite3 UNIQUE constraint will be broken when that value is tried to input twice, i want an sqlite3 insert statement which helps to do this my code is. I read that INSERT IGNORE is used for this purpose. Can somebody provide me with syntax to do this correctly?
My code is given below.
String insertQuery1 = "INSERT INTO Bookdetails bookpath,lastchapter VALUES(?,?)";
db.execSQL(Query1, new String[] { filepath, none });
What is the correct syntax for this query? filepath and none are string which have values assigned
Also this table Bookdetails has a primarykey field 'id' which is auto increment? will it create any problems when data is inserted like this way?
String insertQuery1 = "INSERT INTO Bookdetails (bookpath,lastchapter) VALUES(?,?)";
db.execSQL(Query1, new String[] { filepath, none });
Change
INSERT INTO Bookdetails bookpath,lastchapter VALUES(?,?)
to
INSERT OR IGNORE INTO Bookdetails (bookpath,lastchapter) VALUES(?,?)
The OR IGNORE causes that when a constraint such as UNIQUE is violated, the insert doesn't take place and there won't be an error.
The column names to insert to need to be in () parens.
Additionally, you're passing some other query to execSQL() than the insertQuery1 here.
Also this table Bookdetails has a primarykey field 'id' which is auto increment? will it create any problems when data is inserted like this way?
No, since no insertion takes place.
If you had INSERT OR REPLACE instead of the ignore, it would translate to a DELETE followed by INSERT, generating a new row id in case the id was not specified in the insert itself.
The query is wrong:
INSERT INTO Bookdetails bookpath,lastchapter VALUES(?,?)
It should be:
INSERT INTO Bookdetails (bookpath, lastchapter) VALUES (?, ?)
Mind the parentheses surrounding the fields list!
Related
I need to retrieve the id of the row inserted just now. ie, i have a table for words and a table for meaning. i need the wordId of the word i insert in the table for words and that wordId is used for inserting the meaning in meaning table. Can anyone help me out??
I thought i could use trigger and tried the trigger:
"CREATE TRIGGER IF NOT EXISTS word_insert_trigger AFTER INSERT ON tb_words BEGIN select NEW.word_id from tb_words; END;"
like this. i tried this in sqlite dbbrowser. but it didn't work out.
i need the row id when i insert a row like this :"insert into tb_words(word_name) values('test');"
How can i do that without using "SELECT last_insert_rowid()"? like in the following link:
How to retrieve the last autoincremented ID from a SQLite table?
No need for a trigger. Use the SQliteDatabase insert method. It returns the id (as a long) (more correctly it returns the rowid and assuming that the word_id column has been defined as an alias of the rowid column, then the returned value will be the value assigned to the word_id column).
An alias of the rowid column is defined if word_id INTEGER PRIMARY KEY is coded (the AUTOINCREMENT key may be used BUT in generally should not be used).
You may wish to read SQLite AUTOINCREMENT and/or Rowid Tables
Instead of something like :-
db.execsql("insert into tb_words(word_name) values('test');");
You would use something like :-
ContentValues cv = new ContentValues();
cv.put("word_name","test");
long word_id = db.insert("tb_words",null,cv);
1.which data type should be used to store data like group=AB+ ?
E/SQLiteLog: (1) near "group": syntax error SQLiteDatabase:
Error inserting
district=jhapa phone=9843284985 name=Tom group=AB+
My table is in this format
CREATE TABLE IF NOT EXISTS `Doners` (\n" +
"\t`name`\tTEXT,\n" +
"\t`phone`\tNUMERIC,\n" +
"\t`group`\tBLOB,\n" +
"\t`district`\tTEXT\n" +
");";
For Android you can either use
- native SQL via the SQLiteDatabase execSQL method
- the SQLiteDatabase convenience insert family of methods :-
insert (effectively INSERT OR IGNORE)
insertOrThrow (standard INSERT)
insertWithOnConflict
SQLiteDatabase - insert
So assuming that you want to insert :-
Tom into the name column,
9843284985 into the phone column,
AB+ into the group column,
NOTE that group is an SQLite keyword and therefore cannot be used and will result in a syntax error, unless it is enclosed SQL As Understood By SQLite - SQLite Keywords
jhapa
And that the variable db is an instantiated instance of the SQliteDatabase class then :-
you could use :-
db.execSQl("INSERT INTO `Doners` VALUES('Tom',9843284985,'AB+','jhapa')");
noting that a value must be provided for all the defined columns and that the values should be in the order that the columns were defined in.
or you could use :-
db.execSQL("INSERT INTO Doners (district,phone,name,`group`) VALUES ('jhapa','9843284985','Tom','AB+')");
Here you specify the columns into which the values will be placed, you can specify them in what order you like (values will be inserted according to the order), you can also omit columns (dependant upon the column definition)
Defining a column as NOT NULL would require a column and value. However, if a DEFAULT value has been defined as well as NOT NULL then the column can be omitted.
you could use the insert convenience method like :-
ContentValues cv = new ContentValues();
cv.put("phone","9843284985");
cv.put("name","Tom);
cv.put("`group`","AB+");
cv.put("district","jhapa");
long rowid = db.insert("Doners",null,cv);
rowid will be the rowid of the inserted row (a unique identifier of the row) or if no row was inserted then -1.
the convenience method :-
it builds the SQL on your behalf
protects against SQL injection
encloses values accordingly
suitable encodes byte[]'s into the the x'ff00fe.......' used by SQL.
returns the rowid (executes a query using last_insert_rowid()).
in regards to :-
which data type should be used to store data like group=AB+ ?
Due to SQLite's flexibility it probably does not matter what type is assigned to the column. That is with the exception of the rowid or an alias of the rowid (the_column INTEGER PRIMARY KEY makes the_column an alias of the rowid column) any type of data can be stored in any type of column and to further expand on the flexibility type can be virtually anything (keywords and other syntactically confusing values excepted).
As such CREATE TABLE mytable (mycolumn RUMPLESTILTSKIN) is valid (column has numeric affinity). see - Datatypes In SQLite Version 3
In my Android app, I create a FULLTEXT table like this:
CREATE VIRTUAL TABLE products USING fts3 (
_id integer PRIMARY KEY,
product_name text NOT NULL,
...
)
And I add this index:
CREATE INDEX product_name_index ON products (product_name)
The app populates the table with various products, each with a unique _id value.
However, when I then try to insert an already-existing product ID (using an _id value that is already in the table, but with a different product_name value) like this:
long rowId = db.insertOrThrow("products", null, contentValues);
a new row is added to the table (with a brand new rowId value returned)!
I expected the insertOrThrow command to fail, so where am I going wrong? Is it something to do with the fact that it's a FULLTEXT table or could the index I specified on the product_name column be messing things up somehow?
I read this section about INTEGER PRIMARY KEY, but unfortunately I'm none the wiser.
Update
When I try to perform the same operation on a standard (non-FULLTEXT) table, then the insertOrThrow command results in the expected SQLiteConstraintException.
I think the issue might be that an FTS table has the concept of a docid and a rowid column and specifying null for the docid results in that being given a value.
as per :-
There is one other subtle difference between "docid" and the normal
SQLite aliases for the rowid column.
Normally, if an INSERT or UPDATE
statement assigns discrete values to two or more aliases of the rowid
column, SQLite writes the rightmost of such values specified in the
INSERT or UPDATE statement to the database.
However, assigning a
non-NULL value to both the "docid" and one or more of the SQLite rowid
aliases when inserting or updating an FTS table is considered an
error. See below for an example.
1.3. Populating FTS Tables
I have a case that I would like to insert record in SQLite with database.insert(table, null, values).
TABLE t2 (_id, field1, field2)
..
val.setVal1(null);
val.setVal2(val2);
..
if(val.getVal1==null){
values.put(field1, _id);
}else{
values.put(field1, var.val1);
}
values.put(field2, var.val2);
database.insert("t2", null, values);
Is possible to do sth like this "values.put(field1, _id);"?
_id is generated at database.insert().
Note: I am looking for solution for one insert call. Insert and update row with (field1=_id) is easy.
i think i see now. you're asking if you can enter a value into a specific SQLite row _id field if it's available in your val object. Else, you want the database to automatically create a unique id for that column while inserting, like normally done. Is this correct?
To that end, i would seriously reconsider this purpose. You should never be specifying values for the _id column because it needs to be unique or else you'll get exceptions thrown. Moreover, it's only purpose is to be a unique identifier for the system, so you personally knowing this value should be of no use to you.
If you still need this functionality, i'd suggest making another field in your table (much like the _id column but not it), which you can fill with randomly generated numbers or val.getVal1 values.
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.
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.
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.
Try this way :
ContentValues initialValues= new ContentValues();
if(check here --id is null----)
{
initialValues.put("_id", "0");
}
else
{
initialValues.put("_id", id);
}
mDb.insert(TABLE, null, initialValues)
Check following:
http://developer.android.com/reference/android/database/sqlite/SQLiteDatabase.html#insert(java.lang.String, java.lang.String, android.content.ContentValues)
SQL doesn't allow inserting a completely empty row without naming at least one column name. If your provided values is empty, no column names are known and an empty row can't be inserted. If not set to null, the nullColumnHack parameter provides the name of nullable column name to explicitly insert a NULL into in the case where your values is empty.
the insert needs a null value you just have to put
db.insert ("people", null, c);