Add new column in my table SQLite Database Android [duplicate] - android

I'm trying out statements for creating a database, and after 10 entities without any issues I ran into this error
Error: Near line 83: near "Transaction": syntax error
The first line is line 83 with it's context of creating a table
CREATE TABLE Transaction (
TransactionID INTEGER,
AccountID INTEGER REFERENCES User (AccountID),
ItemID INTEGER REFERENCES Item (ItemID),
Method STRING,
Price INTEGER,
TransactionDate DATE,
PRIMARY KEY (TransactionID)
);
Now I can't seem to find the issue, and suggestion's of something with ASCII using the wrong space couldn't be solved by writing the same thing again manually.
I haven't even gotten around to checking the integrity of my foreign keys, and it's not working. Hopefully somebody could provide some insight on what I'm missing.

Transaction is one of the reserved names in SQLite. For a full list see here.
Ways to solve this issue are:
Change the Table name to a word that isn't reserved.
or
Quote the reserved name by using one of these 4 listed quote marks
'keyword'
"keyword"
[keyword]
`keyword`

Related

SQLite in Android adding quotes to start and end of datelike string

Interesting issue while using SQLite in Android. I am seeing an inconsistency in the string length and quoting of a string between what is stored in the database and the materialized value seen in Java.
We are using an ORM called SugarORM to query the DB, but I've traced the offending code to the internal android.database.sqlite.SQLiteCursor class used within SugarORM, specifically the cursor.getString(columnIndex) method.
I have a string in the database that is an ISO data string 2019-03-25T19:19:39.664Z and is stored in a VARCHAR column . I have confirmed using DB Browser for SQLite that the length of the string as its stored in the database is indeed 24 characters. SELECT LENGTH(MyStringColumn) FROM MyTable WHERE ...
When I get the value of this string via cursor.getString(columnIndex), it is returning the string "2019-03-25T19:19:39.664Z". Notice the leading and trailing quotes. Java reports to me that the string is 26 characters long.
Any value that I store in this column that is not an ISO data does not have this behavior. I tried tracing the SQLiteCursor source back, but ultimately it ends up being a Native method and that's where my skill set stops.
Can anyone explain what might be going on here? I am probably just going to write a wrapper around my queries to get rid of the quotes, but its all very perplexing. The date string is being fed to a JavaScript interpreter and causing it to fail when creating a JavaScript Date object.
If it helps, I have replicated the behavior on both my S7 physical device and a Pixel 6 emulator.
As a quick get around you could use :-
SELECT length(replace(mystringcolumn,'"','')) FROM mytable;
or before using the original SELECT use :-
UPDATE mytable SET mystringcolumn = replace(mystringcolumn,'"','');
If this doesn't fix the issue, then for some reason it is the code that retrieves the data that is at fault.
e.g. consider :-
DROP TABLE IF EXISTS mytable;
CREATE TABLE IF NOT EXISTS mytable (mystringcolumn VARCHAR);
INSERT INTO mytable VALUES('2019-03-25T19:19:39.664Z'),('"2019-03-25T19:19:39.664Z"');
SELECT length(mystringcolumn), length(replace(mystringcolumn,'"','')) FROM mytable;
which results in :-
i.e. The 2nd row, 2nd column retrieves the appropriate value by using the replace function to strip of the quotes, if they exist.
As to why the quotes exist could depend upon either the way that the data is inserted (perhaps you have inadvertenly coded the quotes but the db being looked at isn't the actual database as copied from the App) or the way in which the data is being retrieved that for some reason adds them.
I don't believe it likely that the Cursor getString method has a bug in which the quotes are added, otherwise such an issue would likely be a recurring issue.

SQLiteLog Accessing the log or piping it out [Android]

Is there a way to access the SQLiteLog or at least pipe out errors to do with SQLite?
I would like to automatically send any errors, like the below, so I can optimise the database by adding in indexes, or making other changes as need be.
E/SQLiteLog: (284) automatic index on messages(chat_id)
It could well be that I'd only want to catch code 284, rather than getting everything. Is there a way of doing this when building the app, as would be useful to pass to crashlytics to help with development going forward
A potential alternative, would be to run the queries preceded with EXPLAIN QUERY PLAN, and to then check for AUTOMATIC COVERING INDEX in the results.
e.g.
DROP TABLE IF EXISTS table1;
DROP TABLE IF EXISTS table2;
CREATE TABLE IF NOT EXISTS table1 (column1 TEXT, column2 TEXT);
CREATE TABLE IF NOT EXISTS table2 (column3, column4);
EXPLAIN QUERY PLAN
SELECT * FROM table1, table2 WHERE column1=column3;
Results in :-
As you can see this is based upon a predication of the number of rows rather than the actual number of rows, so works if there is no data (as above), which could well be beneficial, from a development perspective, as opposed to trying to trap on a as happens basis.

Error with query in SQLite

My SQLLite query is not working properly. See below:
UUID i=UUID.randomUUID();
String Beregero ="INSERT INTO
contacts(id,uuid,name,phone,email,street,city,state,zip) " +
" VALUES(3,"+"'"+i.toString()+"'"+",'Patrice
Beregeron','978-555-1212','pBeregero#BostonBruins.com'," +
"'1 causeway street','Boston','Mass','01236');";
db.execSQL(Beregero);
I am receiving the following error in my log:
(table contacts has no column named uuid (code 1): , while
compiling: INSERT INTO contacts(id,uuid,name,phone,email,
street,city,state,zip) VALUES(3,'12ee5bbf-dabb-4d95-bfe7-6e6f14702add',
'Patrice Beregeron','978-555-1212','pBeregero#BostonBruins.com',
'1 causeway street','Boston','Mass','01236');)
#################################################################
The exception says it all, your table has no column name uuid created. So uninstall the app, then run it again. This error occurs only if the column is not generated.
The error message in you log clearly states the problem. The contacts table does not have a column uuid. You now could do the following:
Check if you have got right lower case vs. upper case. The column in question might be UUID instead of uuid (I don't know SQLite, but case matters in many database systems).
If the column really is not in the table yet, then add it (either by code or by hand). Read SQLite's documentation to learn how to that (I can't help you here because I don't know SQLite).
Uninstalling and re-installing the app would help only if the app would generate the database upon installing or during the first run. Since we don't know anything about the app, this might or might not be the case.
You have not added the column "uuid" in the create table "contacts" query like this :
String createTableContacts = "create table contacts ( ' uuid text ')";

INSERT OR REPLACE for sqlite rows with dependent foreign tables

Say I have table Book and table Page. Say that table Page has book's dbId as a foreign key. When I do an INSERT OR REPLACE on a Book row, does that change the dbId of the book?
Say the book is title="Song of Songs", author="King Solomon",pages=50" say that I want to change the title of the book and that will lead to replacement of the row. So the question is: will the replace cause the dbId of the book to change? I imagine it shouldn't, but I just don't know.
So this is about ON CONFLICT REPLACE
The documentation says about INSERT OR REPLACE:
When a UNIQUE or PRIMARY KEY constraint violation occurs, the REPLACE algorithm deletes pre-existing rows that are causing the constraint violation prior to inserting the current row and the command continues executing normally.
If the new dbId has the same value as the old one, it does not change (obviously). But if the constraint violation happens in another column, the new dbId might have a different value (especially if it's an autoincrementing column).
For implementing your idea :
1:) First get to foreign key from the first table using select query.
2:) then create a function with a parameter through which you can pass this foreign key in process of getting relevant data using the foreign key from the foreign table.
3:) Now use below query for fetching to related data using that key-
databaseObject.update(TABLE_NAME, values, COLOMN_NAME + " = ?",
Array_of_replacing_values);

SQLite-how to compare two column

friends,
I am doing an Android project in my company, still some small work is remaining, I need your help to complete the task.
The problem is...
I have created two tables in which, table1 has an empty column, for purpose for saving name...
The table2 has a list of names, the objective is only the names from this list should be should be saved in the table1's empty column other than that it shouldn't accept any of the name typed manually.
You appear to want to make the list of names a validation: if the user wishes to save a name to table1, the name must already exist in table2.
Typically this would be done as in the following example, in which only the products listed in PRIZEPRODUCTS can be entered into PRIZEWINNERS table: someone could not win a Boat, for example, given the data below:
PRIZEPRODUCTS
id
productname
1|TV
2|iPad
3|backpack
PRIZEWINNERS
id
productid
winner
ALTER TABLE PRIZEWINNERS
ADD CONSTRAINT PRIZEWINNERS_PRIZEPRODUCTS_FK
FOREIGN KEY(productid) REFERENCES PRIZEPRODUCTS(id)
SQLite doesn't create the foreign key using ALTER TABLE but as part of the create-table statement. See here for the syntax. For enabling foreign key support in Android (2.2), see here.
Now, you can establish the foreign key on the [productname] column if [productname] were the key of PRIZEPRODUCTS. In other words, you could make person-name the key of the table rather than having a PersonID. But if that name is changed in the validation table, it can break the foreign key relationship, unless ON UPDATE CASCADE is enabled, but I am not sure if this is supported in Android.
I hope below query will work for you.
insert into table1(name) values (select name from table2 where id=?).
Thanks.

Categories

Resources