I've only started exploring with triggers recently. I've set up my database mail function and all is working well. My trigger works perfectly if the column value is changed, but how do I get the value/row that changed?
USE [database]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER TRIGGER [dbo].[triggerName] ON [dbo].[tableName]
FOR UPDATE
AS
declare #cust varchar(100);
if update(Column)
BEGIN
SET NOCOUNT ON
set #cust = THE VALUE MUST GO HERE I ASSUME
END
EXEC msdb.dbo.sp_send_dbmail
#recipients = 'someone#example.com',
#profile_name = 'ProfileName',
#subject = 'Customer Information Changed',
#body = #cust;
Compare the values in inserted and deleted. If they are not the same, then the value changed.
Related
One of my customer's website had been getting injection attack (inserting ads in emails) and at that time I didn't know how to handle the attack so I set trigger on update and delete to send me an email so I would know ads were added to table. However, I did not receive any email when values got changed.
ALTER TRIGGER [dbo].[TRIG_DEL]
ON [dbo].[A]
INSTEAD OF DELETE
AS
BEGIN
DECLARE #str VARCHAR(100)
SET #str = CONCAT('Someone is trying to delete A table at ', CURRENT_TIMESTAMP)
EXEC [msdb].[dbo].sp_send_dbmail
#profile_name = 'A_Email',
#recipients = 'abc#def.com;',
#subject = 'UPDATE ALERT',
#body = #str
END
This is my trigger and it works fine when I test it. Is there any way to avoid trigger? I just want to know how the attacker avoided the trigger, out of curiosity.
I am trying to create a trigger which should shoot a mail as soon a record is added to a said table. For this purpose I have created a the following trigger, which is sort of catering my requirement:
ALTER TRIGGER [dbo].[EMAIL_ALERT_NEW]
ON [dbo].[APTCR_LOG]
after insert
as
BEGIN
SET NOCOUNT ON;
DECLARE #body NVARCHAR(MAX) = N'';
SELECT AUDTUSER, NAMERMIT ,AMTRMITTC,IDRMIT FROM APTCR_LOG inserted
SELECT #body += CHAR(13) +++ CHAR(10) +++ RTRIM(AUDTUSER) +++ RTRIM(NAMERMIT) +++RTRIM(AMTRMITTC) +RTRIM(IDRMIT) FROM APTCR_LOG inserted;
--SELECT NAMERMIT, AUDTUSER ,AMTRMITTC FROM APTCR_LOG WHERE AMTRMITTC > 100000
BEGIN
--SELECT AUDTUSER, NAMERMIT ,AMTRMITTC,IDRMIT FROM APTCR_LOG inserted WHERE AMTRMITTC > 100000.000
EXEC msdb.dbo.sp_send_dbmail
#recipients = 'ublaze#gmail.com',
#profile_name = 'default',
#subject = 'NEW PAYMENT',
#body = #body;
END
end
The issue is it's sending all the records on the table where I just need the last record which was added in to the table.
Can somebody please help with this situation?
I have made a trigger to run upon insert of record, which should first check the current time and if it is beyond a particular hour and minute, it should fire the trigger and should take data from a table and use those values in the subject and body of the email.
Below is the trigger which is working fine but i need to add time condition and I tried to query a table based on the record inserted into the table but I am not getting the desired email.
As you can see that I tried to use a table value to be sent in the subject but I get the email with SQL Server Message in the subject.
Another thing I want to add is to query the table and check if the INSERTED.USERID is available in the table or not, if it is not available, then no need to fire the trigger.
USE [Attendance]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER TRIGGER [dbo].[after_insert_ATT_LOG] ON [dbo].[ATT_LOG]
FOR INSERT
AS
BEGIN TRY
DECLARE #PositionCode NVARCHAR(5), #FullNameE NVARCHAR(45), #FullNameE2 NVARCHAR(40), #Email NVARCHAR(50), #EDescription NVARCHAR(100), #ReportingToShortNo NVARCHAR(5), #ReportingtoFullNameE NVARCHAR(45), #ReportingEmail NVARCHAR(50)
Select #PositionCode=ED.POsitionCode, #FullNameE=EP.FullNameE,#FullNameE2=ED.FullNameE, #Email=ED.Email, #EDescription=EP.EDescription, #ReportingToShortNo=EP.ReportingToShortNo, #ReportingtoFullNameE=EP.ReportingtoFullNameE, #ReportingEmail=(Select Email
FROM HRSystem.dbo.employeedetails WHERE PositionCode= EP.ReportingToShortNo) FROM HRSystem.dbo.employeedetails ED, HRSystem.dbo.Position EP WHERE ED.PositionID = EP.PositionID AND ED.PositionCode = (Select INSERTED.USERID FROM INSERTED) COLLATE DATABASE_DEFAULT;
EXEC msdb.dbo.sp_send_dbmail
#recipients = 'abc#abc.com',
#profile_name = 'Alert',
#subject = #FullNameE,
#body = 'Test Alert';
END TRY
BEGIN CATCH
DECLARE #dummy int
SET #dummy = 1
END CATCH
as for your second concern
Another thing I want to add is to query the table and check if the INSERTED.USERID is available in the table or not, if it is not available, then no need to fire the trigger.
a FOR INSERT trigger fires right after a row is inserted. meaning, the USERID you wanna look for is sure to be in table ATT_LOG.
and as for your first issue. please try the t-sql code below:
CREATE TRIGGER [dbo].[after_insert_ATT_LOG] ON [dbo].[ATT_LOG]
FOR INSERT
AS
BEGIN TRY
DECLARE #PositionCode NVARCHAR(5), #FullNameE NVARCHAR(45), #FullNameE2 NVARCHAR(40), #Email NVARCHAR(50), #EDescription NVARCHAR(100), #ReportingToShortNo NVARCHAR(5), #ReportingtoFullNameE NVARCHAR(45), #ReportingEmail NVARCHAR(50)
Select #PositionCode=ED.POsitionCode, #FullNameE=EP.FullNameE,#FullNameE2=ED.FullNameE
, #Email=ED.Email, #EDescription=EP.EDescription
, #ReportingToShortNo=EP.ReportingToShortNo
, #ReportingtoFullNameE=EP.ReportingtoFullNameE
, #ReportingEmail=
(Select Email
FROM HRSystem.dbo.employeedetails
WHERE PositionCode= EP.ReportingToShortNo)
FROM HRSystem.dbo.employeedetails ED, HRSystem.dbo.Position EP
WHERE ED.PositionID = EP.PositionID
AND ED.PositionCode =
(Select INSERTED.PositionCode FROM INSERTED) COLLATE DATABASE_DEFAULT;
EXEC msdb.dbo.sp_send_dbmail
#recipients = 'abc#abc.com',
#profile_name = 'Alert',
#subject = #FullNameE,
#body = 'Test Alert';
END TRY
BEGIN CATCH
DECLARE #dummy int
SET #dummy = 1
END CATCH
i want to insert columns date, service and service_count from an existing table to a new table. i want to do it using a procedure but it's not working.
set ANSI_NULLS ON
set QUOTED_IDENTIFIER ON
go
ALTER PROC [dbo].[SP_INSERTCOLOUMNS]
AS
BEGIN
DECLARE #SQLS NVARCHAR(MAX)
SET #SQLS = 'insert into test(date,service,service_count)
select date,service,count(service) from tbl_OBD_CDRS
group by date,service'
PRINT #SQLS
EXEC SP_EXECUTESQL #SQLS
PRINT 'INSERTED SUCCESSFULLY'
END
if i run the insert command independently it works fine. if i run it using this procedure it says Command(s) completed successfully, but no changes are made in the table "test".
I don't see any issue in your script. Why don't you try to check count in Test table. See if no of records increases in your Test table.
set ANSI_NULLS ON
set QUOTED_IDENTIFIER ON
go
ALTER PROC [dbo].[SP_INSERTCOLOUMNS]
AS
BEGIN
select date,service,count(service) from tbl_OBD_CDRS
group by date,service
DECLARE #SQLS NVARCHAR(MAX)
SET #SQLS = 'insert into test(date,service,service_count)
select date,service,count(service) from tbl_OBD_CDRS
group by date,service'
PRINT #SQLS
EXEC SP_EXECUTESQL #SQLS
PRINT 'INSERTED SUCCESSFULLY'
END
Try to run this on SQL Server and post your result.
EXEC [dbo].[SP_INSERTCOLOUMNS]
ALTER PROC [dbo].[SP_INSERTCOLOUMNS]
AS
BEGIN
-- select date,service,count(service) from tbl_OBD_CDRS
-- group by date,service
insert into test(date,service,service_count)
select date,service,count(service) from tbl_OBD_CDRS Group by date,service
PRINT 'INSERTED SUCCESSFULLY'
END
use this if any error in table / datatype it throw directly
I created a trigger on a table, and now I can't alter or delete it.
I cant even access the table.
what can I do?
trigger script:
create trigger [Products].[InsertLessThen5InStock]
on [Products].[Products]
after update
as
BEGIN
DECLARE #ck int
select UnitsInStock from Products.Products where UnitsInStock<5
set #ck=##ROWCOUNT
print #ck
if #ck >0
BEGIN
DECLARE #mails varchar (200)
exec dbo.Manager_email #mails output
EXEC msdb.dbo.sp_send_dbmail
#profile_name = 'DefaultMailSender',
#recipients = #mails ,
#body = 'Products that will expire in less then 5 days',
#subject = 'Products that will expire in less then 5 days',
#body_format = 'HTML',
#query = 'EXECUTE MadCat.dbo.SaveTableAsHTML
#DBFetch =''select UnitsInStock from Products.Products where UnitsInStock<5'''
END
END
GO
Since it is complaining about not being able to get a lock, it means some process has reserved the table exclusively. You should try restarting the server, and then issuing the drop trigger command.
drop trigger [Products].[InsertLessThen5InStock]