SQLite UPDATE value with row number possible/options? - android

Hi i'm working on an SQLite viewer in android using java and shell commands (so commands have to be one line) i've written the layout and viewer and all everything is perfect. I set it up so when a value is long pressed an edit text shows where the user can input the new value and then when okay is pressed it should update the value.
I have the column name, old and new value, database name, table name etc however the issue is allowing them to update the value i've seen things like the where clause but the issue is if a column has the value multiple times (which could very well be the case) it won't know the correct row.
So bear in mind i'm new to sqlite been working with it less than a week. Is there a way i can update the column value with the columns name and row number?
What are my options to update the table.
I also don't really under stand this say i have a table like this (one column)
sample
--------
0
0
0
1
0
1
1
0
How would you update the third row to equal 1? If I did
sqlite3 DATABASEHERE "UPDATE TABLEHERE SET sample='1' WHERE sample='0'"
The where statement describes rows 1, 2, 3, 5, and 8 so there has to be a way to use row number?
Thanks for any help

SQLite gives you access to rowid. So you can write SELECT rowid, col FROM table1 and then use it to update the table :UPDATE TABLEHERE SET sample='1' WHERE rowid=3

Related

Limiting number of rows in SQLite

I have a situation where I just want to limit only 50 rows in a table. If user inserts a new row after that then first row (which was inserted very first) should get deleted and new row gets inserted, so that count remains same.
I know that I can have an rowid field and while inserting new record I can check if there are already 50 rows so delete the smallest rowid and then insert the new one. But just wanna know if there is any better solution so that I don't have to do 3 database operations (1. query #of rows, 2. delete minimum, 3. insert)
I know a way that works, but it's a little ugly. It relies on carefully constructed constraints and on seeding the database. For brevity, I'm using just five rows instead of 50.
create table test (
row_num integer primary key
check ((round(row_num) = row_num) and (row_num between 1 and 5)),
other_columns char(1) not null default 'x',
row_timestamp timestamp
not null unique
default current_timestamp
);
The expression round(row_num = row_num) guarantees you have integers in the row_num column. Otherwise, SQLite would let you insert 1.54 or 'wibble' in there.
The other_columns column is just a placeholder for your actual data.
insert into test (row_num, row_timestamp) values
(1, '2015-01-01 08:00:01'),
(2, '2015-01-01 08:00:02'),
(3, '2015-01-01 08:00:03'),
(4, '2015-01-01 08:00:04'),
(5, '2015-01-01 08:00:05');
The actual timestamp values don't really mean anything. Not yet, anyway. Seeding the database like this means that, from now on, you only have to execute update statements. If the table were empty to start with, you'd have to deal with different logic for inserts and updates. For example, you'd have to count rows to figure out whether to insert or to update.
create trigger update_timestamp
after update on test
for each row
begin
update test
set row_timestamp = strftime('%Y-%m-%d %H:%M:%f', 'now')
where row_num = OLD.row_num;
end;
The "update_timestamp" trigger makes SQLite maintain the timestamp with fractions of a second (%f). Might depend on whether the underlying OS supports fractional precision.
create trigger no_deletes
after delete on test
for each row
begin
-- There might be a more elegant way to prevent deletes.
-- This way just inserts exactly what a delete statement deletes.
insert into test (row_num, other_columns, row_timestamp)
values (OLD.row_num, OLD.other_columns, OLD.row_timestamp);
end;
Now you can update data. You update your own data, which here is just the placeholder other_columns, and SQLite takes care of the rest.
update test
set other_columns = 'b'
where row_timestamp = (select min(row_timestamp) from test);
select * from test order by row_timestamp desc;
row_num other_columns row_timestamp
---------- ------------- -----------------------
1 b 2015-03-08 12:43:21.926
5 x 2015-01-01 08:00:05
4 x 2015-01-01 08:00:04
3 x 2015-01-01 08:00:03
2 x 2015-01-01 08:00:02

Restricting displaycount of a row in sqlite table

I have two columns in a table. I am using this table in an android application. For ex., TAB1:
when I display One, the display_count of 1 should increment by 1. Like that, I have to display the names continuously through out my application. Mean while, the display_count is getting too big in long run. Is there any option in sqlite, to restrict the column data, such that, if I reach a certain value say display_count = 64 for a row, the display_count should should reset to 1 and again start from 1. To say clearly, display_count should not exceed 64.
Logically while updating, you can use (col=col+1)%65 instead of col=col+1. The thing is count will again start from 0 instead of 1

how to reset key IDs numbering for a table after deleting one row, SQLite database Android

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.

How do I keep my SQLite Database organized? Android

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;

How can I count the number of rows before a certain row in sqlite?

I have a database that stores the rank of an Item.
The rank is an absolute value that will be correct if all the items are taken into account.
If I only need a subset say four of this items it will give me something like:
Rank RowId in the whole Table
---------------
4 114
8 71
70 16
83 7
I now need an int specifying the rank only in the subset where the max rank is the number of items in the subset in my example 1,2,3,4.
Is there a way to achieve this in my sqlite query? I only need one of the ranks in my Activity. I thought of ordering the results of the query by rank and then somehow get the position of item I want to rank at that moment. But how would I achieve this with sqlite?
I tried to create a temporary table and insert the subset into it like this:
CREATE TABLE rank(ID);
INSERT INTO position SELECT ID from items WHERE ITEM_ID = 3 ORDER BY POSITION;
SELECT RowID from rank WHERE ID = 9;
DROP TABLE rank;
This is working in SQLite Manager and will return the correct number. But if I do this in Android in fails saying that there is no table rank while compiling query
07-07 13:35:46.150: ERROR/AndroidRuntime(2047): Caused by: android.database.sqlite.SQLiteException: no such table: rank: , while compiling: SELECT RowID from rank WHERE ID = 9
EDIT: have to agree with #Matt the only way I've been able to do this is to use the temp table approach.
For what it's worth here's what it looks like...
create temp table if not exists <temptable>(Id integer primary key, rank);
insert into temptable(rank) select <column> from <table>;
select * from temptable;
EDIT: Actually that returns the ID associated with the row which isn't sequential so you won't always get 1,2,3,4... I'll have to think of something else. Sorry.
Not sure if I've understood your question. You basically want this?
Id Value
---------------
1 4
2 8
3 70
4 83
So you want to add a pseudo-column as the id no matter what your subset contains?
If that's correct then this should do it...
SELECT RowId, <other columns>.... FROM <table> WHERE <where>
Apologies if I've misunderstood.
You could output your query (ordered by rank) into a temporary table with an auto increment ID.
If you need to read only one row from a subquery you can always execute a limit on it, by providing the offset of how many records to be skipped first, and how much to be returned
so if you want to get 25th row you tell to skip 24, and return 1
select * from (SELECT * FROM table order by rank) limit 24,1

Categories

Resources