I have created a table like Players in onCreate() method which is in MySQLiteHelper.java:
String CREATE_PLAYERS_TABLE = "CREATE TABLE Players
(id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT, password TEXT, score INTEGER)";
db.execSQL(CREATE_PLAYERS_TABLE);
And I have an update method in the same class like:
public int PlayerUpdate(Player PL) {
// 1. get reference to writable DB
SQLiteDatabase db = this.getWritableDatabase();
// 2. create ContentValues to add key "column"/value
ContentValues values = new ContentValues();
values.put("name", PL.getName());
values.put("password", PL.getPassword());
values.put("score", PL.getScore());
// 3. updating row
int i = db.update(TABLE_Players, // table
values, // column/value
KEY_ID + " = ?", // selections
new String[] { String.valueOf(PL.getId()) }); // selection args
// 4. close
db.close();
return i;
}
and when I call functions to change score variable as:
public void scoreUp() {
helper.PlayerUpdate(new Player(player_name,player_password,player_score+5));
}
public void scoreDown() {
helper.PlayerUpdate(new Player(player_name,player_password,player_score-5));
}
I am getting a logcat error like:
Failed to read row 0, column 1 from a CursorWindow which has 1 rows, 1 columns.
FATAL EXCEPTION: main
java.lang.IllegalStateException: Could not execute method of the activity
Caused by: java.lang.IllegalStateException: Couldn't read row 0, col 1 from CursorWindow.
Make sure the Cursor is initialized correctly before accessing data from it.
Thanks.
SOLVED:
There has been another query that causes this specific exception and I found out.
The exception comes from accessing cursor columns and the code you posted doesn't show that.
However, column indexing starts from 0, so to access the first column value as string, use getString(0) instead of getString(1).
Related
I am using this method to get query for this string:
public void deletedata(){
p=srt.split(",");
DatabaseHandler dba=new DatabaseHandler(this);
for(String s:p) {
dba.removeSingleproduct(s);
}
Database method is :
public boolean removeSingleproduct(String name) {
SQLiteDatabase db = this.getWritableDatabase();
return db.delete(tablename, productinserted + "=" + name, null) > 0;
}
I want to delete only one row by calling database as product inserted can have two same value.
Please help guys.
Since you're deleting with a selectedValue String,
add a single quote before and after the name
return db.delete(tablename, productinserted + " = '" + name + "'", null) > 0;
Or you can simplify your code.
public int removeSingleproduct(String name) {
return getWritableDatabase().delete(tablename, productinserted + " = ?", new String[] { name });
}
Return int - the number of rows affected if a whereClause is passed in, 0 otherwise. To remove all rows and get a count pass "1" as the whereClause.
The following will use the name to locate all rows with the provided name but only delete the first according to it's rowid (unless WITHOUT ROWID has been specified [very likely not]).
public boolean removeSingleproduct(String name) {
boolean rv = false;
SQLiteDatabase db = this.getWritableDatabase();
Cursor csr = db.query(tablename,new String[]{"rowid AS dltid"},productinserted + "=?",new String[]{name},null,null,null);
if(csr.moveToFirst()) {
rv = db.delete(tablename,"rowid=?",new String[]{Long.toString(csr.getLong(csr.getColumnIndex("dltid")))}) > 0;
}
csr.close();
return rv;
}
If you wanted to ensure that a row was only deleted if multiple rows with the same productinserted name existed, then you could simply change
if(csr.moveToFirst()) { ........
to
if(csr.moveToFirst() && csr.getCount() > 1) { .......
Note! csr.moveToLast() could be used instead of csr.moveToFirst() it would probably then delete the newest addition rather than probably deleting the oldest addition.
If you think
but I haven't defined a column called rowid
then :-
Except for WITHOUT ROWID tables, all rows within SQLite tables have a
64-bit signed integer key that uniquely identifies the row within its
table. This integer is usually called the "rowid". The rowid value can
be accessed using one of the special case-independent names "rowid",
"oid", or "rowid" in place of a column name. If a table contains a
user defined column named "rowid", "oid" or "rowid", then that name
always refers the explicitly declared column and cannot be used to
retrieve the integer rowid value.
SQL As Understood By SQLite - ROWIDs and the INTEGER PRIMARY KEY
I'd like to do something like this:
public boolean containsKey(int primaryKey) {
SQLiteDatabase db = getReadableDatabase();
// what should i do here to determine if the db contains the primaryKey?
}
What is the most efficient way to check if the db contains the specified value?
You could try to read the row with that PK value:
public boolean containsKey(int primaryKey) {
SQLiteDatabase db = getReadableDatabase();
Cursor cursor = db.query("TableName", null, "IDColumn = " + primaryKey,
null, null, null, null);
return cursor.moveToFirst();
}
However, it would be a better idea to use a helper function that allows you to avoid having to muck around with a cursor:
public boolean containsKey(int primaryKey) {
SQLiteDatabase db = getReadableDatabase();
return DatabaseUtils.queryNumEntries(db, "TableName", "IDColumn = " + primaryKey) > 0;
}
You should inspect sqlite scheme. You may try
"SELECT name FROM sqlite_master WHERE type='table'"
Second variant:
PRAGMA table_info(table-name);
If You are looking for getting the column names for a table:
PRAGMA table_info(your_table_name);
Example :
PRAGMA table_info(Login);
you will get pk value 1 if you have primary key in login table.
Check this tutorial on PRAGMA
This pragma returns one row for each column in the named table.
Columns in the result set include the column name, data type, whether
or not the column can be NULL, and the default value for the column.
The "pk" column in the result set is zero for columns that are not
part of the primary key, and is the index of the column in the primary
key for columns that are part of the primary key.
I have the following code to update or insert database, where q_id is my primary key
public long updateResponse(int response, int q_id) {
SQLiteDatabase db = helper.getWritableDatabase();
ContentValues contentValues = new ContentValues();
long id = 0;
contentValues.put(VivzHelper.Q_ID, q_id);
contentValues.put(VivzHelper.QUESTION_RESPONSE, response);
id = db.insertWithOnConflict(VivzHelper.TABLE_QUESTION_TEXT, null, contentValues, SQLiteDatabase.CONFLICT_REPLACE);
if(id==-1)
Log.d("failed", "failed"+response);
else
Log.d("success","success"+response);
return id;
}
Above code is updating/inserting QUESTION_RESPONSE but making all other column in that row as null in table.. Help
Above code is updating/inserting QUESTION_RESPONSE but making all other column in that row as null in table
That's what the "replace" conflict resolution does. If the insert would result in a conflict, the conflicting rows are first deleted and only then is the new row inserted. NULL is the default default value for a column.
If you need to retain other column data in the row, use an UPDATE query. For example, to update the response column to the row with the specified id:
contentValues.put(VivzHelper.QUESTION_RESPONSE, response);
db.update(VivzHelper.TABLE_QUESTION_TEXT, contentValues,
VivzHelper.Q_ID + "=?", new String[] { String.valueOf(q_id) });
I am using sqlite
i want to print the query executed in db to insert
here is my code
// for SAving Ocean/Air sales
public int saveOrder(Order odr) throws SQLException {
SQLiteDatabase db = con.getWritableDatabase();
int ordrId = 0;
ContentValues values = new ContentValues();
values.put("cr_usr", odr.getCrUsr());
values.put("cr_ts", odr.getCrTs().toString());
values.put("eat_mst_cust_id", odr.getEatMstCustId());
values.put("ordr_dt", odr.getOrdrDt().toString());
String selectQuery = "SELECT last_insert_rowid()";
try {
// Inserting Row
db.insertOrThrow("eat_ordr", null, values);---getting error here for constraint failed
Cursor cursor = db.rawQuery(selectQuery, null);
cursor.moveToFirst();
ordrId = cursor.getInt(0);
db.close();
} finally {
db.close();
}
return ordrId;
}
I am not getting any error but row is failed to insert bcz it returns 0 for idvalue
so i want to see executed query how to get that query?
here is my table structure
CREATE TABLE "eat_ordr" ("eat_ordr_id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL ,
"eat_mst_cust_id" VARCHAR NOT NULL REFERENCES "eat_mst_cust"("eat_mst_cust_id"),
"ordr_no" VARCHAR NOT NULL UNIQUE ,
"ordr_dt" DATETIME NOT NULL ,
"ordr_stat" VARCHAR NOT NULL ,
"last_sync_ts" DATETIME,
"cr_ts" DATETIME DEFAULT CURRENT_TIMESTAMP, "md_ts" DATETIME, "cr_usr" VARCHAR, "md_usr" VARCHAR)
The insertOrThrow documentation says:
Returns
the row ID of the newly inserted row
So this can be done much easier:
ordrId = db.insertOrThrow("eat_ordr", null, values);
Inserting data to SQLite table with constraint failure
I'm trying to insert data into SQLite table on Android. _id is primary key of the table and I am inserting a row using this method:
public void addSomeData(int id, String datetime) {
ContentValues contentValues = new ContentValues();
contentValues.put(KEY_ID, id);
contentValues.put(KEY_DATETIME, datetime);
mDb.insert(TABLE, null, contentValues);
}
The problem I get is that sometimes primary key constraint is validated and I would like to use something like INSERT IF NOT EXISTS, but preferably something that would work with ContentValues. What are my options? I understand that insertOrThrow() and insertWithOnConflict() methods only return different values, or should I use one of these methods?
Use insertWithOnConflict() with CONFLICT_IGNORE.
Will return ROWID/primary key of new or existing row, -1 on any error.
In my case "constraint failure" happened because of I had some tables which are depended on each other. As for the "insert if not exist", you can query with this id and you check if the cursor's count is bigger than zero. Check the method I'm already using in my app.
public boolean isRowExists(long rowId) {
Cursor cursor = database.query(this.tableName, this.columns, DBSQLiteHelper.COLUMN_ID + " = ? ", new String[] { "" + rowId }, null, null, null);
int numOfRows = cursor.getCount();
cursor.close();
return (numOfRows > 0) ? true : false;
}
to do so you could simply query the db to see if a row with that key exists and insert the new row only if the query returns no data.