I'm trying to remove a row from an SQL table using this code below. However, whenever I call this method I get this following error:
android.database.sqlite.SQLiteException: no such column: Plumber (code 1): , while compiling: DELETE FROM service WHERE name = Plumber
public boolean deleteService(String name){
SQLiteDatabase db = this.getWritableDatabase();
boolean result = false;
String query = "SELECT * FROM "
+ TABLE_SERVICE
+ " WHERE "
+ COLUMN_NAME
+ " = \""
+ name
+ "\""
;
Cursor cursor = db.rawQuery(query, null);
if(cursor.moveToFirst()){
String nameStr = cursor.getString(0);
db.delete(TABLE_SERVICE, COLUMN_NAME + " = " + nameStr, null);
cursor.close();
result = true;
}
db.close();
return result;
}
This is my table
public void onCreate(SQLiteDatabase db){
String CREATE_USERS_TABLE = "CREATE TABLE " +
TABLE_SERVICE + "("
+
COLUMN_NAME + " TEXT," +
COLUMN_RATE + " TEXT," +
COLUMN_CATEGORY + " TEXT," + COLUMN_SUBCATEGORY + " TEXT)";
db.execSQL(CREATE_USERS_TABLE);
}
First you're fetching all the rows that in COLUMN_NAME have the value name.
Next you want to delete the 1st of these rows (maybe it's the only one?) because nameStr gets the value of the 1st column which is COLUMN_NAME.
Why are you doing this?
Just execute this statement:
int number = db.delete(TABLE_SERVICE, COLUMN_NAME + " = '" + name + "'", null);
if number gets the value 0 then no rows were deleted, else it gets the number of deleted rows.
delete deletes rows not columns.
If you want to get rid of a column, you need to drop it. The SQL syntax is:
alter table table_service drop column <column_name>;
I don't know how to express this in java with the methods that you are using.
Ensure that your SQL syntax is correct, and that "Plumber" is a string with double quotes. By my experience, these errors are usually caused by an incorrect column or name.
Use this format:
DELETE FROM table_name WHERE condition(s)
SQLite browser can also help you visualize your database.
Related
I am trying to get the max id of a table in SQLite in Android. This is how I get it in the database helper:
public int getMaxIncrementation() {
SQLiteDatabase sqLiteDatabase = this.getReadableDatabase();
String result = "0";
try{
Cursor cursor = sqLiteDatabase.rawQuery("SELECT MAX(id) FROM " +TABLE_INCREMENTATION, new String[]{});
cursor.moveToFirst();
result = cursor.getString(cursor.getColumnIndex(INCREMENTATION_ID));
}catch (Exception ex) {
Log.e("ex", ex.getMessage());
}
return Integer.parseInt(result);
};
This is how I created the table:
private static final String CREATE_TABLE_INCREMENTATION = "CREATE TABLE IF NOT EXISTS " + TABLE_INCREMENTATION
+ "("
+ INCREMENTATION_DATEADDED + " TEXT,"
+ INCREMENTATION_DIRECTION + " INTEGER,"
+ INCREMENTATION_ID + " INTEGER PRIMARY KEY AUTOINCREMENT,"
+ INCREMENTATION_USER + " TEXT"
+ ")";
This is the snapshot of my table with data in it:
On debugging, I always get this error:
Couldn't read row 0, col -1 from CursorWindow. Make sure the Cursor
is initialized correctly before accessing data from it.
First, since you don't have in the query any ? placeholders then you don't need to pass any parameters to the sql statement, so the 2nd argument of rawQuery() should be null.
Also you must give an alias to the column that your query returns and use it to get the returned value (you can't use INCREMENTATION_ID because it is not the name of the column returned):
Cursor cursor = sqLiteDatabase.rawQuery("SELECT MAX(id) AS maxid FROM " +TABLE_INCREMENTATION, null);
if (cursor.moveToFirst())
result = cursor.getString(cursor.getColumnIndex("maxid"));
Or if you don't use an alias then use 0 as there is only 1 column returned:
Cursor cursor = sqLiteDatabase.rawQuery("SELECT MAX(id) FROM " +TABLE_INCREMENTATION, null);
if (cursor.moveToFirst())
result = cursor.getString(0);
I'm trying to update data in rows in my DB, but i catch error that there's no such column (no such column 'Moscow' or another)
This is DBHelper code:
public static final String tableName = "currentWeather";
public static final String KEY_ID = "_id";
public static final String cityName = "city";
public static final String cityTemp = "temperature";
And creating DB:
sqLiteDatabase.execSQL("create table " + tableName + "(" + KEY_ID + "
integer primary key autoincrement,"
+ cityName + " text," + cityTemp + " text, " + " UNIQUE(" + cityName +
"))");
and error shows when i try to execSQl in response:
sqLiteDatabase.execSQL(
"UPDATE " + DBHelper.tableName + " SET " +
DBHelper.cityTemp + "=" +
response.body().getForecastMain().getTemp() + "
WHERE "
+ DBHelper.cityName + "=" + cityName);
I expect to update temperature data in rows by cityName
cityName and response.body().getForecastMain().getTemp() are strings and they should be passed surrounded with single quotes to the sql statement:
sqLiteDatabase.execSQL(
"UPDATE " + DBHelper.tableName + " SET " + DBHelper.cityTemp + "='" + response.body().getForecastMain().getTemp() + "'" +
"WHERE " + DBHelper.cityName + " = '" + cityName + "'"
);
But the recommended and safe way of doing the update is with the use of ContentValues and ? as placeholders for the parameters:
ContentValues cv = new ContentValues();
cv.put(DBHelper.cityTemp, String.valueOf(response.body().getForecastMain().getTemp()));
int rows = sqLiteDatabase.update(
DBHelper.tableName,
cv,
DBHelper.cityName + " = ?",
new String[] {cityName}
);
You can examine the value of the integer variable rows.
If it is 1 this means that 1 row was updated (because cityName is unique) so the update was successful.
I think you have changed column name or add new one (city). So you can fix it by two ways
By uninstall the application from phone
Add column name in upgrade method.
Example:
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// If you need to add a column
if (newVersion > oldVersion) {
db.execSQL("ALTER TABLE foo ADD COLUMN new_column INTEGER DEFAULT 0");
}
}
The thing is you need to wrap the values after the = sign in single quotations in the UPDATE statement. As for digits they work in both cases.
For example here is the correct syntax
UPDATE currentWeather
SET temperature = 45
WHERE
city = 'Moscow'
But in your code I'm assuming cityName has the value Moscow without the single quotation marks so the converted SQL code will be like this
UPDATE currentWeather
SET temperature = 45
WHERE
city = Moscow
Now the sql interpreter will think Moscow is some database object or column or something and not a literal value. So you need to surround your values in single quotation marks.
Also consider What the data type of response.body().getForecastMain().getTemp() is.
If it's int you have to parse it or something, as the data type of the related column is Text.
I have database with 4 columns int id | String data | String date | int boot and i have some data in it. I have method getRow(String s) when i call it with string for id or data and change query to that option it works but when i´m trying to get row with equal date it won´t pass cursor.moveToFirst condition.
Here is my code:
String CREATE_TABLE = "CREATE TABLE "
+ TABLE_NAME + "(" + COLUMN_ID + " INTEGER PRIMARY KEY AUTOINCREMENT," + COLUMN_DATA
+ " TEXT," + COLUMN_DATE + " TEXT," + COLUMN_BOOT + " Integer" + ")";
public String getRowID(String id){
SQLiteDatabase db = this.getReadableDatabase();
Cursor c = db.rawQuery("select * from " + TABLE_NAME + " where " + COLUMN_ID + " = " + id, null);
if (c != null && c.moveToFirst()) {
//loggin succes
return "string";
}else return null;
}
public String getRowDate(String date){
SQLiteDatabase db = this.getReadableDatabase();
Cursor c = db.rawQuery("select * from " + TABLE_NAME + " where " + COLUMN_DATE + " = " + date, null);
if (c != null && c.moveToFirst()) {
//loggin succes
return "string";
}else return null;
}
myDb.getRowID("1"); returning something
myDb.getRowDate("02122016"); returning null
I have two rows in my database.
1 | 0.19 | 01122016 | 0
2 | 0.19 | 02122016 | 0
Be wary when comparing integers and strings. You may wonder why SQLite would be comparing integers at all since your arguments are strings, until you consider that your raw query looks like this:
select * from TABLE where DATE = 02122016
That value is interpreted as an integer and converted to text, but it loses the leading zero in the process. You can verify this with a sqlite3 shell:
sqlite> select 02122016;
2122016
sqlite> select '02122016' = 02122016;
0 -- false
sqlite> select cast(02122016 as text);
2122016
The simplest fix is to quote the value using a method from DatabaseUtils:
String escaped = DatabaseUtils.sqlEscapeString(date);
String query = "select * from " + TABLE_NAME + " where " + COLUMN_DATE + " = " + escaped;
A better fix would be to use a placeholder argument instead. Note that Android binds all arguments as strings:
String query = "select * from " + TABLE_NAME + " where " + COLUMN_DATE + " = ?";
db.rawQuery(query, new String[]{date});
However, my advice would be to not use rawQuery() and instead use one of the real query() methods. Here's a good example.
Lastly, perhaps you should consider a different format for storing dates. In practice I usually either store an INTEGER column with a unix timestamp (seconds or milliseconds since epoch), or I use a TEXT column with values in the yyyy-MM-dd format since this is implicitly supported by numerous datetime functions in SQLite.
I have a database for my leaderboard. Currently, I insert all scores into my leaderboard, and select the 5 highest scores to show on my app. I think it would take up too much room to never delete the other scores, so I would like to delete them. How can I do this?
Here's how I select the top 5 scores, ranked first by score and second by time if score is equal:
public Cursor gethmLeaderboard(SQLiteDatabase db){
String[] columns = {TableInfo.LB_RANK, TableInfo.LB_SCORE, TableInfo.LB_TIME};
Cursor c = db.query(TableInfo.TABLE_HM, null, null, null, null, null, TableInfo.LB_SCORE + " DESC, " + TableInfo.LB_TIME + " ASC", "5");
return c;
}
Here's how I create my table:
public String CREATE_HMQUERY = "CREATE TABLE " + TableInfo.TABLE_HM + "("
+ TableInfo.LB_RANK + " INTEGER PRIMARY KEY AUTOINCREMENT DEFAULT 1 ," + TableInfo.LB_SCORE +
" INT,"+ TableInfo.LB_TIME + " VARCHAR );";
I want to delete all rows NOT IN that query. How can I do that?
Edit:
I tried this query:
public String DEL_ALLBUTES = "DELETE FROM " +
TableInfo.TABLE_HM + " WHERE " +
TableInfo.LB_RANK + " NOT IN (SELECT " +
TableInfo.LB_RANK + " FROM " +
TableInfo.TABLE_HM + " ORDER BY " +
TableInfo.LB_SCORE + " DESC, " +
TableInfo.LB_TIME + " ASC LIMIT 5);";
In this format:
db.rawQuery(DEL_ALLBUTES, null);
But when I check the database there are still tons of rows so it doesn't work.
Your table needs to have some unique ID. Use that to identify the rows you want to keep:
DELETE FROM ES
WHERE ID NOT IN (SELECT ID
FROM ES
ORDER BY Score DESC, Time ASC
LIMIT 5);
You can create temp table insert top 5 score into temp table and delete all table then insert temp table into main table.
CREATE TEMP TABLE TempES AS SELECT
ID
FROM
ES
ORDER BY
Score DESC,
Time ASC
LIMIT 5;
DELETE
FROM
ES;
INSERT INTO ES SELECT
*
FROM
TempES;
DROP TABLE TempES;
I have created a table called CHEMISTID:
private static final String CREATE_TABLE_CHEMISTID = "CREATE TABLE "
+ CHEMISTID + "(" + KEY_ID + " INTEGER PRIMARY KEY, " + KEY_CHEMISTID
+ " TEXT" + ")";
My insert function works properly but when I run a search query to find if a chemistId is already present using the following query statement:
String selectQuery = "SELECT * FROM " + CHEMISTID +" WHERE " + KEY_CHEMISTID + " = "+ chemistID + ";";
Cursor c = db.rawQuery(selectQuery,null);
My logcat displays the following error message:
E/AndroidRuntime(1169): FATAL EXCEPTION: main
E/AndroidRuntime(1169): android.database.sqlite.SQLiteException: no such column: Spain (code 1): , while compiling: SELECT * FROM chemistIdTable WHERE chemistId = Spain;
Where Spain is a particular chemistId that I have dynamically created in my program.
How should I fix my selectQuery String so that it searches in the column name KEY_CHEMISTID for a particular String chemistId?
You need to quote your strings such as Spain in SQL so they get taken as string literals and not column name identifiers. You can use single quotes like 'Spain' for that.
However it's much better to use ? parameter placeholders instead and supply the parameter values in the selection args array, like:
... KEY_CHEMISTID + "=?" ...
c = db.rawQuery(selectQuery, new String[] { chemistID });
You missed single quote,So change
String selectQuery = "SELECT * FROM " + CHEMISTID +" WHERE " + KEY_CHEMISTID + " = "+ chemistID + ";";
to
String selectQuery = "SELECT * FROM " + CHEMISTID +" WHERE " + KEY_CHEMISTID + " = '"+ chemistID + "';";
Recommended solution is to use parameterized query as
Cursor c = db.query(CHEMISTID, null, KEY_CHEMISTID + "=?",
new String[] { chemistID },null, null, null, null);