Sql Trigger After Insert Update another table with conditions - sql

I am creating After Insert trigger , its working fine, but I have certain conditions before executing the statements inside the trigger
Based on Different CustomerId Run the trigger, I want check which CustomerId got inserted in my LoyaltyDetailsTable, say if last insert
was Customerid=2 then pass that Customerid in where condition then run
the trigger , or if Customerid = 1 then run the trigger for that Id,
so on.
I want to check whether in PriceClaimTable the inserted CustomerId exist or not, If exists then update the details else just insert the
values in LoyaltyDetailsTable only.
Trigger query
CREATE TRIGGER DetailsAfterInsert ON [dbo].[LoyaltyDetailsTable]
FOR INSERT
as
UPDATE PriceClaimTable
SET CurrentPoints =
(
(SELECT SUM(LoayaltyPointsTable.Points) AS RecentPoints FROM LoayaltyPointsTable
join LoyaltyDetailsTable ON LoayaltyPointsTable.LoyaltyPointsId
= LoyaltyDetailsTable.LoyaltyPointsId
WHERE CustomerId=1 and LoyaltyDetailsId= (SELECT MAX(LoyaltyDetailsId)
AS LoyaltyDetailsTable FROM LoyaltyDetailsTable))
+
(SELECT CurrentPoints FROM PriceClaimTable WHERE ClaimCustomerId=1 and
PriceClaimId=(SELECT max(PriceClaimId) FROM PriceClaimTable
))
)
WHERE ClaimCustomerId=1 and PriceClaimId=(SELECT max(PriceClaimId) FROM PriceClaimTable)
This is my first attempt to write a trigger, and here is table structure.
Any help would be great.

What you're looking for here is the inserted table. Every time you issue an UPDATE statement, SQL Server generates two virtual tables called inserted and deleted that store information on the data modifications you're making. These tables are accessible from your trigger. For more information, see here: https://msdn.microsoft.com/en-us/library/ms191300.aspx
You can use inserted to get the IDs you're looking for. So, instead of:
WHERE ClaimCustomerId=1
you can use:
WHERE ClaimCustomerId=inserted.ClaimCustomerId

Related

TSql Trigger To Delete Rows from Table1 Upon Insert to Table2

I've read and tried other posts/answers but am having a hard time getting this to work. I feel like it should be pretty simple for an experienced SQL programmer, but for me I'm ready to ask for help.
When I insert a record into the HistoricalWorkorders table, I simply want to delete any records with the same workorder # in the ActiveWorkorders table.
I'm trying to accomplish this using a trigger on insert.
I started simple by using the following code to insert into ActiveWorkorders every time a record is inserted into HistoricalWorkorders. That code works.
How do I modify this query such that upon insert to the HistoricalWorkorders table, any records with the same workorder # within the ActiveWorkorders table get deleted?
On a seperate note, everyone says you can reference the inserted record simply by referencing 'inserted', but it doesn't work for me? For example, shouldn't inserted.workorder return the workorder value being inserted to the table?
ALTER trigger [dbo].[WOArchive] on [dbo].[HistoricalWorkOrders]
after update,insert
as
begin
insert into ActiveWorkorders
(Workorder,Grindcount,Status)
select i.workorder, i.grindcount, i.status
from HistoricalWorkorders t
inner join inserted i on t.workorder=i.workorder
end

How to Update a Single record despite multiple Occurances of the same ID Number?

I have a table that looks like the below table:
Every time the user loan a book a new record is inserted.
The data in this table is derived or taken from another table which has no dates.
I need to update this tables based on the records in the other table: Meaning I only need to update this table based on what changes.
Example: Lets say the user return the book Starship Troopers and the book return is indicated to Yes.
How do I update just that column?
What I have tried:
I tried using the MERGE Statement but it works only with unique rows of data, meaning you get an error if the same ID appears more than once.
I also tried using a basic UPDATE Statement and a JOIN but that's not going well.
I am asking because I have ran out of ideas.
Thanks for reading
If you need to update BooksReturn in target table based on the same column in source table
UPDATE t
SET t.booksreturn = s.booksreturn
FROM target t JOIN source s
ON t.userid = s.userid
AND t.booksloaned = s.booksloaned
Here is SQLFiddle demo
You can do this by simple Update & Insert statement.....
Two table A & B
From B you want to insert data into A if not exists other wise Update that data....
,First Insert into temp table....
SELECT *
INTO #MYTEMP
FROM B
WHERE BOOKSLOANED NOT IN (SELECT BOOKSLOANED
FROM A)
,Second Check data and insert into A.
INSERT INTO A
SELECT *
FROM #MYTEMP
And at last write one simple update statement which update all data of A. If any change then it also reflect to that data otherwise data as it is.
You can also update from #MYTEMP table.

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 .....

Sql Server trigger insert values from new row into another table

I have a site using the asp.net membership schema. I'd like to set up a trigger on the aspnet_users table that inserted the user_id and the user_name of the new row into another table.
How do I go about getting the values from the last insert?
I can select by the last date_created but that seems smelly. Is there a better way?
try this for sql server
CREATE TRIGGER yourNewTrigger ON yourSourcetable
FOR INSERT
AS
INSERT INTO yourDestinationTable
(col1, col2 , col3, user_id, user_name)
SELECT
'a' , default , null, user_id, user_name
FROM inserted
go
You use an insert trigger - inside the trigger, inserted row items will be exposed as a logical table INSERTED, which has the same column layout as the table the trigger is defined on.
Delete triggers have access to a similar logical table called DELETED.
Update triggers have access to both an INSERTED table that contains the updated values and a DELETED table that contains the values to be updated.
You can use OLDand NEW in the trigger to access those values which had changed in that trigger. Mysql Ref
In a SQL Server trigger you have available two psdeuotables called inserted and deleted. These contain the old and new values of the record.
So within the trigger (you can look up the create trigger parts easily) you would do something like this:
Insert table2 (user_id, user_name)
select user_id, user_name from inserted i
left join table2 t on i.user_id = t.userid
where t.user_id is null
When writing triggers remember they act once on the whole batch of information, they do not process row-by-row. So account for multiple row inserts in your code.
When you are in the context of a trigger you have access to the logical table INSERTED which contains all the rows that have just been inserted to the table. You can build your insert to the other table based on a select from Inserted.
Create
trigger `[dbo].[mytrigger]` on `[dbo].[Patients]` after update , insert as
begin
--Sql logic
print 'Hello world'
end

what is the correct syntax for creating a database trigger for insert, modify and delete

i have what seems like a basic scenario for a db trigger in SQL server and i am running into an issue.
i have table Users (id, name, phone, etc) and i have tables UsersHistory (id, user_id action, fields, timestamp)
i want a database trigger where anytime inserts, updates or deletes into Users, i want a new record created in UsersHistory with the user id and the action that was done (insert new, updated fields, deleted id. Basically an audit log table.
this is how far i got, but i can't figure out how to:
Get the id on modify and deletes and also
How to get a list of fields that have changed and the action that was committed (insert, delete, update)
CREATE TRIGGER Update_Users_History
ON Users
AFTER INSERT,DELETE,UPDATE
AS
BEGIN
-- Insert statements for trigger here
insert into UsersHistory (user_id, [action], [fields], timestamp)
select max(id) as user_id, {action ??},{fields??} getdate() from Users)
END
GO
any suggestions?
The easiest might be to just simply create three triggers - one for each operation:
CREATE TRIGGER trgUserInsert
ON dbo.User AFTER INSERT
AS BEGIN
INSERT INTO dbo.UserHistory............
END
CREATE TRIGGER trgUserDelete
ON dbo.User AFTER DELETE
AS BEGIN
INSERT INTO dbo.UserHistory............
END
CREATE TRIGGER trgUserUpdate
ON dbo.User AFTER UPDATE
AS BEGIN
INSERT INTO dbo.UserHistory............
END
That way, things are simple and you easily understand what you're doing, plus it gives you the ability to turn off a trigger for a single operation, if you e.g. need to insert or delete a huge list of items.
Inside the trigger, you have two "pseudo-tables" - Inserted (for INSERT and UPDATE) and Deleted (for UPDATE and DELETE). These pseudo tables contain the values for the newly inserted values (or the updated ones in UPDATE), or the ones that were deleted (for DELETE) or have been updated (the old values, before the update, for the UPDATE operation).
You need to be aware that a trigger will be called once even if you update a huge number of rows, e.g. Inserted and Deleted will typically contain multiple rows.
As a sample, you could write a "AFTER INSERT" trigger like this (just guessing what your table structure might be....):
CREATE TRIGGER trgUserInsert
ON dbo.User AFTER INSERT
AS BEGIN
INSERT INTO
dbo.UserHistory(UserID, Action, DateTimeStamp, AuditMessage)
SELECT
i.UserID, 'INSERT', getdate(), 'User inserted into table'
FROM
Inserted i
END
You are looking for a way to find out which "action" this trigger caused? I don't see any way to do this - another reason to keep the three trigger separate. The only way to find this out would be to count the rows in the Inserted and Updated tables:
if both counts are larger than zero, it's an UPDATE
if the Inserted table has rows, but the Deleted does not, it's an INSERT
if the Inserted table has no rows, but the Deleted does, it's a DELETE
You're also looking for a "list of fields that were updated" - again, you won't have any simple solution, really. You could either just loop through the fields in the "Users" table that are of interest, and check
IF UPDATE(fieldname) ......
but that gets a bit tedious.
Or you could use the COLUMNS_UPDATED() function - this however doesn't give you a nice list of column names, but a VARBINARY in which each column is basically one bit, and if it's turned on, that column was updated. Not very easy to use.....
If you really want to create a single, big trigger, this could serve as a basis - it detects what operation has caused the trigger to fire, and will insert entries into your User_History table:
CREATE TRIGGER trgUser_Universal
ON dbo.Users
AFTER INSERT, UPDATE, DELETE
AS BEGIN
DECLARE #InsHasRows BIT = 0
DECLARE #DelHasRows BIT = 0
IF EXISTS(SELECT TOP 1 * FROM INSERTED)
SET #InsHasRows = 1
IF EXISTS(SELECT TOP 1 * FROM DELETED)
SET #DelHasRows = 1
DECLARE #TriggerAction VARCHAR(20)
IF #InsHasRows = 1 AND #DelHasRows = 1
SET #TriggerAction = 'UPDATE'
ELSE
IF #InsHasRows = 1
SET #TriggerAction = 'INSERT'
ELSE
SET #TriggerAction = 'DELETE'
IF #InsHasRows = 1
INSERT INTO dbo.UsersHistory(user_id, [action], [fields], timestamp)
SELECT i.UserId, #TriggerAction, null, getdate()
FROM INSERTED i
ELSE
INSERT INTO dbo.UsersHistory(user_id, [action], [fields], timestamp)
SELECT d.UserId, #TriggerAction, null, getdate()
FROM DELETED d
END
I haven't included the figuring out which fields have been updated part just yet - that's left as an exercise to the reader :-)
Does that help at all?
There are two "tables" that are used in the trigger. One is DELETED and one is INSERTED. When you delete a row, that row is captured in the DELETED table. When you insert a row, that row is captured in the INSERTED table. When you update a row, the old row is in the DELETED table, and the new row is in the INSERTED table. The DELETED and INSERTED tables have the same schema as the table on which you are adding the trigger.
You might check out this solution that will create a query for you that will make all the auditing triggers you want, as well as the table in which to store the audits, excluding any selected tables. It will only do UPDATE triggers, but could easily be modified to make INSERT and DELETE triggers as well.