SQL After trigger update value that triggers update - sql

I have 2 tables, shipment and invoice. I have an after trigger that updates the shipment table with the invoice number from the invoice table.The invoice table has their related shipment numbers, can be more than one for each invoice.
Create Trigger ShipmentInvoice
on Therefore.dbo.Invoice
For Insert
AS
Update cat set
invoice = Fac.invoice
FROM therefore.dbo.thecat10 cat
INNER JOIN therefore.dbo.vFacturaAlbaran alb
on alb.shipment COLLATE Modern_Spanish_CI_AS = alb.shipment
This Works but it updates the whole table every time. I need a way to update the shipment table only with the values that were recently added in the invoice table when the trigger is activated.
Edit
The trigger is over the invoice table. I am updating the shipment table with the invoice numbers from the invoice table.

This Works but it updates the whole table every time. I need a way to update the shipment table only with the values that were recently added in the invoice table when the trigger is activated.
That because you are joining both tables, you need to use INSERTED table to get only the inserted rows as :
Create Trigger ShipmentInvoice
on Therefore.dbo.Invoice
For Insert
AS
Update cat set
invoice = I.invoice
FROM therefore.dbo.thecat10 cat
INNER JOIN INSERTED I alb ON Cat.ID = I.ID
...

it seems odd that you are updating the table to you are already inserting into; why are you not resolving the correct value before hand? This is pseudo-sql, but will get you on the right path
CREATE TRIGGER ShipmentInvoice
ON Therefore.dbo.Invoice
FOR INSERT
AS
UPDATE cat
SET invoice = Fac.invoice --There is no table/alias Fac, where is this coming from? inserted?
FROM therefore.dbo.thecat10 cat
JOIN inserted i ON cat.{Primary/Foreign ID COLUMN} = i.{Primary/Foreign ID COLUMN}
INNER JOIN therefore.dbo.vFacturaAlbaran alb ON alb.shipment COLLATE Modern_Spanish_CI_AS = alb.shipment;
Note the items in the braces ({}) and also my comment about your object Fac.

Related

SQL insert trigger for insert with update

I have two tables:
[1] Donations - with amount and pet_id field
[2] Pets - with id and total donations field
I'm trying to create a trigger which will update total donations field whenever
a new row is being inserted to Donations table. I tried this one:
create trigger update_donations
on sponserships
for insert
as
update dbo.Pets
set tot_donations = (
select new_val = inserted.amount + pets.tot_donations
from inserted
where inserted.[Pet-ID] = pets.[Animal-ID]
)
But of course it changes all records, whereas i want to change only records that are changed in the donations table.
It is usually not a good practice to store this type of derived information - you could have a view that computes it on the fly rather than a trigger that keeps it up to date. Also please note that if you go that way, you also need a delete and an update trigger...
That said, you can use the following query in your insert trigger to update the relevant record in the pets table:
update p
set p.total_donations = p.total_donations + i.amount
from dbo.Pets p
inner join inserted i on i.[Pet-ID] = p.[Animal-ID]

updating values of a table from another table through a join changes all values to 1 single value

I have 3 tables: raw_sales, sales and details. raw_sales is being populated using COPY from a txt file. All the fields in raw_sales are either string or text. After importing, we run an sql to populate sales and details. There is a foreign key (sale_id) in details. Here's a sample INSERT command that we use to populate sales and details.
INSERT INTO sales (source, source_identifier)
(SELECT DISTINCT
'FOO' AS source,
"identifier" AS source_identifier
FROM raw_sales
LEFT JOIN sales
ON sales.source_identifier = raw_sales.identifier
AND sales.source = 'FOO'
WHERE sales.id IS NULL
AND identifier IS NOT NULL);
INSERT INTO details (sale_id, description)
(SELECT DISTINCT
sales.id AS sale_id,
"improvements" as description
FROM raw_sales
JOIN sales
ON sales.source_identifier = raw_sales.identifier
AND sales.source = 'FOO'
LEFT JOIN details AS existing
ON existing.sale_id = sales.id
WHERE existing.id IS NULL
AND "improvements" != '');
This seems to work fine. After this, there's another sql that's being ran to update existing tables. The query is as follows
UPDATE details SET
description = "improvements"
FROM raw_sales
JOIN sales
ON sales.source_identifier = raw_sales.identifier
AND sales.source = 'FOO'
JOIN details AS existing
ON existing.sale_id = sales.id
WHERE existing.id IS NOT NULL;
This query updates all rows in the details table to a single value, the first non-empty value from raw_sales table. How can I change the above sql so that it updates the existing records in the details table?
There are several problems with your query:
if details.id is a primary key (field id typically is), then what is the point in comparing it to NOT NULL? You're not using any left joins, there is no way it could possibly be NULL if it truly is an identifier.
UPDATE table t SET ... FROM ... requires linking the table t with something on the FROM section, but you're not, therefore each row of table will be updated to any single random row from the FROM results.
Perhaps you want to do this:
UPDATE details SET
description = "improvements"
FROM raw_sales
JOIN sales ON (sales.source_identifier = raw_sales.identifier AND sales.source = 'FOO')
JOIN details AS existing ON (existing.sale_id = sales.id)
WHERE existing.id = details.id;

Trigger with table join

I want to create a trigger to update stock inventory. My quantity on stock and quantity ordered by the client are on two different tables. How do i join both?
CREATE OR REPLACE
TRIGGER UPDATE_QUANTITY_TRIGGER
AFTER insert ON SALE_ORDER
FOR EACH ROW
BEGIN
update product values
(:old.product_id,
:old.product_name,
:old.description,
quantity_on_stock-s.quantity,
:old.minimal_quantity,
:old.unit_price,
:old.product_type_id);
from product, sale_order s
where product.product_id=s.product_id;
END;
OR
CREATE OR REPLACE
TRIGGER UPDATE_QUANTITY_TRIGGER
AFTER insert ON SALE_ORDER
FOR EACH ROW
BEGIN
update product set
p.quantity_on_stock= p.quantity_on_stock-s.quantity;
from product p , sale_order s
where p.product_id=s.product_id;
END;
The sale_order table has columns sale_no, quantity, and product_id.
You can't join in an update statement. Your second attempt is closer but is still joining, and has no correlation. You also have a stray semicolon. I think you're looking for something like:
CREATE OR REPLACE
TRIGGER UPDATE_QUANTITY_TRIGGER
AFTER insert ON SALE_ORDER
FOR EACH ROW
BEGIN
update product p set
p.quantity_on_stock = p.quantity_on_stock - :new.quantity
where p.product_id = :new.product_id;
END;
This uses the values from the :new pseudorecord to both identify the product record to be updated, and to get the quantity to decrement the stock level by. There is no need to join to the triggering table again - which isn't allowed anyway.
You may run into unexpected behaviour or results doing this kind of update in a multiuser environment though.

How can I update and replicate one column from one table to another column from another table?

I need to replicate one column (TYPE) from one table (CUTOMER) to another column (UNDEF000) from table (ORDERS), by this way everytime when someone update column(TYPE) to be automaticaly replicated on (UNDEF000), Table CUSTOMER and ORDERS are linked by column (PRE_ORDERCODE).
First I try to fill UNDEF000 from TYPE:
UPDATE ORDERS
JOIN CUSTOMER
SET ORDERS.UNDEF000=CUSTOMER.TYPE
WHERE ORDERS.PRE_ORDERCODE= CUSTOMER.PRE_ORDERCODE;
not function :(
UPDATE ORDERS
SET ORDERS.UNDEF000= CUSTOMER.TYPE
FROM CUSTOMER CUSTOMER
INNER JOIN ORDERS ORDERS
ON CUSTOMER.PRE_ORDERCODE= ORDERS.PRE_ORDERCODE
Can you please help me with this two problems?
I think your update should be like:
UPDATE ORDERS O SET O.UNDEF000= (
SELECT CUSTOMER.TYPE FROM CUSTOMER
WHERE CUSTOMER.PRE_ORDERCODE = O.PRE_ORDERCODE);
Trigger code:
create or replace trigger after_update_customer after update on
customer for each row
declare
begin
update orders set UNDEF000 = :new.type
where pre_ordercode = :new.pre_ordercode;
end;

SQL: insert records is not in order

I am having a problem while a record is inserted into a table.
each parking_cost is inserted after its related record. It should be with its record. why is this happening?
Any ideas ?
Regards.
If you are doing two separate queries to populate the row in the table, the first query needs to be an INSERT, the second query needs to be an UPDATE, eg:
INSERT INTO Customers (Pre_Payed_Card, Parking_ID) VALUES ('1234', 1)
Then
UPDATE Customers SET Parking_Cost = <cost> WHERE Parking_ID = 1
An INSERT will always create a new row; two INSERT queries for the same logical entity will result in two separate rows like you have in the screenshot.
Update: re-reading that query, you're probably after something like
UPDATE Customers SET Parking_Cost = p.Parking_Cost
FROM Customers c INNER JOIN Parking p ON c.Parking_ID = p.Parking_ID
WHERE c.Parking_ID = 1