Does my trigger updates all the records - sql

I have written a simple trigger which sets a column value with the id column value.
This is my trigger.
CREATE TRIGGER SubSectionsPrioritytrigger
ON SubSections
AFTER INSERT
AS
UPDATE dbo.SubSections
SET Priority = Id
After writing this trigger that, does this updates all the records after each insert. Or the only created new row.
Could some one provide any info on this.
Thanks.

To Update just the inserted row, you can do this:
UPDATE dbo.SubSections
SET SubSections.Priority = SubSections.Id
FROM INSERTED
WHERE INSERTED.Id = dbo.SubSections.Id

It does exactly what you wrote
UPDATE dbo.SubSections
SET Priority = Id
Any row will be updated.
You can change this to
UPDATE dbo.SubSections
SET SubSections.Priority = Inserted.Id
FROM INSERTED
WHERE INSERTED.id = SubSections.id
this will affect only the inserted rows.

to update just the last inserted row to what ever value you want you need to specify that row id which makes that row unique, from other rows.
and in your trigger you have not specified a where clause which causes all rows in the table to be updated.
whenever a any operation/event occurs on the table which has trigger associated with it mean a new record is inserted/updated or deleted an magic table is created in memory of SQL Server and we can access that magic table with the keyword "Inserted" in case of insert or Update and "Deleted" in case of delete.
so your query should be like this.
UPDATE dbo.SubSections
SET SubSections.Priority = SubSections.Id
FROM INSERTED
WHERE INSERTED.Id = dbo.SubSections.Id

Related

Database After Update Trigger From Inserted But Not Inserted? [SQL Server]

I'm trying to create a SQL Server trigger that when an update on table 1 happens in the val2 column, it takes that value and updates table2. I'm struggling to understand how to do this properly on something that sounds easy.
Image of tables
I believe my issue is trying to set a value that is not actually from inserted. (The only value getting updated is val2). I don't know how I can pair where to do the update other than grabbing the ID also on the updated row to compare to the place I want to update. Any help/advice on this would be greatly appreciated. Below is my current trigger that does not work.
CREATE TRIGGER Pull_ID on table1
AFTER UPDATE
AS
BEGIN
#id_ = id from inserted
#val2_ = val2 from inserted
UPDATE table2
SET val2 = #val2_
FROM
WHERE table2.id = #id_
END
You need to build your trigger so that it can handle multiple rows - always.
So you a proper set-based approach, not relying on the false assumption that you only get one row.
Try this:
CREATE TRIGGER Pull_ID on table1
AFTER UPDATE
AS
UPDATE table2
SET val2 = i.val2
FROM Inserted i
WHERE table2.id = i.id
The Inserted pseudo table contains all the rows that have been updated - their new values after the UPDATE. Join that table with your Table2 based on the primary key column (assuming that's the Id) and use a proper, set-based, multi-row capable single UPDATE statement - and you're done!

How do I prevent update on wrong data?

I have a scenario, like I want insert a record into a table, then I
update same record by getting the last inserted row Id, so now my
issue is if a another user inserts a new record before the first
record gets updated, so according to my scenario I get the last
inserted row Id , in this case update applied on the last row instead
of the first one, any solution please.
This is for SQL Server
if you have an Identity column in the Table, after inserting use the ##IDENTITY variable or SCOPE_IDENTITY() function to get the Identity value of the Row inserted and then while updating use the Identity Filed in the Where Clause.
Something like this
INSERT INTO MyTable(FullName)
VALUES('My Name')
SELECT #IdVal = SCOPE_IDENTITY()
UPDATE MyTable SET Phone='1234' WHERE IdCol = #IdVal

Insert trigger will not work properly

I am trying to create a database trigger that will update certain characters in a field for a table when a user inserts data into the table...
Ex.
ID EXCHANGE LEADRT
1 new L-3
2 new 3
3 new 5
So I would want to leave id 1 alone because the format for the LEADRT is correct but ids 2 and 3 are not.
CREATE TRIGGER triggerupdate ON PoleUnits FOR INSERT,
UPDATE AS
if not exists (select * from Poleunits where LEADRT like '%L-%')
update PoleUnits set LEADRT = STUFF (LEADRT, 1, 0,'L-');
Any ideas why I can't get this to work or better suggestions on how to accomplish this?
In insert and update triggers you have access to a specific table called inserted where the rows to be inserted/updated are held. Those are not real tables, they are just logical tables with the same structure as the table on which the trigger fired.
Your current logic works on the original table, thus working with all the existing data, but not with the data you are actually inserting, i.e. it will update everything except the data you actually want updated. Something like this could work:
CREATE TRIGGER triggerupdate ON PoleUnits
FOR INSERT, UPDATE AS
update PoleUnits
set LEADRT = STUFF (PoleUnits.LEADRT, 1, 0,'L-')
from PoleUnits
inner join inserted -- this is basically a self join
on PoleUnits.ID = inserted.ID
where PoleUnits.LEADRT not like '%L-%'
This will only update those rows in PoleUnits that are being inserted, and only if their LEADRT field is not in the L- format.

SQL Server insert trigger not working

This is my first time using triggers.
My trigger is not being triggered please help.
CREATE TRIGGER sbhack_autoban
ON LOG_CONNECT201211
FOR INSERT
AS
BEGIN
/* query to run if single or multiple data is
inserted into LOG_CONNECT201211 table */
UPDATE login.dbo.USER_CHECK_LOGIN
SET login.dbo.USER_CHECK_LOGIN.CHECKLOGIN = 2
WHERE login.dbo.USER_CHECK_LOGIN.USER_KEY IN
(SELECT e.USER_KEY
FROM game.dbo.CHAR_DATA0 AS e
INNER JOIN gamelogs.dbo.LOG_USING_DEPOT201211 AS p
ON e.CHAR_KEY = p.CHAR_KEY
WHERE p.GATENUM = 150)
AND login.dbo.USER_CHECK_LOGIN.CHECKLOGIN = 0
AND login.dbo.USER_CHECK_LOGIN.USER_KEY != 51;
END
This is suppose to run the query inside the BEGIN : END if an entry is inserted into the LOG_CONNECT201211 table. But nothing is happening even when I have inserted multiple data into LOG_CONNECT201211.
When your INSERT trigger fires - then at least one new row has been inserted! That's a fact.
Now the question is: given that a single or multiple new rows have been inserted - what do you want to do with this knowledge??
Typically, you could e.g. set a column to a value you cannot specify as a default constraint - or you could insert the fact that the row has been inserted into an audit table or something....
So you'd have something like this:
CREATE TRIGGER sbhack_autoban
ON LOG_CONNECT201211
FOR INSERT
AS
INSERT INTO LogAudit(InsertedDate, UserKey)
SELECT
GETDATE(), i.User_Key
FROM
Inserted i
or something like that....
Update: ok, so you want to run that UPDATE statement when the rows have been inserted - not 100% clear, what columns/values from the inserted rows you want to use - looks like the e.UserKey column only - correct?
Then the UPDATE would be:
UPDATE login.dbo.USER_CHECK_LOGIN
SET login.dbo.USER_CHECK_LOGIN.CHECKLOGIN = 2
WHERE
login.dbo.USER_CHECK_LOGIN.USER_KEY IN
(SELECT USER_KEY FROM Inserted)
AND login.dbo.USER_CHECK_LOGIN.CHECKLOGIN = 0
AND login.dbo.USER_CHECK_LOGIN.USER_KEY != 51;
Update #2:
The point I still don't understand is : why do you want to run an update that uses the USER_CHECK_LOGIN, CHAR_DATA0 and LOG_USING_DEPOT201211 tables, when some rows are getting inserted into a totally separate, unrelated table LOG_CONNECT201211 ??
A trigger is used when you want to do something because rows have been inserted into that table - but in that case, you typically want to do something with the rows and their values that have been inserted...
I just don't see any connection between the rows being inserted into LOG_CONNECT201211 event, and the tables you are then querying from and updating. Where's the link?? WHY do you need to run *this UPDATE when data is inserted into LOG_CONNECT201211 ?? It would make sense if data where inserted into one of the tables involved in the UPDATE - but like this, it just totally doesn't make any sense .....

Identity of inserted/updated row in trigger

I have the following trigger but need ti find the identity of the row so I don't update all records in the table. How can I get the identity of the affected row?
BEGIN
UPDATE tb_Division SET LastModified = GetDate() WHERE "id of inserted/updated row"
END
Since a trigger in MS SQL Server does not distinguish between single-record and multi-record operations, you should JOIN the table with the INSERTED pseudo table or use a subselect:
UPDATE tb_Division
SET LastModified = GETDATE()
WHERE id IN (SELECT id FROM INSERTED)
id being the primary key column of your table.
Have you looked at the id of the inserted logical table? You have to be careful when using triggers, as a trigger may be operating on more than one row:
UPDATE tb_Division AS td
SET LastModified = GetDate()
FROM INSERTED AS i
WHERE td.id = = i.id
See here for more details, and from MSDN:
DML triggers use the deleted and inserted logical (conceptual) tables. They are structurally similar to the table on which the trigger is defined, that is, the table on which the user action is tried. The deleted and inserted tables hold the old values or new values of the rows that may be changed by the user action. For example, to retrieve all values in the deleted table, use:
Mind you - a trigger can deal with a ton of rows at once - you'll have to take that into account!
You need to join your table to be updated with the Inserted pseudo-column on that ID field:
UPDATE dbo.tb_Division
SET LastModified = GetDate()
FROM Inserted i
WHERE tb_Division.Id = i.Id
or something like that.