it gives me an error when I am using this key but when I use LENGTH, it works fine. I hope it is allowed on android sqlite coz it's the best way for this:
I am just trying to remove the spaces after words that will be selected from Database.
public ArrayList<String> getCorrectList() {
// TODO Auto-generated method stub
Cursor c = db.rawQuery("SELECT REPLACE(Level_1, ' ', '') FROM " + TABLE, null);
ArrayList<String> resultsList = new ArrayList<String>();
try {
if (c != null) {
if (c.moveToFirst()) {
do {
String levelData = c.getString(c
.getColumnIndex("Level_1"));
resultsList.add("" + c.getColumnIndex("Level_1"));
} while (c.moveToNext());
}
}
} catch (SQLiteException e) {
Log.e("Database", "Cannot get List (" + e + ")");
}
Log.d("array", "List: " + resultsList);
Collections.shuffle(resultsList);
return resultsList;
}
This works fine in SQLite3 shell:
e$ sqlite3
SQLite version 3.7.14.1 2012-10-04 19:37:12
Enter ".help" for instructions
Enter SQL statements terminated with a ";"
sqlite> create table t(a,b,c);
sqlite> select replace(a,' ', '') from t;
REPLACE is both a function and a command in SQLite3. Perhaps db.rawQuery is parsing the query and getting confused by REPLACE. Try this:
db.rawQuery("select rtrim(replace(Level_1, ' ', '')) FROM " + TABLE, null);
Related
Im trying to retrieve some data out of a database called Train_list When i try to do so m greeted with the error:
D/FinalĀ Error: android.database.CursorIndexOutOfBoundsException: Index 0 requested, with a size of 0
After a bit of googling And a bit of Trail and error i realized that the cursor was returning a null value So i Questioned if the data was actually being inserted into the database. So i Used a third party plugin ( Or what ever you want to call it ) to see if the data was indeed present in the Database
As You can see the database does indeed have three entries. Now when i Try to read the database with this code:
setContentView(R.layout.activity_display_data);
Bundle bundle = getIntent().getExtras();
no_name = (ListView) findViewById(R.id.Disp_list);
String message = bundle.getString("package");
String parameter;
SQLiteDatabase db = openOrCreateDatabase(message, SQLiteDatabase.CREATE_IF_NECESSARY, null);
SQLiteDatabase db1 = openOrCreateDatabase("Train_list.db", SQLiteDatabase.CREATE_IF_NECESSARY, null);
Cursor header;
namer=(TextView)findViewById(R.id.T1);
try {
header = db1.rawQuery("Select Train_name From Train_list Where Train_no='"+message.substring(0,(message.length()-3))+ "'", null);
header.moveToFirst();
String temp = header.getString((header.getColumnIndex("Train_name")));
Toast.makeText(Display_data.this, "blahhh:"+temp, Toast.LENGTH_LONG).show();
Log.d("Sucess!","temp:"+temp);
Toast.makeText(Display_data.this, "Gotcha:"+temp , Toast.LENGTH_LONG).show();
namer.setText("Train Name: " + temp);
header.close();
}catch(Exception e)
{
Log.d("Final Error",e.toString());
Toast.makeText(Display_data.this, "Error", Toast.LENGTH_LONG).show();
}
I get the aforementioned error. Some posts suggested adding a '?' but that didnt help either
Heres the code with which i inserted the data:
try {
final String CREATE_TABLE_TRAIN_LIST = "CREATE TABLE IF NOT EXISTS Train_list ("
+ "Train_name VARCHAR,"
+ "Train_no VARCHAR,"
+ "Train_start VARCHAR,"
+ "Train_end VARCHAR,"
+ "Seats_Available VARCHAR);";
db.execSQL(CREATE_TABLE_TRAIN_LIST);
Toast.makeText(admin_manipulation.this, "Table created", Toast.LENGTH_LONG).show();
String sql = "INSERT or replace INTO Train_list (Train_name, Train_no, Train_start, Train_end, Seats_Available) VALUES('"+str_Train_name + "',' " +str_Train_no + "', '" +str_Train_start+"','" +str_Train_end+"',' " +str_Train_seats +"');";
try {
db.execSQL(sql);
Toast.makeText(admin_manipulation.this, "train no:"+str_Train_no, Toast.LENGTH_SHORT).show();
}catch(Exception e)
{
Toast.makeText(admin_manipulation.this, "Sorry Not Inserted Sucessfully", Toast.LENGTH_SHORT).show();
Log.d("Error experienced",e.toString());
}
Any idea why this is happening?
Try checking by getting the cursor count for the query you have run. header.getCount() and then do the header.getString() only if there is data
if (header!= null && header.getCount() > 0){
header.moveToFirst();
// All the logic of retrieving data from cursor
}
This line in your code:
header = db1.rawQuery("Select Train_name From Train_list Where Train_no='"+message.substring(0,(message.length()-3))+ "'", null);
might throw problems depending on the message passed in.
If the Train_no is supposed to be the train numbers in your table, substringing - 3 looks like it will return only the "aa" portion. Then your rawQuery will look for a Train_no that is "aa".
Consider using the LIKE SQL syntax. This question is useful.
Your query may look like:
header = db1.rawQuery("Select Train_name From Train_list Where Train_no like '"+message.substring((message.length()-3), message.length())+ "'", null);
Currently We have one application in which we are receiving many crash reports while deleting record from database .
Here is method in which app is crashing.
public int deleteGroupMap(String nickName) {
SQLiteDatabase database = this.getWritableDatabase();
try {
return database.delete(TABLE_NAME_GROUP_MAP, COLUMN_GMAP_NICK_NAME + " = '" + nickName + "'", null);
} catch (Exception e) {
e.printStackTrace();
} finally {
database.close();
}
return 0;
}
but we am getting following exception:
android.database.sqlite.SQLiteException: near "adz": syntax error
(code 1): , while compiling: DELETE FROM groups_map WHERE
gmap_nick_name = ''adz.'
Any help will be appreciated.
Look at delete signature:
int delete (String table, String whereClause, String[] whereArgs)
Third argument is where args:
You may include ?s in the where clause, which will be replaced by the
values from whereArgs. The values will be bound as Strings.
It's automatically escaped, so there is no need to put quotes (', ") manually.
Use where args instead of strings concating:
database.delete(TABLE_NAME_GROUP_MAP, COLUMN_GMAP_NICK_NAME + " = ?", new String[] { nickName });
Try Like This
public int deleteGroupMap(String nickName) {
SQLiteDatabase database = this.getWritableDatabase();
try {
database .execSQL("DELETE FROM "+ TABLE_NAME_GROUP_MAP + " WHERE " + COLUMN_GMAP_NICK_NAME + " = "+nickName+"");
database .close();
} catch (Exception e) {
e.printStackTrace();
} finally {
database.close();
}
return 0;
}
Try this
return database.delete(TABLE_NAME_GROUP_MAP, COLUMN_GMAP_NICK_NAME + "= ?" , new String[]{Long.toString(nickName)});
You should also use parameter markers because appending values directly is error prone when the source contains special characters.
try following because it will also prevent SQL injections to your app
database.delete(TABLE_NAME_GROUP_MAP, COLUMN_GMAP_NICK_NAME + "=?", new String[]{String.valueOf(nickName));
Following is my code for update record done.
try {
String str_edit = edit_note.getText().toString();
Toast.makeText(getApplicationContext(), str_edit,
Toast.LENGTH_LONG).show();
Toast.LENGTH_LONG).show();
String rawQuery="UPDATE " + GlobalVariable.getstr_tbl_name()
+ " SET note = '" + str_edit + "' where name = '"
+ str + "' ";
db.execSQL(rawQuery);
} catch (Exception e) {
System.out.println(e.getMessage());
}
Code for Display:
try {
Cursor note_cursor = db.query(GlobalVariable.getstr_tbl_name(),
new String[] { "note" + " as note" }, "name" + "=?",
new String[] { GlobalVariable.getstr_food_name() }, null,
null, null);
if (note_cursor.moveToFirst()) {
int notecol = note_cursor.getColumnIndex("note");
do {
String str = note_cursor.getString(notecol);
Toast.makeText(getApplicationContext(), str,
Toast.LENGTH_LONG).show();
edit_note.setText(str);
} while (note_cursor.moveToNext());
}
}
catch (Exception e) {
System.out.println(e.getMessage());
}
I am getting all variable value i.e global variables and all but update does not reflects on table.
What wrong i am done?
whenever we try to update our database then just clean and uninstall your app then again install may be some changes not take place when we don't uninstall it if u find correct then tell other wise we will see the next
Should
int notecol = note_cursor.getColumnIndex("name");
instead be
int notecol = note_cursor.getColumnIndex("note");
since in the first block of code you are updating note..
The problem is that you try to update your DB using a rawQuery method instead of a execSql. RawQuery is intended to retrieve data from your database, while execSql lets you
Execute a single SQL statement that is NOT a SELECT or any other SQL statement that returns data.
You can also consider to use public int update (String table, ContentValues values, String whereClause, String[] whereArgs) method.
I use the following code to insert new lines efficiently in a DB :
#Override
public void insertImpacts(HolderExpense expense, int[] shares, int[] amounts, HolderUser[] users) {
try {
mDb.beginTransaction(); // the insertion of the impacts of one expense are considered to be ONE block
String sql = "INSERT INTO "+DATABASE_TABLE_IMPACTS+" "+
"("+IMPACT_USERROWID+", "+IMPACT_EXPENSEROWID+", "+IMPACT_TTROWID+", "+IMPACT_NUMBEROFPARTS+", "+IMPACT_FIXEDAMOUNT+") VALUES (?, ?, ?, ?, ?)";
SQLiteStatement stmt = mDb.compileStatement(sql);
stmt.bindLong(2, expense.rowId);
stmt.bindLong(3, expense.tt.rowId);
int i = 0;
while (i < shares.length) {
if (users[i] != null) {
Log.v(TAG, "user " +i+": users[i].rowId:"+users[i].rowId+" expense.rowId:"+expense.rowId+" expense.tt.rowId:"+expense.tt.rowId+" shares[i]:"+shares[i]+" amounts[i]:"+amounts[i]+" ");
stmt.bindLong(1, users[i].rowId);
stmt.bindString(4, shares[i]+"");
stmt.bindString(5, amounts[i]+"");
stmt.execute();
}
i++;
}
stmt.close();
mDb.setTransactionSuccessful();
}
catch (Exception e) { e.printStackTrace(); throw new RuntimeException("insertImpacts() failed"); }
finally { mDb.endTransaction(); }
}
It works until android 4.x where I get that error:
02-26 14:27:46.179: W/System.err(937): android.database.sqlite.SQLiteConstraintException: error code 19: constraint failed
02-26 14:27:46.179: W/System.err(937): at android.database.sqlite.SQLiteStatement.native_execute(Native Method)
02-26 14:27:46.219: W/System.err(937): at android.database.sqlite.SQLiteStatement.executeUpdateDelete(SQLiteStatement.java:92)
02-26 14:27:46.219: W/System.err(937): at android.database.sqlite.SQLiteStatement.execute(SQLiteStatement.java:70)
Seems it crashes at stmt.execute() when inserting the second line into the table.
Any clue ?
-- EDITION --
The schema of the table is the following:
private static final String DATABASE_CREATE_TABLE_IMPACTS =
"create table " + DATABASE_TABLE_IMPACTS + " ("
+ IMPACT_ROWID + " integer primary key autoincrement, "
+ IMPACT_USERROWID + " integer not null, "
+ IMPACT_EXPENSEROWID + " integer not null, "
+ IMPACT_TTROWID + " integer not null, "
+ IMPACT_NUMBEROFPARTS + " integer not null, "
+ IMPACT_FIXEDAMOUNT + " integer not null, "
+ "constraint i_cstr1 unique ("+IMPACT_USERROWID+", "+IMPACT_EXPENSEROWID+")); ";
This code works like a charm on Android 2.2 (but fails on Android 4.0).
Print of the two first lines I insert (it crashes when trying to insert the second):
02-26 14:27:46.069: E/DatabaseAdapter.java(937): user 0: users[i].rowId:7 expense.rowId:2 expense.tt.rowId:2 shares[i]:1 amounts[i]:-1
02-26 14:27:46.069: E/DatabaseAdapter.java(937): user 1: users[i].rowId:5 expense.rowId:2 expense.tt.rowId:2 shares[i]:1 amounts[i]:-1
Found. The different version of android do not behave the same way. On Android 4.x, all the 'bindXXX' lines must be placed in the 'while' loop. Even if it is repetitive.
while (i < shares.length) {
if (users[i] != null) {
stmt.bindLong(1, users[i].rowId);
stmt.bindLong(2, expense.rowId);
stmt.bindLong(3, expense.tt.rowId);
stmt.bindString(4, String.valueOf(shares[i]));
stmt.bindString(5, String.valueOf(amounts[i]));
stmt.execute();
}
i++;
}
This is perfect Gilbou! I also made your data binding solution for my task: csv file importing to SQLite database. There was about 25.000 rows in the csv file, and importing it and insert to SQLite takes for me about 5 seconds (before it took 5 minutes without data binding!!)
Thank you so so much!
I also share mine, maybe it can helps for somebody, too (Android 4.0):
public boolean updateFromCsv() {
boolean ok = true;
String line = "";
BufferedReader br = null;
try {
FileInputStream fis = new FileInputStream(Environment
.getExternalStorageDirectory().getAbsolutePath()
+ "/Servantes/Be/leltariv_export.csv");
br = new BufferedReader(new InputStreamReader(fis));
} catch (FileNotFoundException e) {
ok = false;
e.printStackTrace();
}
try {
database.beginTransaction();
String sql = "INSERT INTO "+LeltarTable.TABLE_LELTAR_NEV+" "+
"("+LeltarTable.COLUMN_ID+", "+LeltarTable.COLUMN_LSZ+", "+LeltarTable.COLUMN_MEGN+", "+LeltarTable.COLUMN_HELY+", "+LeltarTable.COLUMN_DARAB+") VALUES (?, ?, ?, ?, 0)";
SQLiteStatement stmt = database.compileStatement(sql);
while ((line = br.readLine()) != null) {
String[] colums = line.split(";");
stmt.bindAllArgsAsStrings(colums);
stmt.execute();
}
stmt.close();
database.setTransactionSuccessful();
}catch (Exception e) {
e.printStackTrace();
ok = false;
}
finally {
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
ok = false;
}
database.endTransaction();
}
return ok;
}
As we Android developers know, the SQLiteDatabase execSQL method can execute only one statement.
The doc says:
Execute a single SQL statement that is not a query. For example, CREATE TABLE, DELETE, INSERT, etc. Multiple statements separated by ;s are not supported.
I have to load in a batch of records, 1000 and counting.
How do I insert these efficiently?
And what's the easiest way to deliver these SQLs with your apk?
I mention, there is already a system database and I will run this on the onUpdate event.
I have this code so far:
List<String[]> li = new ArrayList<String[]>();
li.add(new String[] {
"-1", "Stop", "0"
});
li.add(new String[] {
"0", "Start", "0"
});
/* the rest of the assign */
try {
for (String[] elem : li) {
getDb().execSQL(
"INSERT INTO " + TABLENAME + " (" + _ID + "," + NAME + "," + PARSE_ORDER
+ ") VALUES (?,?,?)", elem);
}
} catch (Exception e) {
e.printStackTrace();
}
How do I insert these efficiently?
Use transaction:
db.beginTransaction();
try {
for(;;) {
db.execSQL(...);
}
db.setTransactionSuccessful();
} finally {
db.endTransaction();
}
I think what you have is the only way to load those 1000 records, now, as far as deploying that DB with your apk file, check out this post:
http://www.helloandroid.com/tutorials/how-have-default-database