Delete from 2 tables using INNER JOIN - sql

I have 3 tables.
InvoiceOriginal
Invoice
InvoiceHistory
the invoice table has a foreign key constraint.
Each entry in the invoice table has a corresponding entry in Invoiceoriginal.
The invoiceOriginal table stores the original values of the invoice and invoice table stores the values which have been modified by the user.
this is done to get diferrences at the time of submission.
the SQL I am using is
DELETE i
FROM invoice i
INNER JOIN InvoiceHistory aih
ON i.ClientId = aih.HistoryClientNumber
AND i.invoiceNumber = HistoryInvoiceNumber
however deletion is not possible because of foreign Key constraint.
The table is as under:
Invoice InvoiceOriginal InvoiceHistory
Id FK_InvoiceId ClientId
ClientId ClientId InvoiceNumber
InvoiceNumber
I need to delete the entry in invoice and InvoiceOriginal once there is an entry for that invoice number in InvoiceHistory for the same clientId.

You cannot issue a delete statement against more than one table at a time, you need to have individual delete statements for each of the related tables before deleting the parent record(s)

I'm fairly sure you can't delete from multiple tables with a single statement. I would normally delete the child rows first with one statement and then delete the parent record. You may wish to do this inside a transaction if you might need to roll back on failure.
Alternatively, you could enable CASCADE ON DELETE on the foreign key which would automatically cascade the deletions through the child records if that is something that is suitable for this system.

You can't delete the records from multiple table from a single query. But you have two methods to solve this
Delete all the related records from child or mapping table, and then
delete the Parent / header table record. (Multiple queries required here. Use SQL Transaction for a better control).
Or, Modify your foreign key constraint to ON DELETE CASCADE

Yes, YOU CAN, I did it right now:
DELETE T1,T2 FROM T1
INNER JOIN
T2 ON T2.FIELD = T1.FIELD
WHERE
T1.SOMETHING='SOMETHING'

Related

SSMS SQL - Create table with related columns

I have a DB Diagram with relationships on primary and foreign keys. Then I create a new table in the diagram, with foreign keys to 2 other tables. Example:
Tables in the diagram: Customers, Orders and Status
New table: View (with fk to Customers(CustID), Orders(OrID) and Status(SID))
In view table, I want a column Ordertype which should be a related/linked column to Orders table.
Meaning, that whenever I change a value of Ordertype in my new View table, it gets updated in the Orders table as well.
How can I achieve this? I guess I need sql script that adds such a related column to my view table.
What I have tried:
Relationship Orders(PK) and View(FK) has update property set to "Cascade".
Given same column name and datatype to Ordertype in both tables, Orders and View
But, this doesn't work for me.
Thanks.
Foreign key constraints can't help you to update data. You could try to use DML Trigger.
For example,
CREATE TRIGGER InsertUpdateTrigger ON View
AFTER Insert, Update AS
BEGIN
UPDATE O
SET O.OrderType = I.OrderType
FROM ORDERS O
JOIN INSRTED I on O.orid = I.id(change to your id)
END

Delete multiple rows of data from multiple tables in SQL

I need help of making a SQL query, when I delete the main category it should delete all the data of my subcategory and all the products related to that subcategory. Basically deleting data from 3 tables.
Can it be done in one query?
Cant give you code sample without a Database reference. But if all the tables have the same Primary key you can try using INNER JOIN.
DELETE table1, table2, table3
FROM table1
INNER JOIN table2 ON table2.key = table1.key
INNER JOIN table3 ON table3.key = table1.key
WHERE table1.key = value;
key value should be common accross all tables. Something like a "ID".
Instead of solving it via Sql, you could use foreign keys with the ON DELETE CASCADE setting enabled.
If you database type/version supports it.
F.e. ANSI SQL:2003, MySSQL, Oracle, PostgreSQL, MS SQL Server, SQLite
That way, when you delete from the main table. Then the records in the other table that reference to those deleted records, will automatically be deleted also.
For example in MS Sql Server:
ALTER TABLE SubCategory
ADD CONSTRAINT FK_SubCategory_MainCategoryID_Cascade
FOREIGN KEY (MainCategoryID)
REFERENCES MainCategory(ID) ON DELETE CASCADE;
ALTER TABLE Products
ADD CONSTRAINT FK_Products_SubCategoryID_Cascade
FOREIGN KEY (SubCategoryID)
REFERENCES SubCategory(ID) ON DELETE CASCADE;
It's a way to automatically maintain the referential integrity between them.
After that a delete from the MainCategory table will delete the related records from the SubCategory table. And also the Products that are related to the deleted SubCategory records.
And here is a db<>fiddle example for SQLite to demonstrate.
P.S. Personally I would prefere an ON DELETE SET NULL or an ON DELETE SET DEFAULT n, or even using triggers. Sure, that would require an extra cleanup of the unreferenced records afterwards, f.e. via a scheduled script. But it just feels less detrimental. Because then it's easier to fix when someone accidently deleted a MainCategory that shouldn't have been deleted.

SQL Server Trigger on Deleted - Which records are in deleted table?

I'm new to triggers, but I'm having a hard time understanding if I'm taking the right approach here.
I'm using SQL Server 2016. I have 2 tables, Teams and TeamMembers. Teams is the parent table and TeamMembers is the child, using Teams.TeamID as a foreign key.
I also have an Activities table that logs any creates or updates to any of my tables. This table has a TableName text column as well as an IdRow column that references the ID of the row that gets created or updated. I've also got a JSONChanges column which contains a JSON string of what was changed in that activity log item.
So there's only 1 record for each Activity on a table. But potentially many activities performed per record.
So, when a user deletes a team, I need to not only delete all of the Activities logged for that team and the Team Members for that team (which is easy to do within my Team_Delete stored procedure), but I also want to delete any records in my Activities table for the activities on the TeamMembers. Since the Activities table's IdRow column points at the TeamMemberID column in the TeamMembers table, I can't use the TeamID from the delete stored procedure.
My thought was to just create a delete trigger on the TeamMembers table.
Whenever a TeamMember was deleted, I could just delete all of the records in the Activities log that point to the record that was deleted. That would simplify my Team_DELETE stored procedure. I think.
The confusion I have has to do with the records that will be in the deleted table at any given time. If User A deletes a TeamMember, and at the same time, User B runs an Update on another Team Member, won't the deleted table have 2 records in it? If I delete all records in my Activities Table based on what's in the deleted table, then I'm deleting records I shouldn't be deleting. Right?
The other issue is how do I pick just one record to delete? How do I know which record in the deleted table is the one I want from the trigger?
If I had to use a trigger on TeamMembers , I would try:
CREATE TRIGGER [ schema_name .]DeleteTeamMemberActivities ON [ schema_name .]TeamMembers
AFTER DELETE
AS
DELETE
FROM
Activities a
INNER JOIN DELETED d ON d.TeamMemberID = a.IdRow AND a.TableName ='TeamMembers';
I would also use the cascading delete on the foreign key relation between Team and TeamMembers.
[edited 08/09/2017 12:45 correcting the a.TableName join]
FYI, I edited cclarke's code a little bit - here's what I ended up with:
CREATE TRIGGER TRIGGER_DeleteTeamMemberActivities ON TeamMembers
AFTER DELETE
AS
DELETE a
FROM
Activities a
INNER JOIN deleted d ON d.TeamMemberID = a.IDRow AND a.TableName
='TeamMembers';

Deleting rows from multiple tables

I created a query that will delete rows from three tables that has 'Employee'.
When I execute it, it only deletes rows from one table tblEmployeeType. I tried adding Alias of other tables beside DELETE but SQL does not support it. Is there any alternative way of deleting rows from multiple tables? or I forgot some codes on my query or should I just separate delete queries? Thank you.
DELETE a
FROM tblEmployeeType a INNER JOIN
tbl_Selected_AccessType b
ON a.EmpTypeName = b.UserType INNER JOIN
tbl_AccessType_AllFunction c
ON a.EmpTypeName = c.UserType
WHERE a.EmpTypeName = 'Employee'`
INSERT and UPDATE statements can only directly affect one table at a time. If you have foreign keys configured with ON DELETE CASCADE then child records will be deleted along with the parent record. Regardless of using cascade, you should have foreign keys on the table so that your DELETE doesn't leave orphaned child records with broken referential integrity.
Another way to achieve affecting other tables in an INSERT or UPDATE is by using a trigger on the table. This can be desirable when you want to do checks before blindly deleting child records.

Deleting using a join without where

I have two tables. adjustments and transactions. I want to delete all loan adjustments contained in transactions.
There are three corresponding fields to it. Date. ID. Value.
There are no fks. I used a delete join but it didn't work.
However when using a join it asks for me to specify data for trans.id. Trans.date. Trans.value. Is there anyway to forgo the where as I want to delete all of the related entries from adjustments in transactions.
If you want to delete all the row from Transactions table referencing in Adjustments table. There should be a column in Transactions table which references to some column in Adjustments table.
Suppose the ID column in your Transactions table References some ID column in Adjustments table then you would write this delete query something like this...
DELETE FROM Transactions
WHERE EXISTS ( SELECT 1
FROM Adjustments
WHERE ID = Transactions.ID)