I get this error on a device, while it works good on another device. Here is the error :
Caused by: android.database.sqlite.SQLiteException: not an error
at android.database.sqlite.SQLiteQuery.nativeFillWindow(Native Method)
at android.database.sqlite.SQLiteQuery.fillWindow(SQLiteQuery.java:86)
at android.database.sqlite.SQLiteCursor.fillWindow(SQLiteCursor.java:164)
at android.database.sqlite.SQLiteCursor.getCount(SQLiteCursor.java:156)
at com.Orange.MakeVisits.Themes.onCreate(Themes.java:162)
I execute a query and at the line that checks if the Cursor is null, I get this error. Here is my code :
String stmtGetThemes = "SELECT * FROM pr_fields_descriptor a "
+ "inner join pr_fields_starring b on a.id_fields_descriptor = b.fields_descriptor_id "
+ "where b.starring_id = '"+pos_starring_id+"' and a.theme_id='"+themes_ids[m]+"' order by form_rank";
Cursor getThemesCursor1 = db.databaseQuery(stmtGetThemes);
if (getThemesCursor1!=null && getThemesCursor1.getCount()>0){
//----
}
and databasequery is this method (is defined in the class that extends SQLiteOpenHelper):
public Cursor databaseQuery(String stmt) {
Cursor cursor = db.rawQuery(stmt, null);
return cursor;
}
Any idea what can cause this error ? The statement is not good ? Why it works on others devices?
Any idea is welcome. Thanks in advace.
String stmtGetThemes = "SELECT * FROM pr_fields_descriptor a "
+ "inner join pr_fields_starring b on a.id_fields_descriptor = b.fields_descriptor_id "
+ "where b.starring_id = '"+pos_starring_id+"' and a.theme_id='"+themes_ids[m]+"' order by form_rank";
Do not terminate this query by ";".
Don't Pass array Type Paramters in Query, sometimes it won't work
int themes_id = themes_ids[m];
String stmtGetThemes = "SELECT * FROM pr_fields_descriptor a inner join pr_fields_starring b on a.id_fields_descriptor = b.fields_descriptor_id where b.starring_id = '"+pos_starring_id+"' AND a.theme_id = '"+themes_id+"' ORDER BY form_rank";
Cursor getThemesCursor1 = db.databaseQuery(stmtGetThemes);
if (getThemesCursor1 != null && getThemesCursor1.getCount() != 0){
//----
}
Related
I have two method's in my SQLite Database in which i check if there is in a table certain column that is the same as a String after it i print all other columns on the same row and with the second method i check if a column from the first method equals to a data stored in a column of another table.
But i'm having issues when i check for a data that is not in the database here is an example:
TABLE CODART_BARCODE
CODART_CODART CODART_BARCODE CODART_PXC
123 1234 1
TABLE CODART_ART
DESCR_ART PVEN_ART PACQ_ART CODART_ART
PIZZ 1.50 12 123
So if in an EditText i insert 123 that equals to CODART_CODART and there is also 123 in CODART_ART from the other table i will print "PIZZ 1.50 12" but if i insert in the EditText 12356 the app crash because there is no same data in DB how can i prevent that app crash? i mean if there is no same data can i make a Toast that says "no data" or something like this but not making the app crash?
Here are the two methods from DB:
public String dbRawSearch(String id) {
StringBuilder dbString = new StringBuilder();
SQLiteDatabase db = this.getWritableDatabase();
String query = "SELECT * FROM " + TABLE_CODART + " WHERE CODART_BARCODE = " + id;
//Cursor points to a location in your results
#SuppressLint("Recycle") Cursor c = db.rawQuery(query, null);
//Move to the first row in your results
c.moveToFirst();
//Position after the last row means the end of the results
while (!c.isAfterLast()) {
if (c.getString(c.getColumnIndex("CODART_BARCODE")) != null) {
dbString.append(c.getString(c.getColumnIndex("CODART_CODART"))).append("\n");
dbString.append(c.getString(c.getColumnIndex("CODART_BARCODE"))).append("\n");
dbString.append(c.getString(c.getColumnIndex("CODART_PXC"))).append("\n");
}
c.moveToNext();
}
db.close();
return dbString.toString();
}
// FETCH codArt from Articoli
public String dbRawArticoli(String id){
StringBuilder dbString = new StringBuilder();
SQLiteDatabase db = this.getWritableDatabase();
String query = "SELECT * FROM " + TABLE_ART + " WHERE CODART_ART = " + id;
Cursor c = db.rawQuery(query, null);
c.moveToFirst();
while (!c.isAfterLast()) {
if (c.getString(c.getColumnIndex("CODART_ART")) != null) {
dbString.append(c.getString(c.getColumnIndex("DESCR_ART"))).append("\n");
dbString.append(c.getString(c.getColumnIndex("PVEN_ART"))).append("\n");
dbString.append(c.getString(c.getColumnIndex("PACQ_ART"))).append("\n");
}
c.moveToNext();
}
db.close();
return dbString.toString();
}
Your issue is that you are not correctly enclosing the search argument and thus if the value is non numeric then SQLite will consider that you are comparing a column, hence the no column found.
Lets say assuming you use :-
String result1 = yourdbHelper.dbRawSearch("123");
Then the resultant SQL will be :-
SELECT * FROM CODART WHERE CODART_BARCODE = 123;
That is fine as the search is looking for a number.
However if you used:-
String result1 = yourdbHelper.dbRawSearch("Fred");
Then the resultant SQL will be :-
SELECT * FROM CODART WHERE CODART_BARCODE = FRED
This would fail because FRED is non-numeric, and is therefore interpreted as saying SELECT all columns from the table CODART where the column named COADRT has the same value as the column named FRED, there is no column named FRED.
The result is that you get an error along the lines of :-
06-11 11:34:12.653 1373-1373/soanswers.soanswers E/AndroidRuntime: FATAL EXCEPTION: main
java.lang.RuntimeException: Unable to start activity ComponentInfo{soanswers.soanswers/soanswers.soanswers.MainActivity}: android.database.sqlite.SQLiteException: no such column: FRED (code 1): , while compiling: SELECT * FROM CODART WHERE CODART_BARCODE = FRED
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2059)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2084)
at android.app.ActivityThread.access$600(ActivityThread.java:130)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1195)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4745)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
at dalvik.system.NativeStart.main(Native Method)
The Fix
The resolution is simple, and that is to enclose the argument being searched for in single quotes so that the SQL is then :-
SELECT * FROM CODART WHERE CODART_BARCODE = 'FRED'
Note that is just one example. However you will need to makes similar changes to both methods (dbRawSearch and dbRawArticoli), as shown :-
To do this you could change :-
String query = "SELECT * FROM " + TABLE_CODART + " WHERE CODART_BARCODE = " + id;
to :-
String query = "SELECT * FROM " + TABLE_CODART + " WHERE CODART_BARCODE = '" + id + "'";
and also change :-
String query = "SELECT * FROM " + TABLE_ART + " WHERE CODART_ART = " + id;
to :-
String query = "SELECT * FROM " + TABLE_ART + " WHERE CODART_ART = '" + id + "'";
Additional
However, there are SQLiteDatabase convenience methods that simplify building queries which also enclose/convert data accordingly.
One of these is the query method (as used in the following).
Rather than
moving to the first row and then
checking to see if you are then at the last row and then
using a moveToNext then going back to 2
in a do while loop, as all of the Cursor move??? methods return
true if the move could be made
otherwise false
you can simplify matters using :-
while(yourcursor.moveToNext) {
.... process the current row
}
As such the following methods could be considered
Note the 2 at the end of the method name is just to distinguish them from the originals
:-
public String dbRawSearch2(String id) {
StringBuilder dbString = new StringBuilder();
String whereclause = "CODART_BARCODE=?";
String[] whereargs = new String[]{id};
SQLiteDatabase db = this.getWritableDatabase();
Cursor c = db.query(TABLE_CODART,null,whereclause,whereargs,null,null,null);
while (c.moveToNext()) {
dbString.append(c.getString(c.getColumnIndex("CODART_CODART"))).append("\n");
dbString.append(c.getString(c.getColumnIndex("CODART_BARCODE"))).append("\n");
dbString.append(c.getString(c.getColumnIndex("CODART_PXC"))).append("\n");
}
c.close(); //<<<< Should always close cursors when finished with them
db.close();
return dbString.toString();
}
public String dbRawArticoli2(String id) {
StringBuilder dbString = new StringBuilder();
String whereclause = "CODART_ART=?";
String[] whereargs = new String[]{id};
SQLiteDatabase db = this.getWritableDatabase();
Cursor c= db.query(TABLE_ART,null,whereclause,whereargs,null,null,null);
while (c.moveToNext()) {
dbString.append(c.getString(c.getColumnIndex("DESCR_ART"))).append("\n");
dbString.append(c.getString(c.getColumnIndex("PVEN_ART"))).append("\n");
dbString.append(c.getString(c.getColumnIndex("PACQ_ART"))).append("\n");
}
c.close();
db.close();
return dbString.toString();
}
you should use wether your cursor is null or not and its size
if (c != null) {
if (c.getCount() > 0) {
return "your string";
}
}
return "";// In case no record found
In blank case give proper msg to the end user.
Change this part :
//Move to the first row in your results
c.moveToFirst();
//Position after the last row means the end of the results
while (!c.isAfterLast()) {
if (c.getString(c.getColumnIndex("CODART_BARCODE")) != null) {
dbString.append(c.getString(c.getColumnIndex("CODART_CODART"))).append("\n");
dbString.append(c.getString(c.getColumnIndex("CODART_BARCODE"))).append("\n");
dbString.append(c.getString(c.getColumnIndex("CODART_PXC"))).append("\n");
}
c.moveToNext();
}
To :
//Move to the first row in your results
if(c!= null && c.moveToFirst())
{
//Position after the last row means the end of the results
while (!c.isAfterLast()) {
if (c.getString(c.getColumnIndex("CODART_BARCODE")) != null) {
dbString.append(c.getString(c.getColumnIndex("CODART_CODART"))).append("\n");
dbString.append(c.getString(c.getColumnIndex("CODART_BARCODE"))).append("\n");
dbString.append(c.getString(c.getColumnIndex("CODART_PXC"))).append("\n");
}
c.moveToNext();
}
}
Explanation: In the case where there is no same data available you don't have the result set to get the string or column index from the result set.
I try to get all unique values from database coulmn using SELECT DISTINCT sql command.
But i get exception when my activity is loading, i have this error code in logcat:
05-05 09:08:32.637: E/AndroidRuntime(1314): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.workoutlog/com.example.workoutlog.AddWorkOutPage}: android.database.sqlite.SQLiteException: near "SELECT": syntax error (code 1): , while compiling: SELECT * FROM exerciseTable WHERE SELECT DISTINCTexercise_typefromexerciseTable
I think that i have not wrote the command correctly, here is my code:
public String[] getAllExercies() {
String selecet = "SELECT DISTINCT" + COLUMN_EXERCISE + "from" + TABLE_NAME;
Cursor c = ourDatabase.query(TABLE_NAME, null, selecet, null, null, null, null);
int dayExercise = c.getColumnIndex(COLUMN_EXERCISE);
String[] list = new String[c.getCount()-1];
int j = 0;
for (c.moveToFirst(); !c.isAfterLast(); c.moveToNext()){
list[j] = c.getString(dayExercise);
j++;
}
return list;
}
I think you should first checkout these answers here and here in order to see the working of .query() function.
Please note that while using ourDatabase.query() function, the parameters are as follows:
String Table Name: The name of the table to run the query against
String [ ] columns: The projection of the query, i.e., the columns to retrieve
String WHERE clause: where clause, if none then pass null
String [ ] selection args: The parameters of the WHERE clause
String Group by: A string specifying group by clause
String Having: A string specifying HAVING clause
String Order By by: A string Order By by clause
So your third variable should be a WHERE clause, something like:
String[] args = { "first string" };
Cursor c = ourDatabase.query("TABLE_NAME", null, "exercise_type=?", args, null, null, null);
Since you don't need a WHERE clause, for your purposes you might want to use rawQuery() method instead.
String selecet = "SELECT DISTINCT " + COLUMN_EXERCISE + " FROM " + TABLE_NAME;
ourDatabase.rawQuery(selecet, null);
Update
Try the answer from here. Do something like this:
Cursor c = ourDatabase.query(true, "exerciseTable", new String[] {"exercise_type"}, null, null, "exercise_type", null, null, null);
int dayExercise = c.getColumnIndex(COLUMN_EXERCISE);
//... continue with your further code
Hope this helps else please comment.
Issue:
you have not maintained the space between the words.
Explaination:
suppose, String COLUMN_EXERCISE = "exercise";
and String TABLE_NAME = "tbl_workout";
then
String selecet = "SELECT DISTINCT" + COLUMN_EXERCISE + "from" + TABLE_NAME;
simply means,SELECT DISTINCTexercisefromtbl_workout
Solution:
String selecet = "SELECT DISTINCT " + COLUMN_EXERCISE + " from " + TABLE_NAME;
Edit:
Kindly use following syntax to fire rawQuery
Cursor c = ourDatabase.rawQuery(selecet,null);
I hope it will be helpful !
You miss all the spaces in your query, you should replace with this:
String selecet = "SELECT DISTINCT " + COLUMN_EXERCISE + " FROM " + TABLE_NAME;
In my application, store the amount details of company in my sq lite DB.For example om my first position of DB in name column-company 1,total column - 400,second position of DB in name column-company 2,total column - 800,third position of DB in name column-company 1,total column - 500.how Sum the company 1 details only to return the total amount.
My main coding is,
String str = db.company_amount("Company 1");
Log.v("Total", ""+str);
My DB coding is,
String company_amount(String name){
SQLiteDatabase db = this.getReadableDatabase();
String s = "";
Cursor cursor = db.rawQuery("SELECT SUM(KEY_AMOUNT) FROM TABLE_BILL_DETAILS WHERE = ?", new String[] {String.valueOf(name)});
if (cursor != null) {
if (cursor.moveToNext()) {
s = cursor.getString(1);
return cursor.getString(1);
}
cursor.close();
}
return s;
}
It shows some error,I don't know how to return the values.Can any one know please help me to solve this problem.
My Logcat Error
04-25 14:54:06.701: E/AndroidRuntime(2776): FATAL EXCEPTION: main
04-25 14:54:06.701: E/AndroidRuntime(2776): java.lang.RuntimeException: Unable to start activity
ComponentInfo{invoicebill.details/invoicebill.details.Total_company_details}: android.database.sqlite.SQLiteException: near "=": syntax error: , while compiling: SELECT SUM(KEY_AMOUNT) FROM TABLE_BILL_DETAILS WHERE = ?
SQLiteDatabase db = getReadableDatabase();
String sql = "SELECT SUM(KEY_AMOUNT) FROM TABLE_BILL_DETAILS WHERE name = ?";
long sum = android.database.DatabaseUtils.longForQuery(db, sql, new String[]{name});
WHERE = ?
This is incorrect SQL syntax. You forgot to specify which field you're comparing with the argument. I guess it's name or something similar, so correct syntax would be something like:
WHERE name = ?
you can use to get details using id like this.
public int getTotalOfAmount(int id) {
odb = dbh.getReadableDatabase();
Cursor c = odb.rawQuery("SELECT SUM(" + KEY_AMOUNT + ") FROM " + DATABASE_TABLE + " WHERE " + KEY_ID + " = " + id, null);
c.moveToFirst();
int i = c.getInt(0);
c.close();
return i;
}
.
I've got a problem with my Android application. I'm trying to query database with multiple tables and display the result in the application. It's a dictionary. The problem is my query doesn't work. I have no clue what I'm doing wrong.
Here is a sample of my code that I use for it. If you need any more information, just let me know.
Thank You.
try {
Cursor cursor = dictionary.getDictionaryDatabase().rawQuery("SELECT index_nom_adresse" + word[0].toLowerCase().trim() + " FROM adresse_definition JOIN definition ON adresse_definition.definition = definition.data_id ", null);
//Cursor cursor = dictionary.getDictionaryDatabase().query("adresse_definition", null, "index_nom_adresse= '" + word[0].toLowerCase().trim() + "' or definition= '" + word[0].toUpperCase().trim() + "' ", null, null, null, null);
cursor.moveToFirst();
if (cursor.getCount() != 0) {
if (word[1] == null || word[1].equals("English")) {
translatedWord = cursor.getString(2);
} else {
translatedWord = cursor.getString(1);
}
} else {
translatedWord = "The word is not in database";
}
cursor.close();
} catch (SQLiteException sqle) {
translatedWord = "The word is not in database";
}
here is a logCat i get when trying to search for word
03-20 14:34:17.341: I/SqliteDatabaseCpp(516): sqlite returned: error code = 1, msg = no such column: index_nom_adressebonbon, db=/data/data/com.example.application/databases/dict.db
The query should be:
Cursor cursor = dictionary.getDictionaryDatabase().rawQuery("SELECT index_nom_adresse" + word[0].toLowerCase().trim() + " FROM adresse_definition JOIN definition ON adresse_definition.definition = definition.data_id ", null);
otherwise the coulmn is not defined correctly.
First of all, your hiding the real error by catching the Exception and then say "the word is not in the database'.
The problem your likely to have, which is just a guess because of the limited amount of information you are giving, is passing the word in the SELECT, instead of in the WHERE clause.
Likely your SQL query needs to be something like this:
SELECT index_nom_adresse
FROM adresse_definition
JOIN definition ON adresse_definition.definition = definition.data_id
WHERE index_nom_adresse = word[0].toLowerCase().trim() OR definition = word[0].toUpperCase().trim()
This translates to:
String sql = "SELECT index_nom_adresse ";
sql += "FROM adresse_definition JOIN definition ON adresse_definition.definition = definition.data_id ";
sql += "WHERE index_nom_adresse = " + word[0].toLowerCase().trim() " OR definition=" + word[0].toUpperCase().trim();
Cursor cursor = dictionary.getDictionaryDatabase().rawQuery(sql, null);
or (a better solution) (No clue how you would do the join, is the JOIN needed?)
Cursor cursor = dictionary.getDictionaryDatabase().query(
"adresse_definition",
new String[] {"index_nom_adresse"},
"index_nom_adresse= ? OR definition=?'",
new String[] {word[0].toLowerCase().trim(), word[0].toUpperCase().trim()},
null,
null,
null);
Please read up on Android and SQL: http://www.vogella.com/articles/AndroidSQLite/article.html
I have no tools here to validate the code, please comment or edit if there are errors.
I am trying to get one specific entry out of my DB with following code:
Object specificObject = myDbHelper.getObject(int id, int level);
// code in DataBaseHelper:
public Object getObject(int id, int level){
c = myDataBase.rawQuery("SELECT * FROM QUESTIONS WHERE ID =" + id + " AND LEVEL = " + level, null);
Object q = new Object();
q.setQuestion(c.getString(1));
q.setName(c.getString(2));
q.setFile(c.getInt(3));
q.setAnswer(c.getString(4));
return q;
}
The problem is this results in following error:
09-24 11:12:52.299: E/AndroidRuntime(7388): Caused by: android.database.CursorIndexOutOfBoundsException: Index -1 requested, with a size of 1
Any ideas? It seems that it knows that it has a size of one (one entry?) but i don't get the index -1 requested issue...
Before accessing data from cursor you have to move first record.
c.moveToFirst()
You should do it like:
c = myDataBase.rawQuery("SELECT * FROM QUESTIONS WHERE ID =" + id + " AND LEVEL = " + level, null);
if(c.moveToFirst()) {
Object q = new Object();
q.setQuestion(c.getString(1));
q.setName(c.getString(2));
q.setFile(c.getInt(3));
q.setAnswer(c.getString(4));
return q;
}
return null;