I got sqlite DB on my android app to save reservations.
The one of the tables there contains the header of each reservation that may contain several parts of the reservation, each reservation has RES_ID while each part has PART_ID
the main table contains only the RES_ID as primary key, i have other tables that contains the parts in each of them PART_ID and RES_ID are both primary keys
i have a case in which i insert several part objects into the DB so eventually what happens is i try to insert a two or more rows with the same RES_ID to the table.
naturally i get SQLiteException, constrains violation since there's already a row with that primary key.
Is there an SQL statement or a java method\const that will notify SQLite that failing is ok and i don
't want the exception ? (just for that table)
Shouldn't this work :
INSERT ((SELECT v1 AS c1, v2 AS c2, ... , vn AS cn) EXCEPT tablename) INTO tablename;
?
Or similar :
INSERT ((SELECT v1 AS c1, v2 AS c2, ... , vn AS cn) WHERE NOT EXISTS (SELECT * FROM tablename WHERE pkc1 = pkv1 AND pkc2 = pkv2 AND ... AND pkcj =pkvj)) INTO tablename;
?
When I get your question right, you are looking for insert or replace. Click
replace is a shortcut for this.
There might be another way but indeed using replace instead of INSERT would do the job nicely.
Checking with the sqlite3 console client i was able to insert a non existing row into the talked about table. If the row already exists, the values will be updated anyway.
10x Jeff and janoliver!
Related
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);
My question involves databases - The scenario is this:
I have an app that tracks when people borrow items. I have an existing table which tracks who they are, what they have borrowed and so on. What I would like to do is create a separate table to track what the person has borrowed, their contact info, if they returned it, etc.
My idea to do this would be to create a Dynamic table in SQL that would hold the records for 1 person, ie
John Smith
DVD; July 12, 2012; Returned in good condition; etc
As I'm still learning, I wanted to know if:
This is possible, feasible or if there is a smarter way of going about it.
Your answer depends on your scenario;
If you are only interested with "who" borrowed "what" (currently) and not "when" except last occurance, and you are assuming there are always only 1 copy of an item, then you can use one to one relation as:
CREATE TABLE Person
(
PersonId int IDENTITY(1,1) NOT NULL,
Name nvarchar(30) NOT NULL,
Surname nvarchar(30) NOT NULL,
BorrowItemId int NULL FOREIGN KEY REFERENCES Item UNIQUE,
BorrowDate datetime NULL,
ReturnDate datetime NULL,
ReturnCondition nvarchar(50) NULL,
CONSTRAINT PK_Person PRIMARY KEY CLUSTERED (PersonId ASC),
)
CREATE TABLE Item
(
ItemId int IDENTITY(1,1) NOT NULL,
ItemDescription nvarchar(50) NOT NULL,
CONSTRAINT [PK_Item] PRIMARY KEY CLUSTERED (ItemId ASC)
)
If you have multiple copies of each item you should remove the UNIQUE key on BorrowItemId changing relation to one to many. In case;
To see the items borrowed and returned with person information:
SELECT PersonId, Name, Surname, ItemDescription, ReturnDate, ReturnCondition
FROM Person INNER JOIN Item
ON BorrowItemId = ItemId
WHERE BorrowItemId IS NOT NULL
AND ReturnDate IS NOT NULL
You can add PersonId filter in WHERE clause to query for specific person
This isn't a good design since you can insert records without date information or you can even have records with date info but no related BorrowItemId. I suggest using many to many and keep historic data (can be handy) or overwrite using update each time the person borrows a new item
Their contact information could be linked into the table which tracks who they are.
If you have not created a table yet for the returns then I suggest you reference the borrowing table's ID and set in the borrowing table a flag to say this item has been returned.
I am not too sure why you would want to create a new table to collate all the information. If you want to get all the information together then I suggest using the SQL keywrod JOIN when preparing statements. If you really want to store the information later on in a table you can but it will just be duplicates in your database.
A tutorial on the different types of joins you can do : http://www.w3schools.com/sql/sql_join.asp
It is definitely possible to do as you describe. It really isn't a very good strategy, though. Your new table is, exactly, equivalent to an additional column in the existing table that tags the row as belonging to a specific individual.
i am getting information from user in sqlite database.
But when i insert same record which is already in database it is added again.
how i can stop duplication of record in sqlite. I am developing this in android.
I am using mobile number as primary key. still it add that record in database.
Please suggest me appropriate solutions.
Thanks in advanced.
Be aware of the limitations of REPLACE or INSERT OR REPLACE as these will overwrite any custom data your app user has added to these rows in the database - it is not as advanced as UPSERT in other SQL databases.
As mentioned in a previous post you really need to identify what the primary key could be and use this information to either update old data or to remove an old row before inserting the fresh one.
If this is not possible then you could always DELETE FROM my_table or DROP my_table before running the insertions so that there will be no duplicates. This will (for better or worse) also make sure that data that is missing from new imports is not left lying around in your app.
make sure you have set your phone number as Primary Key at the time you created the table.
for example:
String query = "CREATE TABLE IF NOT EXISTS PhoneBook ("+
"TelNum VARCHAR(100) PRIMARY KEY NOT NULL,"+
"Address TEXT);";
db.execSQL(query);
and in case you want to enforce foreign keys defined in your table then call the following method before doing anything in your database
db.execSQL("PRAGMA foreign_keys = ON;"); //enforcing FK
Use REPLACE INTO keyword:
REPLACE INTO my_table (pk_id, col1) VALUES (5, '123');
This automatically identifies the primary key and finds a matching row to update, inserting a new one if none is found.
This may be a simple question as I have not done any database work for a while!
I have two tables with data like the below
Table 1
Rows with Primary Keys 1,2
Table 2
Rows with Foreign keys 1,2,3,4
I was to be able to perform a DELETE statement which will remove all rows from Table 2 that do not have a corresponding primary key in table 1, which in this case would result in only rows with foreign keys 1 & 2 being left in the table.
I should mention that this is on Android so I am using SQLite and also I am interested in the ease of doing this via a content provider.
Thanks for any help
Try this:
String SQL="DELETE FROM Table2
WHERE (Table2.FQ1,Table2.FQ2) NOT IN (SELECT PK1,PK2 FROM Table1)";
db.SQL(SQL);
But i'm not sure that the (Table2.FQ1,Table2.FQ2) sentence will run into the NOT IN
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.