Inputting Single Value into SQLiteDatabase - android

I was just wondering if it's possible to just input/update a single value into an SQLiteDatabase (as opposed to an entire row).
The SQLiteDatabase API on the Android developer site makes it sound like you can only insert one row at a time (which erases previous information).
An alternative I've been thinking of is to copy the contents of the entire row into an array, alter a value in the array, and then insert the values of the array as an update row in the SQL Database. Does anyone have a more efficient and less roundabout solution?

The SQLiteDatabase API on the Android developer site makes it sound like you can only insert one row at a time (which erases previous information).
A standard SQL INSERT statement does not erase "previous information". It adds a new row to a table.
I was just wondering if it's possible to just input/update a single value into an SQLiteDatabase (as opposed to an entire row).
By definition, it is not possible to insert a single value into a table. You insert rows into a table. Any columns that you do not provide values for in your INSERT statement need to either allow NULL values or have default values defined on the table.
A SQL UPDATE statement, however, can update a single column in a row. This is true whether you use update() or execSQL() on SQLiteDatabase to update that row.
then insert the values of the array as an update row in the SQL Database
A standard SQL INSERT statement does not update a row. It adds a new row to a table.

Related

Sqlite order by rows order

I am using this query
"select * from SomeTable group by SomeColumn"
It is returns list with accenting order, but i need to same order like in database.
For example the order in database is:
p
a
s
But result is:
a
i
p
Sample
The result need to be like distinct by CityEN but with all columns and order like 1.Paris 2.Amsterdam 3.Istanbul
In Sqlite, each row of a table has a unique rowid, which you can use for sorting.
select * from SomeTable group by SomeColumn order by rowid;
In your statement, add this line to sort the results:
order by min(rowid)
Your query does not enforce any order with ORDER BY clause so no assumption about row order should be made. If you want specific order add i.e. ORDER BY SomeColumn. See docs about all available order options: https://www.sqlite.org/lang_select.html#orderby
By the rules of SQL, you can't count on getting records back in any specific order without specifying an ORDER BY clause in your SQL query.
In practice servers sometimes return values in the order in which they're inserted, in the order of the first index created, or in the order of the primary key--but you can't count on this behavior, and in fact I've seen the behavior change between database maintenance windows or after the database version is upgraded. You definitely wouldn't want to count on a DB engine to give you back records in any particular order if you write a SELECT statement without an ORDER BY clause.
The only real way to get your records back in the order you inserted them is to create a timestamp column and then sort on it during the SELECT. If you don't want to worry about populating that column on INSERT, have that column auto-populate itself with a timestamp (depending on your DB engine).

Custom Room-DB Insert statement

I would like to add a string -- a value entered and changed, occasionally, by the user -- as a tag on all of the records downloaded from a server and inserted into a local, Room managed, db. I would like my DAO method to take as arguments, the tag and a list of entities.
It looks to me as if there is no straightforward way to do this (insert a constant value for all rows) with a Room-managed db.
Iterating over all the records and setting the constant value seems pretty inefficient.
Is there a good way to:
Define a table that contains columns that are never in POJOs (used only as query filters)?
Insert a constant value for all rows added in a single insert?

Android SQLite: How to update one column of all records with different values

I found on Stack similar questions like this How to update an entire column in sqlite? But they don't explain me my how to solve my task.
Say, I have a db with 5 columns and 5 records in it. What i need is to update the last column "date" with the values of unix time that differs by 1 sec. So i need to put values 1406820974139, 1406820974140, 1406820974141, 1406820974142, 1406820974143, 1406820974144.
How to do it using ContentValues? As i got i have to loop five times to create new ContentValues object and update one record at a time (maybe using db.startTransaction() syntax).
My question is is there a way to put all values at a time into one ContentValues object and write in them into DB? Or maybe the better way is to use rawQuery using native SQL syntax as explained in How to update an entire column in sqlite?
In theory, it would be possible to put all the values into a single SQL statement:
UPDATE MyTable
SET date = CASE _id
WHEN 5 THEN 1406820974139
WHEN 17 THEN 1406820974140
WHEN 23 THEN 1406820974141
WHEN 69 THEN 1406820974142
WHEN 666 THEN 1406820974143
END;
However, just creating one ContentValues object for each row is easier than constructing this command.
so that we know which date should go to which row? what is the cririteria to differentiate the rows?
a relational db table is different from say an excel table. there is no implicit row order (if you always see the rows in the same order,you can consider it a kind of coincidence,you can not rely on this like you do in excel), in a db table you need to have a column(or a group of them) with unique values which you use in your queries to identify each of your records.
so you need to be more clear in your question. what date should go to which record (identified by what?). there is no implicit row number, if you want it, add an autoincrement PK column.
then you could for instance use something along the lines of
UPDATE table SET column5= 1406820974140+PKcolumn
where 1406820974140 is the start date you have to choose, depending on what you are up to

Can you delete columns in an SQLite database?

The Android app that I am currently working on dynamically adds columns to an SQLite database. The problem I have is that I cannot figure out a way to remove these columns from the database.
If I add column A, B, C, D, and E to the database, is it possible to later remove column C?
I have done a lot of looking around and the closest thing I could find was a solution that requires building a backup table and moving all the columns (except the one to be deleted) into that backup table.
I can't figure out how I would do this, though. I add all the columns dynamically so their names are not defined as variables in my Java code. There doesn't seem to be a way to retrieve a column name by using Android's SQLiteDatabase.
SQLite has limited ALTER TABLE support that you can use to add a column to the end of a table or to change the name of a table.
If you want to make more complex changes in the structure of a table, you will have to recreate the table. You can save existing data to a temporary table, drop the old table, create the new table, then copy the data back in from the temporary table.
For example, suppose you have a table named "t1" with columns names "a", "b", and "c" and that you want to delete column "c" from this table. The following steps illustrate how this could be done:
BEGIN TRANSACTION;
CREATE TEMPORARY TABLE t1_backup(a,b);
INSERT INTO t1_backup SELECT a,b FROM t1;
DROP TABLE t1;
CREATE TABLE t1(a,b);
INSERT INTO t1 SELECT a,b FROM t1_backup;
DROP TABLE t1_backup;
COMMIT;
SQLite doesn't support a way to drop a column in its SQL syntax, so its unlikely to show up in a wrapper API. SQLite doesn't often support all features that traditional databases support.
The solutions you've identified make sense and are ways to do it. Ugly, but valid ways to do it.
You can also 'deprecate' the columns and not use them by convention in newer versions of your app. That way older versions of your app that depend on column C won't break.
Oh... just noticed this comment:
The app is (basically) an attendance tracking spreadsheet. You can add
a new "event" and then indicate the people that attended or didn't.
The columns are the "events".
Based on that comment you should just create another table for your events and link to it from your other table(s). You should never have to add columns to support new domain objects like that. Each logical domain object should be represented by its own table. E.g. user, location, event...
Was writing this initially. Will keep it if you're interested:
Instead of dynamically adding and removing columns you should consider using an EAV data model for that part of your database that needs to be dynamic.
EAV data models store values as name/value pairs and the db structure never needs to change.
Based on your comment below about adding a column for each event, I'd strongly suggest creating a second table in which each row will represent an event, and then tracking attendance by storing the user row id and the id of the event row in the attendance table. Continually piling columns onto the attendance table is a definite anti-pattern.
With regards to how to find out about the table schema, you can query the sqlite_master table as described in this other SO question - Is there an SQLite equivalent to MySQL's DESCRIBE [table]?
As per SQLite FAQ, there is only limited support to the ALTER TABLE SQL command. So, the only way you can do is that ou can save existing data to a temporary table, drop the old table, create the new table, then copy the data back in from the temporary table.
Also you can get the column name from the database using a query. Any query say "SELECT * FROM " gives you a cursor object. You can use the method
String getColumnName(int columnIndex);
or
String[] getColumnNames();
to retrieve the names of the columns.

Order of insert in android database

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.

Categories

Resources