SQLite Java Android no such table, program crashes - java

I'm trying to make database for my program and I'm having a lot of dumb problems...
It's fragment of main activity:
Database db = new Database(this,editText.getText().toString());
String text = db.printRow();
textView.setText(text);
Now database class:
String nickname="EmptyNick";
public Database(Context context, String name) {
super(context, "database.db", null, 1);
nickname = name;
}
public void onCreate(SQLiteDatabase db) {
if(!nickname.equals("EmptyNick")) {
db.execSQL("create table player(id integer primary key autoincrement,nick text);");
Users user = new Users();
user.setNick("Mariusz");
addPlayer(user);
}
else {
//not important
}
}
private void addPlayer(Users user) {
SQLiteDatabase db = getWritableDatabase();
ContentValues values = new ContentValues();
values.put("nick",user.getNick());
db.insertOrThrow("player",null,values);
}
public String printRow() {
String string=null;
if(!nickname.equals("EmptyNick")) {
String[] collumns = {"id","nick"};
SQLiteDatabase db = getReadableDatabase();
Cursor cursor = db.query("player",collumns,null,null,null,null,null);
cursor.moveToFirst();
while (cursor.moveToNext()) {
string += cursor.getString(1);
}
}
else {
//not important
}
return string;
}
Errors:
no such table: player
Caused by: java.lang.reflect.InvocationTargetException
Caused by: android.database.sqlite.SQLiteException: no such table: player (code 1): , while compiling: SELECT id, nick FROM player
I really can't see what's wrong. Error says there is no table 'player', but it is. On the beggining of onCreate methon in line:
db.execSQL("create table player(id integer primary key autoincrement,nick text);");
Can somebody help me? If I make Toast instead of text.setText(...) it shows me empty field, so yes, it can't create specific row. I understand the error, but do not from where and why it comes.

The table you try to use does not exist. In such cases it is generally a good idea to check the database you are using and check whether the table exists. In this particular case it seems that you create the table if a condition is met. The condition is that your nickname's value differs from the default value. However, it does not differ. Make sure that you use a table if and only if it exists and you have the correct condition for creating the table.

I don't really understand your problem. If there is an error, it will throw an ANR message, how can you print the toast and it shows the empty? and the Toast showed empty because you add only one record of data to your table, then in your printRow(), you called cursor.moveToFirst, then you call while(cursor.moveToNext()) which will move your cursor to second row and it will return false since you only have 1 record.

Related

SQLite database cursor is returning the wrong resource IDs

I'm trying to use references to drawable and String resources from a SQLite database to display the appropriate resources in a fragment. I have a database helper file to populate the database, a database utilities file to create a cursor (or just get the cursor data in an array), and the fragment file.
DatabaseHelper.java
DatabaseHelper(Context context) {
super(context, DB_NAME, null, DB_VERSION);
}
private void updateMyDatabase(SQLiteDatabase db, int oldVersion, int newVersion) {
if (oldVersion == 1) {
db.execSQL("CREATE TABLE FOOD (_id INTEGER PRIMARY KEY AUTOINCREMENT, "
+ "NAME TEXT, "
+ "IMAGE_RESOURCE_ID INTEGER, "
+ "QUOTE INTEGER);");
insertFood(db,"Alcohol", R.drawable.alcohol, R.string.symptom9);
}
private static void insertFood(SQLiteDatabase db, String name, int toxicity, int resourceId, int quote){
ContentValues foodValues = new ContentValues();
foodValues.put("NAME", name);
foodValues.put("TOXICITY", toxicity);
foodValues.put("IMAGE_RESOURCE_ID", resourceId);
foodValues.put("QUOTE", quote);
db.insert("FOOD", null, foodValues);
}
}
Here, R.drawable.alcohol = 2131099733
I'm using Android Studio and when I mouse over the values I'm adding to the database and display a drawable using one of those values, it's the correct drawable, but when I request a cursor (or array based on the cursor), the value that the cursor includes is completely different from the value stored in the database and produces a resource not found error.
I tried returning a data array from the helper method, but that also gave incorrect integer references for the drawables and strings so, I'm returning the cursor from the helper method instead:
DatabaseUtilities.java
//get all of the database data for a particular food given that food's name
public static Cursor getFoodById(Context context, long itemId){
try {
SQLiteOpenHelper DatabaseHelper = new DatabaseHelper(context);
SQLiteDatabase db = DatabaseHelper.getReadableDatabase();
return db.query(DatabaseHelper.FOOD,
new String[]{
DatabaseHelper.NAME, DatabaseHelper.IMAGE_RESOURCE_ID,
DatabaseHelper.QUOTE},
"_id = ?", new String[] {Long.toString(itemId)}, null, null, null
);
} catch (SQLiteException e) {
//TODO Add toast - food not available
return null;
}
}
Finally, I'm trying to display the values here:
DetailFragment.java
#Override
public void onViewCreated(#NonNull View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
Cursor items = DatabaseUtilities.getFoodById(getActivity(), itemId);
if(items.moveToFirst()) {
//set appropriate img
int img = items.getInt(1);
ImageView photo = (ImageView) view.getRootView().findViewById(R.id.detail_photo);
photo.setImageResource(img);
int quote = items.getInt(2);
TextView desc = (TextView) view.getRootView().findViewById(R.id.detail_text);
String descText = getString(quote);
desc.setText(descText);
}
}
This is log output of all of the cursor columns from the last file:
DetailFragment - cursor: Alcohol, 2131165269, 2131558463
The value after Alcohol should be R.drawable.alcohol, 2131099733, but the cursor returns 2131165269 instead. The same is the case with the string reference after the drawable reference. Also, the cursor returns different values for each inserted row, they're just the wrong values and I don't know where they're coming from or if there's a way to convert them to the correct values.
Everything in the program works except that the database doesn't return the correct resource references.
Don't store in the table the integer ids of resources.
Their values are not guaranteed to be the same every time you make changes in the resources and recompile your project.
Instead store the resource ids as string literals.
So change the table's definition to:
CREATE TABLE FOOD (_id INTEGER PRIMARY KEY AUTOINCREMENT, "
+ "NAME TEXT, "
+ "IMAGE_RESOURCE_ID TEXT, "
+ "QUOTE TEXT);
Now store in the columns IMAGE_RESOURCE_ID and QUOTE the string ids.
When you retrieve such a string id from the table by using a cursor, you can get its integer id this way:
int drawableId = getResources().getIdentifier(drawableString, "drawable", getPackageName());
int stringId = getResources().getIdentifier(stringString, "string", getPackageName());
You may need to provide a valid Context to getResources() and getPackageName(), like:
context.getResources().getIdentifier(drawableString, "drawable", context.getPackageName());
Replace drawableString and stringString with the values you retrieved from the table for the image and the string.
If you make the above proposed changes in the definition of the table, you must uninstall the app from the device/emulator and rerun so the database is deleted and recreated with the new definition of the table.

Can't add row to DB using ContentValues.insert() Android Studio (SQLiteLog: (1) no such table: ....)

I'm newbie with Java and Android Studio.I'm currently trying to create a to do list application. For that, I need to store the user's input into a database. However I can create the database and the table without any problem. But each time I try to add new row into the database, an error occurs.
D/DatabaseHandler: ===Inside DatabaseHandler constructor===
D/DatabaseHandler: ===Inside onCreate from DatabaseHandler===
D/MainActivity: ==addToDatabase==
/SQLiteLog: (1) no such table: test_database
E/SQLiteDatabase: Error inserting STATE=14 TASK=13 ID =1
android.database.sqlite.SQLiteException: no such table: test_database (code 1): , while compiling: INSERT INTO test_database(STATE,TASK,ID ) VALUES (?,?,?)
create the database (DatabaseHandler) and create the table (onCreate()):
public class DatabaseHandler extends SQLiteOpenHelper {
public DatabaseHandler(Context context) {
super(context, "test_database", null, 1);
Log.d(TAG, "===Inside DatabaseHandler constructor===");
}
#Override
public void onCreate(SQLiteDatabase db) {
Log.d(TAG, "===Inside onCreate from DatabaseHandler===");
// String database_table = "CREATE TABLE task(" + COLUMN_ID + " INT NOT NULL," + COLUMN_TASK + " INT NOT NULL," + COLUMN_STATE + " INT NOT NULL)";
String database_table = "CREATE TABLE task(ID INT NOT NULL, TASK INT NOT NULL, STATE INT NOT NULL)";
db.execSQL(database_table);
}
}
and finally the function I used for add new row into the DB:
public int addToDatabase(SQLiteDatabase access, String task) {
Log.d(TAG, "==addToDatabase==");
if (access.isOpen() == false) {
Log.d(TAG, "[addToDatabase] Database is not Open");
return (-1);
}
ContentValues values = new ContentValues();
values.put("ID ", 1);
values.put("TASK", 13);
values.put("STATE", 14);
access.insert("test_database", null, values);
return (1);
I already try to solve the problem by myself by looking on the other existing post. It seem that it may be cause because the database wasn't create correctly. Nonetheless as you can there's any error while creating the database, only when I'm trying to add new stuff.
I also read that it could be in report with the version of the database...However, I don't really understand why..(I'm still looking into the official documentation).
Does anyone can explain me and tell me how can I fix the problem ?
Thanks :)
Use this
access.insert("task", null, values)
instead of this
access.insert("test_database", null, values);
or
if you have updated your app table name then uninstall your app manually and try running again.
Your table name is apparently wrong. Change the table creation query.
String database_table = "CREATE TABLE test_database(ID INT NOT NULL, TASK INT NOT NULL, STATE INT NOT NULL)";
This might help you Android Sqlite Database Tutorial
You may edit your "DatabaseHandler" and run the project so that the change in your database doesn't occur.
I simply removed data from the application, to be opened for the first time
and it worked for we:

RawQuery doesn't work when given null valueto args

I'm writing a basic android app in which personal information like name, email, etc. is filled in and stored in an SQLite database by pressing a "submit"-button (this all works perfectly). Then there's a search button which should search for a corresponding person in the database when one field is filled in (e.g. only the field name is given a string "harry" and the other fields keep a null-value). This is the corresponding code in my DatabaseHelper class:
public Person getPerson(String naam, String adres, String email, String geslacht,
String leeftijd, String geboortedatum){
Log.i("Main activity","Person to find: "+naam);
SQLiteDatabase db= this.getReadableDatabase();
Cursor curs=db.rawQuery("SELECT name FROM personen WHERE (name = ?) OR (adress = ?) "
+ "OR (email = ?) OR (gender = ?) OR (age = ?) OR (birthday = ?)",
new String[]{naam, adres, email, geslacht, leeftijd, geboortedatum});
Log.i("Main activity", "Query works");
I used the logs to make sure where the error is thrown and found that the rawQuery does work when all the args[] fields are given a value, but gives an error when one field (e.g. email) contains a null value. Isn't this why I should use the OR statement instead of the AND statement? If not, how can I make it work when not all fields are filled in in the app?
A fast fix should be to do something like that:
new String[]{naam == null? "''":naam, etc}
Check if your sting is initialized, if it is not, replace it by a dummy value.
rawQuery() expects a string array, but null is not a valid string.
You'd have to put the NULL directly into the SQL string, without a parameter.
But when you're constructing the string dynamically anyway, you can just as well leave out that comparison.
search by name:
// Getting single contact
Contact getContact(String name) {
SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor = db.query(TABLE_CONTACTS, new String[] { KEY_ID,
KEY_NAME, KEY_PH_NUM }, KEY_NAME + "=?",
new String[] { name }, null, null, null, null);
//...
for access:
Contact contact = null;
if (cursor.moveToFirst()) {
contact = new Contact(Integer.parseInt(cursor.getString(0)),
cursor.getString(1), cursor.getString(2));
}
cursor.close();
// can return null if no contact was found.
return contact;

Query Data from Existing SQLite Database Android

I followed this tutorial: http://www.reigndesign.com/blog/using-your-own-sqlite-database-in-android-applications/ Created db with SQLite Database Browser, put db file in "assets" folder etc..
Here my db structure created using SQLite Database Browser with instructions in tutorial link;
Then i added this method to end of DataBaseHelper class;
public ArrayList<market> getMarkets() {
String table = "markets";
ArrayList<market> markets = new ArrayList<market>();
market mrkt = new market();
SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor = db.rawQuery("SELECT * FROM " + table, null);
if(cursor.moveToFirst()) {
cursor.moveToNext();
do {
mrkt.market_id = cursor.getInt(cursor.getColumnIndex("marketid"));
mrkt.market_name = cursor.getString(cursor.getColumnIndex("name"));
mrkt.market_telno = cursor.getInt(cursor.getColumnIndex("telno"));
mrkt.market_location = cursor.getString(cursor.getColumnIndex("location"));
mrkt.market_hours = cursor.getString(cursor.getColumnIndex("hours"));
markets.add(mrkt);
}while(cursor.moveToNext());
}
cursor.close();
db.close();
return markets;
}
and i try to show first market's informations on textview with these lines in activity class:
myDbHelper = new DataBaseHelper(this);
markets = new ArrayList<market>();
myDbHelper.createDataBase();
myDbHelper.openDataBase();
markets = myDbHelper.getMarkets();
id.setText(markets.get(0).getMarket_id());
name.setText(markets.get(0).getMarket_name());
telno.setText(markets.get(0).getMarket_telno());
loc.setText(markets.get(0).getMarket_location());
hours.setText(markets.get(0).getMarket_hours());
However i got logcat error:
04-12 23:40:24.477: E/SQLiteLog(30698): (1) no such table: markets
i checked data/data file and there is not my db file
i followed tutorial line by line but i dont know why i can not create table or sqlite database properly ?
i tried .db, .sqlite3 extensions.. if i'm wrong then what should be my db file extension ?
please help..
(note: i have cyanogenmod 11.0 on my phone)
I am not sure what is the problem but this code:
if(cursor.moveToFirst()) {
cursor.moveToNext();
do {
mrkt.market_id = cursor.getInt(cursor.getColumnIndex("marketid"));
mrkt.market_name = cursor.getString(cursor.getColumnIndex("name"));
mrkt.market_telno = cursor.getInt(cursor.getColumnIndex("telno"));
mrkt.market_location = cursor.getString(cursor.getColumnIndex("location"));
mrkt.market_hours = cursor.getString(cursor.getColumnIndex("hours"));
markets.add(mrkt);
}while(cursor.moveToNext());
}
skips the first row of the query. With cursor.moveToFirst() you are already pointing to the first row in the table, but you do additional cursor.moveToNext() which skips the first row, and goes to the second.
You didn't define a table. I'm assuming as it wasn't in the tutorial. This is the line and it should be after the DATABASE_NAME and DATABASE_VERSION, and before the lines to identify the columns:
public static final String TABLE_NAME = "markets";
If you fixed it with other code, please let me know! I've been working on somet

SQLite Cursor getColumnIndex() returning -16 even when column exists

I'm storing a number of objects for my app in an SQLite Database. The class for these objects has a constructor that takes a Cursor object, passed in from the Database class. Example:
public MyClass(Cursor cursor) {
this.id = cursor.getString(cursor.getColumnIndex(MyDatabase.KEY_ROWID));
this.nickname = cursor.getString(cursor.getColumnIndex(MyDatabase.KEY_NICKNAME));
...and so on.
However I've noticed that at random times I've been getting a crash when getColumnIndex for the ID column returns -16. (And if I comment out that line, whichever the first column I try to access is, it will also return -16). I've added some extra logging around it but it hasn't helped as it seems like the columns are fine:
public MyClass(Cursor cursor) {
Log.i("TEST", Column names are: " + Arrays.toString(cursor.getColumnNames()));
Log.i("TEST", Making object, id column index is " + cursor.getColumnIndex(MyDatabase.KEY_ROWID));
Which prints:
Column names are: [_id, nickname...]
Making object, id column index is -16
So it sees like everything should be fine, anyone got any clue why everything could be getting so messed up while reading from the Cursor?
EDIT: Here's how I'm getting the cursor, this is a method in the database class:
public MyObject getMyObject(String id) {
MyObject objectFound = null;
String[] whereArgs = { id };
Cursor cursor = db.query(true, getTableName(), null, WHERE_EQUALS, whereArgs, null, null, null, null);
if(cursor.moveToFirst()) {
//Should only return 1 entry from DB
while(cursor.isAfterLast() == false) {
objectFound = new MyObject(cursor);
cursor.moveToNext();
}
}
cursor.close();
return objectFound;
}

Categories

Resources