How do you delete a row from two separate tables? I thought it would be possible to do this using an inner join
DELETE a.*, b.* FROM Holiday INNER JOIN Accommodation b on a.LocationID = b.LocationID
Here i try to delete by matching the primary key location in the first table to the location id in the second table. I get an SQL Exception "sqlException near a"
Im doing this in SQLITE, java
In SQLite, one DELETE command deletes from only one table.
Your query, as written, doesn't actually restrict the records to be deleted, so if you really want to delete all records, you would use this:
DELETE FROM Holiday;
DELETE FROM Accommodation;
If you want to delete one record in the master table and all corresponding records in the child table, you just filter by that key value:
DELETE FROM Holiday WHERE LocationID = 1;
DELETE FROM Accommodation WHERE LocationID = 1;
Related
When I am copying rows from one table to another, there is a convenient syntax:
INSERT INTO table1 SELECT * FROM table2 WHERE <table 2 rows have some property>
But what if I want to overwrite entire existing rows in table1 with entire rows from table2? So I want something like:
UPDATE table1 SET * FROM table2 WHERE <table 1 and 2 rows match on some key field>
But from what I can tell, the only way to do this is to enumerate the columns being set one by one (set table1.columnA = table2.columnA, table1.columnB = table2.columnB, and so on). Is there some way to say "do it for all the columns" when using UPDATE like there is when using INSERT? If not, why not?
(I guess I could delete all rows from table1 with the given property, and then use the INSERT INTO table1 SELECT * syntax to bring in the replacement rows from table2. But that seems like it leaves a bunch of unwanted deleted rows in the database needing to be vacuumed at some point, as opposed to a clean UPDATE where there are no deleted records? Or maybe I'm not understanding the efficiency of a bunch of deletes followed by a bunch of inserts?)
There is no such syntax for exactly what you have in mind, and I think you will need to SET each column separately. Also, SQLite does not support a direct update join syntax, but we may use correlated subqueries:
UPDATE table1
SET table1.columnA = (SELECT columnA FROM table2 WHERE table1.col = table2.col),
SET table1.columnB = (SELECT columnB FROM table2 WHERE table1.col = table2.col),
SET table1.columnC = (SELECT columnC FROM table2 WHERE table1.col = table2.col);
I have a database normalized like the one on the picture bellow. I store the clients, the accounts and the postal address for each account. As you can notice, the Client-Account relationship type is many-to-many, there for the ClientAccount table.
Since I have a database with 100k Account records I'm considering the use of SQL Bulk Copy. I think that I could use a stage table with all the fields of the tables above, and then normalize the data.
My problem is that I don't know how to move the data to the production tables. How can I create a stored procedure to perform this job, after the bulk insert import?
PS: The database is for as ASP .Net Web Site with the EF enabled.
You must insert one table at a time in the right order
Address -> Account -> Client -> AccountClient
create the addresses:
Insert into Address(data)
Select distinct address_data From temp
Account
Inser Into Account(account_number, address_id)
Select t.account_number, a.id From temp t
Inner Join Address a on a.data = t.address_data
Client
Insert into Client(name, client_number)
Select distinctname, client_number From temp
Client Account
Inser Into ClientAccount(accountId, clientId)
Select a.accountId, c.clientId From temp t
Inner Join Client c on c.name = t.name and c.client_number = t.client_number
Inner Join Account a on a.account_number= t.account_number
Make sure:
you don't create duplicate if some of the data are already there
you match on rows between real and temp table on the right columns
i have the following problem. I have three tables, TABLE_1, TABLE_2 and TABLE_3.
Between TABLE_1 and TABLE_2 is a m:n relationship so theres a connecting table
lets call it TABLE_1_2.
Between TABLE_2 and TABLE_3 is a m:n relationship so theres a connecting table
lets call it TABLE_2_3.
If i delete now a row from TABLE_1 i want that all rows from the other tables connecte also will be deleted.
How can i handle this? i read that sqlite doesnt supports joins for delete statements.
In MS SQL this can be made via altering the table1 and corresponding column by adding ON DELETE CASCADE CONSTRAINT on this column. But in SQLite there is no ALTER COLUMN and ALTER TABLE is also much less functional than in MS SQL. That's why you'll probably have to
Rename the table1 to a table3
Create a new table with ON DELETE CASCADE CONSTRAINT and all other constraints you've already used.
Copy the content of the old table to the new one.
Remove the old table
See also the similar topic.
How can I delete a particular record in a DataBase where 6 tables are joined among each other.
It is possible to create the FOREIGN KEY (with "ON DELETE CASCADE" action) Constraint(s) that will automatically remove records from the corresponding referenced tables. Take a look at the “FOREIGN KEY Constraints” Books Online / MSDN topic for more information.
Do it within a transaction. Referential integrity isn't checked until the transaction is closed:
begin;
delete from table1 where ...;
delete from table2 where ...;
delete from table3 where ...;
commit;
I need to delete rows from an SQLite table where their row IDs do not exist in another table. The SELECT statement returns the correct rows:
SELECT * FROM cache LEFT JOIN main ON cache.id=main.id WHERE main.id IS NULL;
However, the delete statement generates an error from SQLIte:
DELETE FROM cache LEFT JOIN main ON cache.id=main.id WHERE main.id IS NULL;
The error is: SQLite Error 1 - near "left": syntax error. Is there another syntax I could use?
SQLite apparently doesn't support joins with the delete statement, as you can see on the Syntax diagrams. You should however be able to use a subquery to delete them.
ie.
DELETE FROM cache WHERE id IN
(SELECT cache.id FROM cache LEFT JOIN main ON cache.id=main.id WHERE main.id IS NULL);
(Not tested)
Since you going down the route of subquery, might as well get rid of the join altogether and simplify the query:
DELETE FROM cache WHERE id NOT IN (SELECT id from main);
Solution from #wimvds didn't work for me, so I modified the query and removed WHERE condition:
DELETE FROM FirstTable WHERE firstTableId NOT IN (SELECT SecondTable.firstTableId FROM SecondTable LEFT JOIN FirstTable ON FirstTable.firstTableId=SecondTable.firstTableId)
This deletes all the rows from FirstTable that do not have their id assigned to any row in SecondTable.