android sqlite exception:java.lang.IllegalArgumentException: column '_id' does not exist - android

I created a sql lite database with the following columns:
static final String dbName="demoDB";
static final String tableName="Employees";
static final String colID="EmployeeID";
then
public void onCreate(SQLiteDatabase db) {
// TODO Auto-generated method stub
db.execSQL("CREATE TABLE "+tableName+" ("+colID+" INTEGER PRIMARY KEY AUTOINCREMENT, "+
colName+" TEXT, "+colAge+" Integer);");
}
I want to select all the records in the database like this and display them in a gridview:
SQLiteDatabase db=this.getWritableDatabase();
Cursor cur= db.rawQuery("Select "+colName+", "+colAge+" from "+tableName, new String [] {});
String [] from=new String []{DatabaseHelper.colName,DatabaseHelper.colAge};
int [] to=new int [] {R.id.colName,R.id.colAge};
SimpleCursorAdapter sca=new SimpleCursorAdapter(this,R.layout.gridrow,c,from,to);
GridView grid=(GridView)findViewById(R.id.grid);
grid.setAdapter(sca);
but i receive the following exception:
java.lang.IllegalArgumentException: column '_id' does not exist.
the db table does not have a column with name '_id'
so what is wrong with this code
Thanks

a workaround to this problem is to use select statment like this
select EmpId as _id
cause the adapter requires a column with the name _id as you said
thanks

When using an adapter, your Table must always have the Primary Key Column named as "_id"
Just change
static final String colID="EmployeeID";
to
static final String colID="_id";
Cheers!

CursorAdapters require an INTEGER PRIMARY KEY column named _id (available from BaseColumns).

Try this way
SELECT _ID as _ID,_ID as _id , cont_type ,.... FROM DATABASE_TABLE ;
When _ID only ,Message is column '_id' does not exist.
When _id only ,Message is column '_ID' does not exist.

I tried _id (lower case) instead of _ID (Uppercase) solves the problem. Make sure to recreate the DB once again with _id (lowercase)
Thank you very much

If you loading your database from assets: After you have changde your id to _id in the database base table, and your loading it from assets folder that you uninstall the app first, otherwise you will be using your old database.

Related

Android - Change a column type in SQLite database dynamically at runtime

I have an application, where I am detecting the type of a particular column at run-time, on page load. Please refer the below code:
public String fncCheckColumnType(String strColumnName){
db = this.getWritableDatabase();
String strColumnType = "";
Cursor typeCursor = db.rawQuery("SELECT typeof (" + strColumnName +") from tblUsers, null);
typeCursor.moveToFirst();
strColumnType = typeCursor.getString(0);
return strColumnType;
}
The above method simply detects the type of column with column Name 'strColumnName'. I am getting the type of column in this case.
Now, I want to change the column type to TEXT if I am receiving INTEGER as the column type. For this, I tried the below code:
public String fncChangeColumnType(String strColumnName){
db = this.getWritableDatabase();
String newType = "";
Cursor changeCursor = db.rawQuery("ALTER TABLE tblUsers MODIFY COLUMN " + strColumnName + " TEXT", null);
if (changeCursor != null && changeCursor.moveToFirst()){
newType = changeCursor.getString(0);
}
return newType;
}
But while executing the 'fncChangeColumnType' method, I am getting this error, android.database.sqlite.SQLiteException: near "MODIFY": syntax error (code 1): , while compiling: ALTER TABLE tblUsers MODIFY COLUMN UserID TEXT
NOTE: I also replaced 'MODIFY' with 'ALTER', but still getting the same error.
Please check if this is the right method to change the type dynamically.
Please respond back if someone has a solution to this.
Thanks in advance.
In brief, the solution could be :-
Do nothing (i.e. take advantage of SQLite's flexibility)
you could utilise CAST e.g. CAST(mycolumn AS TEXT) (as used below)
Create a new table to replace the old table.
Explanations.
With SQLite there are limitations on what can be altered. In short you cannot change a column. Alter only allows you to either rename a table or to add a column. As per :-
SQL As Understood By SQLite - ALTER TABLE
However, with the exception of a column that is an alias of the rowid column
one defined with ?? INTEGER PRIMARY KEY or ?? INTEGER PRIMARY KEY AUTOINCREMENT or ?? INTEGER ... PRIMARY KEY(??) (where ?? represents a valid column name)
you can store any type of value in any type of column. e.g. consider the following (which stores an INTEGER, a REAL, a TEXT, a date that ends up being TEXT and a BLOB) :-
CREATE TABLE IF NOT EXISTS example1_table (col1 BLOB);
INSERT INTO example1_table VALUES (1),(5.678),('fred'),(date('now')),(x'ffeeddccbbaa998877665544332211');
SELECT *, typeof(col1) FROM example1_table;
The result is :-
As such is there a need to change the column type at all?
If the above is insufficient then your only option is to create a new table with the new column definitions, populate it if required from the original table, and to then replace the original table with the new table ( a) drop original and b)rename new or a) rename original, b) rename new and c) drop original)
e.g. :-
DROP TABLE IF EXISTS original;
CREATE TABLE IF NOT EXISTS original (mycolumn INTEGER);
INSERT INTO original VALUES (1),(2),(3),(4),(5),(6),(7),(8),(9),(0);
-- The original table now exists and is populated
CREATE TABLE IF NOT EXISTS newtable (mycolumn TEXT);
INSERT INTO newtable SELECT CAST(mycolumn AS TEXT) FROM original;
ALTER TABLE original RENAME TO old_original;
ALTER TABLE newtable RENAME TO original;
DROP TABLE IF EXISTS old_original;
SELECT *,typeof(mycolumn) FROM original;
The result being :-
i think the sql query statement is wrong ,try
ALTER TABLE tblUsers MODIFY COLUMN id TYPE integer USING (id::integer);
instead of id use column name....
hope this helps....
EDIT:
"ALTER TABLE tblUsers MODIFY COLUMN "+strColumnName+" TYPE integer USING ("+strColumnName+"::integer);"

How to use _COUNT in BaseColumns

I've been reading up on BaseColumns](https://developer.android.com/reference/android/provider/BaseColumns.html) in Android to help structure my database schema.
I know that _ID is a unique identifier for the row that you have to create yourself:
protected static final String SQL_CREATE = "CREATE TABLE " + TABLE_NAME + "( " +
_ID + " INTEGER PRIMARY KEY AUTOINCREMENT" + ...;
I also read that _COUNT is used to refer to the number of rows in a table.
However, when I tried using _COUNT, I got an error. Here is what I tried:
SQLiteDatabase db = TimetableDbHelper.getInstance(context).getReadableDatabase();
Cursor cursor = db.query(
SubjectsSchema.TABLE_NAME,
new String[] {SubjectsSchema._COUNT},
null, null, null, null, null);
cursor.moveToFirst();
int count = cursor.getInt(cursor.getColumnIndex(SubjectsSchema._COUNT));
cursor.close();
return count;
I'm not sure whether or not this is the correct way to use it, but I got this error:
android.database.sqlite.SQLiteException: no such column: _count (code 1): , while compiling: SELECT _count FROM subjects
How should I be using _COUNT?
In the database, there is nothing special about either _id or _count.
Your queries return an _id or _count column when the table is defined to have such a column, or when the query explicitly computes it.
Many objects of the Android framework expect a cursor to have a unique _id column, so many tables define it.
In most places, the _count is not expected to be present, so it is usually not implemented. And if it is actually needed, it can simply be computed with a subquery, like this:
SELECT _id,
[other fields],
(SELECT COUNT(*) FROM MyTable) AS _count
FROM MyTable
WHERE ...
If you want to find out the size of your own table, you are not required to use the _count name; you can execute a query like SELECT COUNT(*) FROM subjects, or, even simpler, use a helper function that does this for you.

How is it possible to insert row into SQLite table without specifying value for the primary key

I'm working on a project and don't understand this part of this code that I found online. (I have also looked at other examples and they do the exact same thing but I don't quite understand why)
When they are inserting something into the table, they have no value for the primary key. Could someone explain to me why that is the case?
Here is 2 examples of code that I found that do what I have stated above.
Thanks.
// As you can see a contact has 3 attributes.
int _id;
String _name;
String _phone_number;
// Where they create a table. As you can see the primary key is ID
#Override
public void onCreate(SQLiteDatabase db)
{
String CREATE_CONTACTS_TABLE = "CREATE TABLE " + TABLE_CONTACTS + "("
+ KEY_ID + " INTEGER PRIMARY KEY," + KEY_NAME + " TEXT," + KEY_PH_NO + " TEXT" + ")";
db.execSQL(CREATE_CONTACTS_TABLE);
}
// Adding new contact
// This is what I don't understand. Why don't they get an ID for the contact.
// They only have values for the name and phone number when they insert it into the table.
public void addContact(Contact contact)
{
SQLiteDatabase db = this.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(KEY_NAME, contact.getName()); // Contact Name
values.put(KEY_PH_NO, contact.getPhoneNumber()); // Contact Phone Number
// Inserting Row
db.insert(TABLE_CONTACTS, null, values);
db.close(); // Closing database connection
}
Here's another example but this is using a book.
A book has 3 attributes, an id (the primary key), an author and the book name. And once again, they don't get the value for the primary key.
public void addBook(Book book)
{
Log.d("addBook", book.toString());
// 1. get reference to writable DB
SQLiteDatabase db = this.getWritableDatabase();
// 2. create ContentValues to add key "column"/value
ContentValues values = new ContentValues();
values.put(KEY_TITLE, book.getTitle()); // get title
values.put(KEY_AUTHOR, book.getAuthor()); // get author
// 3. insert
db.insert(TABLE_BOOKS, // table
null, //nullColumnHack
values); // key/value -> keys = column names/ values = column values
// 4. close
db.close();
}
because primary key is Autoincrement as it is an alias for ROWID.
from the documentation:
In SQLite, table rows normally have a 64-bit signed integer ROWID
which is unique among all rows in the same table. (WITHOUT ROWID
tables are the exception.)
You can access the ROWID of an SQLite table using one the special
column names ROWID, ROWID, or OID. Except if you declare an ordinary
table column to use one of those special names, then the use of that
name will refer to the declared column not to the internal ROWID.
If a table contains a column of type INTEGER PRIMARY KEY, then that
column becomes an alias for the ROWID. You can then access the ROWID
using any of four different names, the original three names described
above or the name given to the INTEGER PRIMARY KEY column. All these
names are aliases for one another and work equally well in any
context.
When a new row is inserted into an SQLite table, the ROWID can either
be specified as part of the INSERT statement or it can be assigned
automatically by the database engine. To specify a ROWID manually,
just include it in the list of values to be inserted. For example:
so in the examples you have given id is being assigned by database engine. for most of the use cases this is good enough.
You can create the table like
static final String DATABASE_CREATE = "create table "+TABLE_NAME+"( ID integer primary key autoincrement,user_name text,user_phone text,user_email text); ";
Then it will increment automatically
See this link http://www.freakyjolly.com/android-sqlite-integration/
http://www.freakyjolly.com/android-sqlite-how-to-insert-rows-in-database/

Delete specific record in sqlite table based on two criteria: _id and column

I have created a sqlite table for my android app, this table has 5 columns and multiple rows, the columns being: _id, column1, column2, column3, column4.
I want to delete a specific record, for instance the record stored in column3 corresponding to _id (in a different class are the getters and setters, for this I've named the class "TableHandler")
I guess that I'm a bit confused, following is what I was planning, but for column3 I'm not sure what should be the argument, I just want to delete whatever is in that column position corresponding to _id
public void deleteValueColumn3(TableHandler value){
SQLiteDatabase db = this.getWritableDatabase();
db.delete(TABLE_NAME, KEY_ID + " = ? AND " + KEY_COLUMN3 + " = ?",
new String[] {String.valueOf(value.getID()), ?????????);
db.close();
}
The ???????? is that I'm stuck there, maybe the whole method needs to be rewritten, I would appreciate your input.
Thanks
If you want to delete the whole record, just use the _id of the record in delete method, because that is the primary key for your table and therefore is unique. If you'd rather keep the record, you con always use the SQLiteDatabase.update method, specifying null as the new value that will replace column3 value; check out that column3 declaration has no NOT NULL tag, otherwise that could easily throw exception at you.
SQLite does not allow you to delete columns for a specific row.
You can only delete ROWS of data (delete the row that has the column _ID = 1).
Here's a quick tutorial on SQL.
How about updating that column with a null value, rather than using delete()?
ContentValues cv = new ContentValues();
cv.putNull(KEY_COLUMN3);
db.getWritableDatabase().update(
TABLE_NAME,
cv,
KEY_ID + "=?",
new String[]{String.valueOf(keyIdValue)});

Insert in SQLiteOpenHelper dosen't work correctly

I have a problem with SQLite in android , I tried a simple insert in a table but I have an exception and in the exception I read this :
INSERT INTO Biblio(Auteur,Image,Livre) VALUES (?,?,?)
this is my method :
public void AddBook(Bibliothèque bibliothèque)
{
SQLiteDatabase db=this.getWritableDatabase();
//this.open();
ContentValues values=new ContentValues();
values.put(KEY_Auteur,bibliothèque.getNomAuteur());
values.put(KEY_Livre,bibliothèque.getNomLivre());
values.put(Key_photo,bibliothèque.geturiimage().toString());
db.insert("Biblio",null,values);
db.close();
}
and this is my variables:
private static final String TABLE_Nom = "Biblio";
private static final String KEY_ID = "id";
private static final String KEY_Auteur = "Auteur";
private static final String KEY_Livre = "Livre";
private static final String Key_photo="Image";
the problem I don't know why but db.insert invert beetween Image and Livre and because of that I have an exception and I don't know why the value that I insert are ? ? ? in debug I can see that the value are correct ! . normaly the true expression must be :
INSERT INTO Biblio(Auteur,Livre,Image) VALUES (cc,test,(uri of picture))
this is the entire exception :
2927-2927/com.example.myapplication4.app E/SQLiteLog﹕ (1) table Biblio has no column named Livre
05-15 02:53:54.436 2927-2927/com.example.myapplication4.app E/SQLiteDatabase﹕ Error inserting Auteur=gsopfkgop Image=content://media/external/images/media/10 Livre=fhoksgkp
android.database.sqlite.SQLiteException: table Biblio has no column named Livre (code 1): , while compiling: INSERT INTO Biblio(Auteur,Image,Livre) VALUES (?,?,?)
USE This Query to Create Table.
db.execSQL
("CREATE TABLE Biblio (id INTEGER PRIMARY KEY AUTOINCREMENT ,Auteur TEXT,Livre TEXT,Image TEXT)");
then You have to insert record using Below code:
public void AddBook(Bibliothèque bibliothèque)
{
SQLiteDatabase db=this.getWritableDatabase();
//this.open();
ContentValues values=new ContentValues();
values.put(Auteur,bibliothèque.getNomAuteur());
values.put(Livre,bibliothèque.getNomLivre());
values.put(Image,bibliothèque.geturiimage().toString());
db.insert("Biblio",null,values);
db.close();
}
I hope its useful to you..
2927-2927/com.example.myapplication4.app E/SQLiteLog﹕ (1) table Biblio has no column named Livre
Your table doesn't have a column named Livre, either you have a spelling mistake here, in your table creation code, or you haven't defined a column named Livre.
You should try to reinstall your app?
Also, if your db schema has been changed after your app installed in your test device, you have to increase db version parameter to invoke onUpdate() method or reinstall your app to invoke onCreate().

Categories

Resources