How to refer to "New", "Old" row for Triggers in SQL server? - sql

SO I'm new to SQL server from SQLite and I am used to using the New|Old keywords. I have seen that some people use the inserted value refer to a newly created row, but this would only apply on an insert and not an update. Howe can I get something like the New I use in this query?
create trigger ports_country_id_in_check
on [SISTEMA].Puerto
after insert, update
AS
BEGIN
update [SISTEMA].Puerto
set country_id = (select secuencia from [SISTEMA].Pais where codigo = New.pais_asociado)
where [SISTEMA].Puerto.secuencia = New.secuencia
end

Inserted also will also apply to update. One updated row will be seen as a deleted and an inserted row. So you can check both what was and what it is now.

create trigger ports_country_id_in_check
on [SISTEMA].Puerto
after insert, update
AS
BEGIN
Declare #pais_asociado, #secuencia int
select #pais_asociado = Puerto.pais_asociado, #secuencia = Puerto.secuencia
from Puerto join inserted
where Puerto.secuencia = inserted.secuencia
update [SISTEMA].Puerto
set country_id = (select secuencia from [SISTEMA].Pais where codigo = #pais_asociado)
where [SISTEMA].Puerto.secuencia = #secuencia
end

Related

Update or otherwise create an entry in table

I want to update or create a new entry in a table with normal SQL (not MySQL).
My table has columns: T_ID, ITERATION, COMMENT
I know that I can update my table with:
UPDATE TABLE
SET ITERATION = ITERATION + 1
WHERE T_ID = 1;
But if no entry with T_ID = 1 exists I want to create an entry with ITERATION = 1 and T_ID = 1 and as COMMENT nothing.
Is this possible by using a normal SQL statement?
Is this possible by using a normal SQL statement?
No - there is no "standard" SQL construct for an "upsert" (or Merge) in one statement. Different SQL systems have implemented mechanism to perform an "update if exists" operation, such as MySQL's ON DUPLICATE KEY UPDATE or Oracle and SQL Server's MERGE syntax, but nothing in "standard" SQL.
You would want to do it in a stored procedure. Something like this where you're checking to see if anything exists where T_ID = 1. Then based off that conclusion you'll either update or insert.
BEGIN TRAN
IF EXISTS (SELECT * FROM table WHERE T_ID = 1)
BEGIN
UPDATE table SET ITERATION = ITERATION + 1 WHERE T_ID = 1
END
ELSE
BEGIN
INSERT INTO table (T_ID, ITERATION, COMMENT)
VALUES (1, 1, '')
END
COMMIT TRAN

SQL Server : create trigger to replace old value to new value on another table

I am using SQL Server 2008. I want to create a trigger for update which will fire on update of user table.
Trigger functionality: replace user_tbl updated mobile number to user_work_tbl.
CREATE TRIGGER [dbo].[tr_User_Modified]
ON [dbo].[user_tbl]
AFTER UPDATE
AS BEGIN
SET NOCOUNT ON;
DECLARE #MobileNo varchar(11)
IF UPDATE (mobile_no)
BEGIN
DECLARE #MobileNo VARCHAR(50)
SELECT #MobileNo = mobile_no
FROM [dbo].user_tbl
UPDATE [dbo].[user_work_tbl]
SET mobile_no = #MobileNo
WHERE [dbo].[user_work_tbl].mobile_no = #oldMobileNo // here I have a problem
END
END;
In the comment "here I have a problem" I need a mobile number which exists in user_tbl before update so that the only row of user_work_tbl gets updated.
Any suggestions to do this are also accepted.
Thanks for your all response
You need to join three tables together in your trigger - user_work_tbl, inserted and deleted. However, its not clear at the moment exactly what conditions are required:
CREATE TRIGGER [dbo].[tr_User_Modified]
ON [dbo].[user_tbl]
AFTER UPDATE
AS BEGIN
SET NOCOUNT ON;
IF UPDATE (mobile_no)
BEGIN
UPDATE u
SET mobile_no=i.mobile_no
FROM user_work_tbl u
inner join
deleted d
on u.mobile_no = d.mobile_no
inner join
inserted i
on
i.PKCol = d.PKCol --What's the PK of user_tbl?
END
END;
inserted and deleted are pseudo-tables that contain the new and old rows that were affected by a particular statement, and have the same schema as the original table. They're only accessible from within the trigger.
Note, also, that the above trigger is correct, even when multiple rows are updated in user_tbl - provided you can correctly relate inserted and deleted in the final ON clause.
You can get the old phone number from the table deleted and the new one from inserted, but you should use user primary key the update the rows.

SQL Server After Update Trigger - Single Table - 2 Columns

I have a table (dbo.membersdatatable) that has multiple columns. I would like this trigger to update a column called "memberstatus" when "memberdesignation" is updated to a value of "10" from a value of "9".
-------SQL STATEMENT BELOW---------------
IF UPDATE([MemberDesignation])
--need to make it so it will recognize when memberdesignation = 10
UPDATE dbo.MembersDataTable
SET MemStatus = '0'
FROM dbo.MembersDataTable AS mdtbl
INNER JOIN inserted AS i ON i.StudentID = mdtbl.StudentID
Use triggers SPARINGLY. For example, my system has 138 tables, 550 stored procedures and only 28 triggers. I wish I had less.
But if you decide a trigger is required, it will look something like this:
CREATE TRIGGER [t_MemberDesignationSideEffect] ON [dbo].MembersDataTable
FOR UPDATE
AS
SET NOCOUNT ON
IF NOT ( UPDATE([MemberDesignation]) ) RETURN
-- REMINDER: All triggers can and will fire for a set of rows...not just one
UPDATE mdtbl
SET MemStatus = '0'
FROM inserted i
JOIN dbo.MembersDataTable mdtbl on i.StudentID = mdtbl.StudentID
JOIN deleted d on d.StudentID = mdtbl.StudentID
WHERE i.memberdesignation = '10'
and d.memberdesignation = '9'
GO
You are writing an update trigger on table. Here you can use deleted and inserted magic tables. In case of update trigger:
Deleted table contains the row as it was before the UPDATE statement.
Inserted table contains the row as it is after the UPDATE statement.
create trigger update_member_status
on membersdatatable
for update
as
begin
declare #old_designation int
declare #new_designation int
set #old_designation = (select memberdesignation from deleted)
set #new_designation = (select memberdesignation from inserted)
if (#old_designation = 9 and #new_designation = 10)
begin
update membersdatatable
set memstatus = '0'
from membersdatatable as mdtbl
inner join inserted as i on i.StudentID = mdtbl.StudentID
end
end
You are going to update member status of all rows with a
memberdesignation = 10
you can probably add conditions to this query in order to update only the ones you want by using a date field or another
Simply call this procedure after updating your table
CREATE PROCEDURE USP_MemberStatusRules()
AS
UPDATE dbo.MembersDataTable
SET MemStatus = '0'
WHERE memberdesignation = 10
AND .....
AND .....
GO

SQL Trigger Using Variables

I need help creating this trigger, any help will be appreciate it, I can't save this script, it's saying 'Invalid column name OfferId'. But I checked all the columns names and they are correct
CREATE TRIGGER dbo.OrderOffer_UpdatedUnits
ON dbo.OrderOffer
FOR UPDATE
AS
BEGIN
DECLARE #OfferId char(5) SET #OfferId = (Select OfferId From INSERTED i, OrderOffer a Where i.OrderOfferid = a.OrderOfferid);
DECLARE #UnitsAvailable int SET #UnitsAvailable = (Select SUM(UnitsAvailable) From dbo.Offer Where OfferId=#OfferId);
UPDATE dbo.OrderOffer SET dbo.UnitsAvailable = #UnitsAvailable
FROM INSERTED i, OrderOffer a
WHERE i.OrderOfferid = a.OrderOfferid
END
Try this:
CREATE TRIGGER dbo.OrderOffer_UpdatedUnits
ON dbo.OrderOffer
FOR UPDATE
AS
BEGIN
UPDATE a
SET dbo.UnitsAvailable =
(
Select SUM(b.UnitsAvailable)
From dbo.Offer b
Where b.OfferId = a.OfferId
)
FROM OrderOffer a
INNER JOIN INSERTED i
ON i.OrderOfferid = a.OrderOfferid
END
NB: I removed the variables since that would assume you only updated one row at a time. Even if the update runs over multiple rows, the above should still work.

Creating a trigger to update multiple records after insert sql server 2008

Well basically I need this trigger to work after a user inserts multiple records into the database. So that when an optionID of 0 is inserted and the IsoptionalID = 1, then set the OptionID = NULL
CREATE TRIGGER ThisDatabase
ON OtherTable
AFTER INSERT
AS
BEGIN
DECLARE #OPTIONID INT
SET #OPTIONID = OtherTable.OPTIONID
DECLARE #ISoptional INT
SET #ISoptional = OtherTable.ISoptional
CASE #optionID WHEN 0 and #ISoptional = 1 set update OtherTable set optionid = null end
END
I am not sure about the case itself either.
Thank you in advance
This depends on the key field(s) of the table, but SQL Server triggers always work on the entire data set being modified (Inserted, Updated, or Deleted). So the trigger would something more like:
CREATE TRIGGER ThisDatabase
ON OtherTable
AFTER INSERT
AS
BEGIN
SET NOCOUNT ON
UPDATE ot
SET ot.OptionID = NULL
FROM OtherTable ot
INNER JOIN INSERTED ins
ON ins.KeyField = ot.KeyField
WHERE ins.OptionID = 0
AND ins.IsOptional = 1
END
The INSERTED table has the rows that were either Inserted or Updated (current version).
The DELETED table has the rows that were either Deleted or Updated (old version).
So, the INSERTED and DELETED tables are pre-filtered to only the changed records, but they are not updatable (since the event already happened due to this being an AFTER trigger and SQL Server not having a BEFORE trigger) so you need to do the UPDATE on the real table.
It isn't really clear what you want to do, but here's a skeleton. Just note:
Triggers are created on the table which is being affected (not an Other table)
You can certainly update another table as a consequence of a trigger. This is typically done through a join.
Use the inserted and deleted pseudo-tables to identify the record(s) which have been inserted, updated or deleted.
CREATE TRIGGER TR_TableBeingInsertedInto
ON TableBeingInsertedInto
AFTER INSERT
AS
BEGIN
UPDATE OtherTable
-- What you actually want to do here isn't clear to me
SET OtherTable.OPTIONID =
CASE i.OptionID
WHEN 0 THEN NULL
ELSE OtherTable.OPTIONID
END
FROM OtherTable
-- Inserted has the same schema as TableBeingInsertedInto
INNER JOIN INSERTED i
ON OtherTable.SomeCommonKey = i.SomeCommonKey;
END