I have a database with 4 columns. Everything works fine except for the fact that random rows remain inaccessible. I cannot seem to update or delete them. I've used the right code:
DELETION CODE:
boolean deleted=db.delete(TABLE_NAME, KEY_BLAH + "=" + alarm, null) > 0;
CODE FOR UPDATE:
db.update(TABLE_NAME, args, KEY_BLAH + "=" + blah, null)
The deletion code returns false and the update code returns 0 for some rows, which are arbitrary. The rows are implemented into a ListView. Any changes on the ListView elements should be reflected in the SQLite Database. Most of the times the code works. It doesn't seem to work for random rows at random points though. I do not think this is SDK related. I've tried it on ICS, GB and JB.
I've also tried deleting the row and inserting it. Obviously this wouldn't work because my delete statement doesn't seem to work. The logic for this was, if the update wasn't possible it would delete the row and insert the row with the same row id and different data. So, the deleted variable was the condition for an if-block which didn't get executed.
EDIT
Example:
1 1414 000 off
When I click on a few buttons in the list item.
It should become
1 1414 064 off
Now, this works most of the times except for some random rows as I said before.
If you (indirectly) execute an SQL statement like this:
UPDATE MyTable SET x = '064' WHERE blah = 1414
then the values in the blah column are compared with the number 1414.
When using strings in SQL statements, you should always use parameters to avoid formatting problems like this (and SQL injection attacks):
db.update(TABLE_NAME, args, KEY_BLAH + "= ?", new String[] { blah })
Related
I have very strange problem.
After a lot of debugging I come to following line of code:
db.db.rawQuery("INSERT INTO goal_calendar(timestamp) VALUES(1)", null);
db.cursor = db.db.rawQuery("SELECT * FROM goal_calendar", null);
Log.e("SIZE", String.valueOf(db.cursor.getCount()));
The result is "Size 0".
There is no any errors at all. Everything worked just fine and suddenly it didn't want to store nothing in my table. It just stopped. What could be wrong?
According to me the result after these three lines of code SHOULD ALWAYS be error(exception) or SIZE should be greater than 0.
Because this
"INSERT INTO goal_calendar(timestamp) VALUES(1)"
is not a QUERY (SELECT),but a COMMAND.
For commands (INSERT, UPDATE, DELETE, ...), use this:
db.execSQL("INSERT INTO goal_calendar (timestamp) VALUES (1)", null);
I also have some doubts on why do you double "db."
I'd use "db.rawQuery" and "db.execSQL", instead of "db.db.rawQuery" and "db.db.execSQL".
Now two words of explanation:
Your INSERT statement doesn't work. That's why your query correctly returns a zero count.
I have problems in updating rows in SQLite database in my Android application. It works successfully only, if I update it two times. But when I try to do it on the third time, it doesn't update the same row anymore.
LogCat doesn't show any exceptions. db.update() returns '1'.
I've searched similar issues on StackOverflow and the web. People advic]sed to remove db.close(); from database-helper, because I call it several times, or to use db.update method instead of db.rawQuery() or db.execSQL().
I also tested my query in SQLite client, and it works as it's supposed to.
Here is code of simple database-helper method:
public int updateEventDoneMark(Event event)
{
ContentValues args = new ContentValues();
args.put("completed", event.getCompleted());
return db.update("Event", args, "id" + "='" +event.getId() + "'", null);
}
Is there some SQLite-related issue I should know while I update one database entry several times in a row?
What does your content provider update and URI match look like?
Typical Content providers have a URI for each Table/View for a single row where _id is passed as a where_argument and a URI for multiple rows which uses where and where_arguments to select the rows to be updated.
Also it looks like you update by id. Android really want the id column named "_id", although I don't think is currently your issue, but it really depends on the URI it's using. Content Providers are usually coded with the _id and select by the column for a single row based on _id. That's why I want to see content provider. Your also selecting by the id yourself, this doesn't seem normal, although it could be accomplished, but not the norm. Typically the where part is something like 'colunm name = ?" and the next parameter where_arguments is a string array containing the value to replace the '?'.
Hope this helps.
I just want to create simple database, one table with two columns: id, which will be auto incremented and data, so with my target data to store. I created this code, which doesn't return any error but also don't add any data:
database = openOrCreateDatabase ("alldata", 0, null);
try{
database.execSQL("CREATE TABLE cars(_id INTEGER PRIMARY KEY,data INTEGER);");
}
catch(SQLException e){
}
//database.execSQL("INSERT INTO cars(data) values(0);");
database.execSQL("INSERT INTO cars(data) values(1);");
database.execSQL("INSERT INTO cars(data) values(2);");
database.execSQL("INSERT INTO cars(data) values(3);");
database.execSQL("INSERT INTO cars(data) values(4);");
database.execSQL("INSERT INTO cars(data) values(5);");
String[] data={"_id","data"};
Cursor c=database.query(false, "cars", data, null, null, null, null, null, null, null);
int i=0;
if(c.getCount()>0){
c.moveToFirst();
readed[i]=c.getInt(0);
readed[i+1]=c.getInt(1);
i+=2;
}
And when i try to read the "readed" table it only shows two zeros 00:
for(int i=0;i<readed.length;i++){
if(readed[i] != null)
draw_number((int) readed[i],canvas,(float)(0.9*width-i*0.05*width),(float)(0.8*height));
}
Draw number is my methos which is drawing a number on surfaceview, there is nothing wrong with this one. But unfortunetly I do not know, where is a problem with database. As far as i know I did everything ok and it should return:
0 0 1 1 2 2 3 3 4 4 5 5 (because earlier I added one 0 to data column.)
But it only returns 0 0
Any ideas?
You can just clear the Application Data, using 'Manage Apps' --> 'Clear Data' (This would delete all the previously created Databases, Preferences and all that stuff). And again execute the code using AUTOINCREMENT.
database.execSQL("CREATE TABLE cars(_id INTEGER PRIMARY KEY AUTOINCREMENT,data INTEGER);");
The code seems to behave exactly as written.
First you have some code that checks if there is a row in the results. It then proceeds to read the first result, and only the first result (maybe you are mistaking if for while? but in such case you have got moveToFirst wrong, even if you switch if for a while it will only read the first row, again and again) and place it into readed array.
Since readed contains just the numbers from the first row, the second snippet will loop over the whole array but print only the two first numbers (the values that are not null). And this is exactly the result you report.
Perhaps you wanted to write a code that loads all the cursor rows into readed? It would be a loop (not a conditional statement):
while (c.hasNext()) {
c.moveToNext();
readed[i] = c.getInt(0);
readed[i+1] = c.getInt(1);
i += 2;
}
And swallowing exceptions is an offense and an insult to everyone answering your question.
Tendency towards hiding errors instead of solving them is visible in this line of your code:
if(readed[i] != null) {
If it wasn't for the former errors, this code would not be necessary. I believe that the first time you run the loop you got a null pointer exception, and instead of checking the logic of filling the array (what is a null value doing there?!) you just removed the symptoms. This is just like swallowing an exception: shooting the messenger because you don't like some news.
EDIT / UPDATE
As for creating tables, each sqlite database in Android has a version number (a simple int that you can read or write, a fresh database starts with 0), so the low-level way of handling this would be to have something like:
if (database.getVersion == 0) {
// ...create table here...
database.setVersion(1);
}
Most people end using Sqliteopenhelper, as it helps a bit in solving other problems (that you have not hit yet, but probably will) like concurrent access to the database.
you have not used auto increment for your database.? as can be seen in your database
That's the reason you are getting only 1 result.
use drop table and try again
change
for(int i=0;i<readed.length;i++){
to
for(int i=0;i<readed[].length;i++){
Say my SQLite Databate has 2 columns, the first being an auto-incrementing ID and the 2nd being some string. Say right now it's
1 random
2 jellybean
3 ImTired
if I were to delete entry 2, it would then be
1 random
3 ImTired
What I want is a way to make it so when you delete entry 2, it turns it into
1 random
2 ImTired
I thought about updating the entries to shift them all down one and delete the last one, but even if it worked(in my case, it deleted all of my entries, but whatever...), and even if I did get it to
1 random
2 ImTired
the next time I create a new entry, it'll be entry 4. I don't think this necessary to my app, but it seriously bugs me.
The ID column on your DB is working as a Primary Key, which is a column or group of columns used to uniquely identify a row. Once you set a Primary Key on a row you shouldn't change it, else you risk losing the consistency of the DB. For instance, suppose you later create another table that references the rows in your first table. That reference will be made using the Primary Key, and if you later change it your data won't make sense anymore.
If you wanted the ID column to keep changing just to reflect the number of rows in your table you can solve that problem with other methods. For instance. SQL offers a COUNT operator that will return the number of rows in your table:
SELECT COUNT(*) FROM Table_name;
I want to get the number of NOT NULL records from my SQLite database. Since I'm using autoincrement, the last inserted row won't give me the real number of records in the table as even if I delete any middle record, it'll insert at the position higher than the last inserted record.
The insert statement returns me the number of last inserted row, but I want this value on the fly.
Doing a count before on the table should work. Simply query for the id column with the where check of NOT NULL and on the returned cursor just call the getCount()
Just to be sure: You should never ever, really never ever, manipulate the auto increment in a productive database. If you delete a record, than the "gap" should stay there. It has no impact on performance or anything else. If you insert a new record in the gap, you can create a lot of trouble...
So you just want to find the number of rows? (There no such thing as a "null record" as far as I'm aware.)
Can you not just do
select count(1) from YourTableName
or
select count(*) from YourTableName
? (Some databases are faster using one form or other... I don't know about sqlite.)