I have a database wherein i get my questions , correct answers/options from... I want my application to automatically generate random rowIds so that the questions could be shuffled.. Of course, the question that's already shown should not display again. I want to get 10 questions then finish();..
Using a random rowId is the wrong approach. What if the database is modified and the ID becomes invalid? You'd have to check every ID and regenerate when an invalid ID comes up.
Instead, you should use a LIMIT clause in your SELECT statement with a random number less than the number of rows in the table.
No need to generate random ids first. Just insert your rows, making sure you have the questionId column.
When you want read your database. Do something like quizid = rand() ....
After that you select the row with quizid in your database
SELECT * FROM quiztable WHERE questionId = quizid
Something like that will give you a random row from your database.
I think you get the point.
Related
Android, SQLite : I want to insert rows in between other rows in myTable using SQLite in android. For this, I am trying to increment ids of the all rows starting say row 3. So that I can insert a new row at position 3.
The primary key of myTable is column id. There are no other constraints in the table.
I have tried using the query mentioned in https://stackoverflow.com/a/9177264/6671004. This query does work in mySQL but not in Android (SQLite)
Here's the line of code :
database.execSQL("UPDATE myTable SET id = (id + 1) where id > 2 ORDER BY id desc");
Here's the error I'm getting on Android Studio (Compile time) :
https://imgur.com/a/9r0iyAa
This is the exception I'm getting if I remove 'ORDER BY id DESC' from the query :
java.lang.RuntimeException: Unable to start activity ComponentInfo{...}: android.database.sqlite.SQLiteConstraintException: UNIQUE constraint failed: myTable.id (code 1555)
Is this the correct way to do this? Or is there a better way?
As pointed out by many, this is definitely not the correct way to go.
But I found workaround in case someone else is looking for a similar implementation.
Here it is :
UPDATE myTable SET id = - (id + 1) WHERE id > 1;
UPDATE myTable SET id = - id WHERE id < 0;
This is a hack which I found here.
Again, this is not the correct way to go. But just posting a working solution I found.
I have tried using the query mentioned in
https://stackoverflow.com/a/9177264/6671004. This query does work in
mySQL but not in Android (SQLite)
That question is tagged MYSQL. MYSQL has many differences from SQLite.
Here's the line of code :
database.execSQL("UPDATE myTable SET id = (id + 1) where id > 2 ORDER
BY id desc");
The SQLite UPDATE SQL takes the form of :-
i.e. there is no ORDER BY clause and hence the error saying that if you're going to use any KEYWORD then it must be a BETWEEN or IN or a ; (of course you could also extend the condition using AND OR and so on).
This is the exception I'm getting if I remove 'ORDER BY id DESC' from
the query :
The reason being is that the rowid (id being an alias of rowid) has an implied UNIQUE constraint and that the rows will be updated according to the id column in order. So if there are more than 3 rows (or have been and the last row has never been deleted) then when the id is 3, a row with 4 will exist and 3 + 1 = 4 so the row already exists and hence the UNIQUE constraint being encountered.
I want to insert rows in between other rows in myTable using SQLite in
android. For this, I am trying to increment ids of the all rows
starting say row 3. So that I can insert a new row at position 3.
In short that is not a good idea and is virtually definitely not needed.
Is this the correct way to do this? Or is there a better way?
Definitely no
At a guess you want a nice humanly understandable value so you can know what's going on. For example you may present a list with the sequence so you can then say delete the row that has a sequence of 3 and thus equate that to the id column. Fine until you present the list in a different order which may be more user friendly. Suddenly your sequence becomes complicated or even useless and if displayed confusing.
identifiers are intended to identify a row and allow fast access to that row as a numerical index will be more efficient (than a human easily readable non-numeric index) to process. They also cater for reducing unnecessary additional processing (shifting data).
An efficient methodology is presenting the list with tying the id to the position in the list (so position could be the nth element of an array that holds the respective id, regenerating the list (the underlying array) according to a different order so the nth element will still have the respective id).
Embarking on a process of shifting rows will impose additional resource usage for example extra disk IO whose cost is relatively expense. This will be compounded by the fact that you will have to process the rows in reverse order to get around the UNIQUE constraint, that in itself is going to require using even costlier methods because SQLite will by default try to perform the updates efficiently rather than cater for the efficiencies required to digress from recognised/accepted techniques that utilise the underlying efficiencies.
I found this one working. And remove autoincrement from id
String strSQL1 = "UPDATE people_table SET id = (id +1) WHERE id < 0";
String strSQL = "UPDATE people_table SET id = (id -1) WHERE id > 1";
db.execSQL(strSQL);
db.execSQL(strSQL1);
If I have a SQLite table where I delete one row in the middle of it, it removes that row, but the numbering is off. example, removed row 4
id name
1 A
2 B
3 C
5 E
6 F
How can I reset the numbering so that it the key auto incremented key ID is continuous with out the missing 4 like in the table above?
one idea is to delete all the key row ids and re insert them in a for loop. not sure if I should try that as it is auto increment. the other possibility is to make it not auto increment, and use loops to put the numbers in when the table is crated.
You already answered your own question: It's an AUTOINCREMENT field, so you can't do that. Furthermore, this is not how ids should be used in SQL anyway. They are to uniquely identify a row, and if you change the id, then you're breaking that, as well as any references there might possibly be to that id.
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 have a database having 28 rows just for saving app data. My goal is to read One specific column (not one value) from it.
However, I don't want to read all columns at once, because it's slow as I have blob's in db too. Instead, I'd like to read just one column at a time, separately. Can you plese help me to solve this problem.
If you want to read one ROW do something along those lines:
SELECT * FROM tablename WHERE id='5' LIMIT 1;
where 'id' is supposer do be in the table 'tablename'
or else try something like this:
SELECT datafield FROM tablename WHERE 1;
which will give you all the 'datafield' data from the table (ie. a Column).
If this doesn't help you at all then post the code you are already using.
I am wondering how can I insert an element at the beginning of the data base? I want to do this because:
a) I want to display the elements (ListView) as 'last-inserted on top and first-inserted on the bottom' (like a stack)
b) I want to limit the amount of elements in my db. When a new element is added (over the limit) I can put the new one (at the beginning) and delete the last one. (Don't know yet how to delete the last element).
I was searching for a solution but I am starting to wonder I have any control of how the element are inserted. If not I was thinking about displaying the database from end to bottom. But don't actually know how to do it since the cursor is always set at the beginning of the db. If could achieve this I can solve b) by deleting the first element (again don't know how to achieve this yet).
Every row of every SQLite table has a 64-bit signed integer key that uniquely identifies the row within its table. This integer is usually called the "rowid"
To get last inserted at top and first inserted at bottom....
SELECT * from mytable order by ROWID desc;
Read more about ROWID here
And, to delete the oldest:
DELETE from mytable WHERE ROWID = (SELECT MIN(ROWID) FROM mytable);
If you use the ROWID, you do not have to modify your existing table. And, the value of ROWID is guaranteed.
You can store a timestamp (as a new field) when you insert a record into your database. Then you delete the oldest record you can find if it is over the limit (e.g. using MAX SQL keyword). You can display the records in reverse-chronological order by sorting DESC with your timestamp field.