I am trying to create a trigger to insert a record into one table when a record is created in another table. I have figured out how to do this however I am trying to figure out how to change a value of one of the columns value.
In the originating table I have 'County' and in the second table I have a 'CountyID' that comes from a 'County' table. How would I take the 'County' and convert it into a 'CountyID'?
My trigger so far -
CREATE TRIGGER [dbo].[AQB_RMS_LocationCreate] on [AVData].[dbo].[SourceSite]
AFTER INSERT
AS
BEGIN
INSERT INTO AQB_MON.[AQB_RMS].[Location]
([LocationName],[Latitude],[Longitude],[Enabled]
,[StreetAddress1],[StreetAddress2],[City],[CountyID],[StateAbbr],[ZipCode],[DATE_CREATED])
SELECT i.[Description],i.[Latitude],i.[Longitude],i.[Enabled]
,i.[StreetAddress1],i.[StreetAddress2],i.[City],i.[County],i.[StateRegion],i.[ZipCode], getdate()
from [AVData].[dbo].[SourceSite] ss
inner join inserted i on ss.SourceSiteID = i.SourceSiteID
END
GO
Wouldn't this work?
CREATE TRIGGER [dbo].[AQB_RMS_LocationCreate] on [AVData].[dbo].[SourceSite]
AFTER INSERT
AS
BEGIN
INSERT INTO AQB_MON.[AQB_RMS].[Location]
([LocationName],[Latitude],[Longitude],[Enabled]
,[StreetAddress1],[StreetAddress2],[City],[CountyID],[StateAbbr],[ZipCode],[DATE_CREATED])
SELECT i.[Description],i.[Latitude],i.[Longitude],i.[Enabled]
,i.[StreetAddress1],i.[StreetAddress2],i.[City],C.CountyId,i.[StateRegion],i.[ZipCode], getdate()
from [AVData].[dbo].[SourceSite] ss
inner join inserted i on ss.SourceSiteID = i.SourceSiteID
inner join dbo.County C on C.County = i.County
END
Related
I want to create a trigger that will fill up my sales history base after firing in the ORDER table.
I am creating a specific order in regular data base and after that this order automatically goes to sales_history database.
Below part works properly.
When I create a new order in regular database my sales_history database is growing with new ID_ORDERS, hooray! :)
ALTER TRIGGER [dbo].[InsertTrig]
ON [dbo].[ORDER]
AFTER INSERT
AS
IF EXISTS (SELECT *
FROM inserted i
WHERE i.ID_TYPE = 1) -- specific order type
BEGIN
INSERT INTO id.dbo.sales_history (id_order)
SELECT i.ID_ORDER FROM inserted i
END
The problem arises when I want join another table. The trigger stops working
ALTER TRIGGER [dbo].[InsertTrig]
ON [dbo].[ORDER]
AFTER INSERT
AS
IF EXISTS (SELECT *
FROM inserted i
WHERE i.ID_TYPE = 1) -- specific order type
BEGIN
INSERT INTO id.dbo.sales_history (id_order, id_item)
SELECT
inserted.ID_ORDER, ORDER_DETAILS.ID_ITEM
FROM
inserted
INNER JOIN
ORDER_DETAILS ON ORDER_DETAILS.ID_ORDER = inserted.ID_ORDER
END
I also tried this way, and still nothing :(
ALTER TRIGGER [dbo].[InsertTrig]
ON [dbo].[ORDER]
AFTER INSERT
AS
IF EXISTS (SELECT *
FROM inserted i
WHERE i.ID_TYPE = 1) -- specific order type
BEGIN
DECLARE #xyz AS numeric(18, 0)
SET #xyz = (SELECT inserted.ID_ORDER FROM inserted)
INSERT INTO id.dbo.sales_history (id_order, id_item)
SELECT
ORDER.ID_ORDER, ORDER_DETAILS.ID_ITEM
FROM
ORDER
INNER JOIN
ORDER_DETAILS ON ORDER_DETAILS.ID_ORDER = ORDER.ID_ORDER
WHERE
ORDER.ID_ORDER = #xyz
END
I want to create a trigger that will automatically fill up my sales history base after firing in ORDER table.
Your trigger is on the Order table, meaning SQL Server fires it after you insert records into the Order table. At which point, the relevant records in the Order_Details table couldn't have been inserted yet, because they have a foreign key to the Order table.
This is why an inner join between your inserted table and the Order_details table returns 0 rows.
If you want your sales_history from the order_details table, you have to populate it after you insert the records to the order_details table.
CREATE OR ALTER TRIGGER [dbo].[OrderDetails_AfterInsert]
ON [dbo].[ORDER_DETAILS]
AFTER INSERT
AS
INSERT INTO id.dbo.sales_history (id_order, id_item)
SELECT
inserted.ID_ORDER, inserted.ID_ITEM
FROM
inserted
INNER JOIN
[ORDER] ON [ORDER].ID_ORDER = inserted.ID_ORDER
WHERE [ORDER].ID_TYPE = 1 -- specific order type
As a side note: InsertTrig is bad name. Note the name of the trigger in my answer - it tells you exactly what this trigger is for, and on what table.
I am trying to insert values into another table with an after update trigger in the SQL server.
I have a table where I am storing my employees (employee_id, name, exam_results, exam_date) and I need to make a trigger that allows me to insert employee_id, exam_results, and exam_date into a table called exams_backlog whenever exam_results or exam_date is updated in table employees.
I don't know if I am able to check those fields to make the insert.
This is what I have so far:
CREATE TRIGGER updateExamBacklogTrigger
ON employees
AFTER UPDATE
AS
BEGIN
*****HERE IS WHERE I NEED TO CHECK IF ONE OF THOSE TWO FIELDS HAS BEEN UPDATED*****
INSERT INTO exams_backlog SELECT e.employee_id, e.exam_results, e.exam_date FROM employees e
SET NOCOUNT ON;
END
GO
Thanks in advance.
I have found the solution I've been looking for:
As I wanted to check if exam_results or exam_date had been updated I have used
IF(UPDATE(exam_results) OR UPDATE(exam_date ))
And then in order to only insert data for those employees that had been updated I used an
INNER JOIN inserted i ON i.employee_id = e.employee_id
So the complete trigger results as this:
CREATE TRIGGER updateExamBacklogTrigger
ON employees
AFTER UPDATE
AS
BEGIN
IF(UPDATE(exam_results) OR UPDATE(exam_date ))
INSERT INTO exams_backlog SELECT e.employee_id, e.exam_results, e.exam_date FROM employees e INNER JOIN inserted i ON i.employee_id = e.employee_id
SET NOCOUNT ON;
END
GO
We have a stored procedure that is used to UPDATE a table with a value calculated from an existing column.
I am trying to amend the stored procedure to also INSERT a row into a different table, using that same column's value but the column is being rejected by the parser as an invalid column name.
Here is a condensed version of the code. As originally supplied the sequence_no is known to the stored procedure and ends up in reference_no. i.e. the UPDATE works but the INSERT fails.
ALTER PROCEDURE [dbo].[update_references]
AS
-- Original contents:
UPDATE table1
SET reference_no = sequence_no
FROM table1 t1 WITH (NOLOCK)
LEFT OUTER JOIN proptable p1 WITH (NOLOCK) ON t1.checkval = p1.checkval
WHERE p1.fruit = 'apple'
-- I have added the INSERT
INSERT INTO table2 (next_seq_no)
VALUES (sequence_no)
The sequence_no is underlined in red in SSMS.
The insert statement in your code knows nothing about the previous update so you can't reference random columns from that and expect them to still be in scope. The easiest way of doing this is using the OUTPUT clause.
UPDATE table1
SET reference_no = sequence_no
OUTPUT INSERTED.reference_no INTO table2 (next_seq_no)
FROM table1 t1
LEFT OUTER JOIN proptable p1 ON t1.checkval = p1.checkval
WHERE p1.fruit = 'apple'
I am using a trigger on my table for update.
When I was updating 1 row, it works. But when I update 20 rows at once, the log only show 1 history update.
I want to show all updated rows. How to make it?
This my simple sql:
create trigger Triger_Update_Product
on product
for update
as begin
declare #first char(10)
declare #after char(10)
select #first = name from deleted
select #after = name from inserted
insert into historyproduk
select #first, #after, getdate()
end
You need to write the trigger in a set-based fashion and be aware that inserted and deleted will contain multiple rows - so these lines of code are really bad:
select #first = name from deleted
select #after = name from inserted
These select one arbitrary row from the update set - and they ignore all other rows. Don't do this!!
Try this instead:
create trigger Trigger_Update_Product
on product
for update
as begin
insert into historyproduk
select d.name, i.name, getdate()
from deleted d
inner join inserted i on d.PrimaryKey = i.PrimaryKey
end
You need to join the Inserted and Deleted pseudo tables on the primary key and then grab the Name from the old (deleted) and new (Inserted) and insert those - along with the date/time stamp - into the history table in a single INSERT ... SELECT .... statement to handle multiple rows being updated
In SQL Server, is possible to trigger an event based on a SELECT condition in another table?
Let's imaging this trigger in TABLE_1:
FOR INSERT AS
BEGIN
INSERT INTO TABLE_2 (ID, COD_CAT)
SELECT COD_ART,'X3'
FROM INSERTED
This trigger works fine and always.
I would like trigger that insert event only if INSERTED.COD_ART does not already exist in TABLE_2.
Any ideas?
use trigger on table1 and use 'if exists' before insert
...
FOR INSERT AS
BEGIN
IF not EXISTS
(SELECT COD_ART,'X3'
FROM INSERTED A LEFT JOIN TABLE_2 B
ON A.COD_ART = B.COD_ART
WHERE B.COD_ART IS NULL)
BEGIN
INSERT INTO TABLE_2 (ID, COD_CAT)
SELECT COD_ART,'X3'
FROM INSERTED
END
END
You can't have a selective trigger but you can insert selectively. Use LEFT JOIN to insert only non matching rows as below.
INSERT INTO TABLE_2 (ID, COD_CAT)
SELECT COD_ART,'X3'
FROM INSERTED A LEFT JOIN TABLE_2 B
ON A.COD_ART = B.COD_ART
WHERE B.COD_ART IS NULL