Insert after event trigger in SQL Server - sql-server

I need to create a trigger in SQL Server for filling a table if an event is done.
My code:
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER TRIGGER [dbo].[Tr_EsportaMancatiContatti]
ON [dbo].[Lav_CollaudiVodaf_StoricoMancatiContatti]
AFTER INSERT
AS
BEGIN
DECLARE #IDPRATStorico INT;
DECLARE #IDPRAT INT;
DECLARE #CodRichiestaCRM INT;
DECLARE #IDESITO INT;
DECLARE #Telefono VARCHAR;
DECLARE #DataOraContatto INT;
SET NOCOUNT ON;
SET #IDPRATStorico = (SELECT IDPRATStorico FROM inserted);
SET #IDPRAT = (SELECT IDPRAT FROM inserted);
SET #CodRichiestaCRM = (SELECT CodRichiestaCRM FROM inserted);
SET #IDESITO = (SELECT IDESITO FROM inserted);
SET #Telefono = (SELECT Telefono FROM inserted);
SET #DataOraContatto = (SELECT DataOraContatto FROM inserted);
IF #IDESITO = 18 AND count(#IDPRAT) < 3
BEGIN
INSERT Lav_CollaudiVodaf_StoricoMancatiContatti
SET IDPRATStorico=#IDPRATStorico
SET CodRichiestaCRM=#CodRichiestaCRM
SET IDESITO=#IDESITO
SET Telefono=Telefono
SET DataOraContatto=#DataOraContatto
WHERE IdPrat=#IDPRAT;
END
END;
It throws some error.
Target: I have a table filled with contacts, I need to insert these record into another table, if the IDESITO is 18 and the count in the new table is < 3.
Any suggestion is appreciated.

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER TRIGGER [dbo].[Tr_EsportaMancatiContatti]
ON [dbo].[Lav_CollaudiVodaf_StoricoMancatiContatti]
AFTER INSERT
AS
BEGIN
SET NOCOUNT ON;
INSERT INTO Lav_CollaudiVodaf_StoricoMancatiContatti(
IDPRATStorico,
CodRichiestaCRM,
IDESITO,
Telefono,
DataOraContatto
)
SELECT TOP 3
IDPRATStorico,
CodRichiestaCRM,
IDESITO,
Telefono,
DataOraContatto
FROM INSERTED
WHERE IDESITO = 18
END;
I am not sure what you are trying to achieve with count(#IDPRAT) < 3. I guess you might want only the top 3 rows

Related

SQL server execute SP from sql table and update

The table below stores sql insert statements and I run those from a sp. I need to also add an insert to the last_run_dt column. I put the code together via existing stackoverflow questions. I need help implementing this in my code, any feedback will be helpful.
How can I update my code to update the last_run_dt column?
Table:
audit_sql_id audit_sql last_run_dt
1 select * from <<need to add last run_dt value>>
2 select * from <<need to add last run_dt value>>
Code:
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
alter proc [dbo].[sp_sqlAudit]
#packagename as varchar(255)
as
begin
set nocount on;
if #packagename='SQL_DM_AUDIT'
begin
declare #queries table (audit_sql_id int identity(1,1),sqlscript varchar(max))
declare #str_query varchar(max);
declare #startloop int
declare #endloop int
insert into #queries
select audit_sql
from dw.dbo.audit_sql with(nolock)
select #endloop = max(audit_sql_id), #startloop = min(audit_sql_id)
from #queries
while #startloop < = #endloop
begin
select #str_query = sqlscript
from #queries
where audit_sql_id = #startloop
exec (#str_query)
set #startloop = #startloop + 1
end
end
end
I would suggest a slight refactor something like the below. There's no need to bring the entire list of sql statements into TemDB, just iterate over it and get each statement in turn. I would also always add a #debug parameter to print the sql instead if executing.
create or alter procedure dbo.sqlAudit
#packagename as varchar(255)
as
set nocount on;
declare #str_query varchar(max), #Id int
declare #AuditID table (Id int)
if #packagename='SQL_DM_AUDIT'
begin
insert into #AuditID (Id) /* Get list of IDs */
select audit_sql_id
from dw.dbo.audit_sql
while exists(select * from #AuditID) /* Continue while there are IDs in the list */
begin
select top (1) #Id=Id from #AuditID /* Get an ID */
select #str_query=audit_sql /* Get the sql for the ID */
from dw.dbo.audit_sql
where audit_sql_id=#Id
delete from #AuditID where Id=#Id /* Remove this ID from the list */
begin try
exec (#str_query)
if ##Error=0
begin
update dw.dbo.audit_sql set last_run_dt=GetDate() /* Update date for ID if run successful */
where audit_sql_id=#Id
end
end try
begin catch
/*handle error*/
end catch
end
end
go

Only run trigger if value is FALSE

After some trial and error, along with your help, I have come up with the following code for my trigger:
ALTER TRIGGER [dbo].[SnapChapas]
ON [dbo].[Tab_Inventarios_Chapas]
AFTER UPDATE
AS
BEGIN
SET NOCOUNT ON;
IF UPDATE(Ativo)
DECLARE #IDInventario as INT
SET #IDInventario = (SELECT ID FROM inserted)
INSERT
INTO Tab_Inventarios_Chapas_Snap_Banco
( ID_Tab_Chapas,
FormatoL,
Comprimento1,
Comprimento2,
Largura1,
Largura2,
Quantidade,
ID_Tab_Inventarios_Chapas
)
SELECT ID,
FormatoL,
Comprimento1,
Comprimento2,
Largura1,
Largura2,
Quantidade,
#IDInventario
FROM Tab_Chapas
The code above is working. My problem here is: I Have a column called "ACTIVE" in [dbo].[Tab_Inventarios_Chapas]. I need the trigger to only run if the updated value is FALSE.
P.S.: My Application only updates one line at a time; there’s no way to update more than one.
Thanks to #JeroenMostert, I could find an answer.
Here is my final code:
ALTER TRIGGER [dbo].[SnapChapas]
ON [dbo].[Tab_Inventarios_Chapas]
AFTER UPDATE
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
Declare #ativo as bit
Set #ativo = (select Ativo from inserted)
if UPDATE(Ativo) and #ativo='False'
declare #IDInventario as int
Set #IDInventario = (select ID from inserted)
insert into Tab_Inventarios_Chapas_Snap_Banco (ID_Tab_Chapas,FormatoL,Comprimento1,Comprimento2,Largura1,Largura2,Quantidade,ID_Tab_Inventarios_Chapas)
select ID,FormatoL,Comprimento1,Comprimento2,Largura1,Largura2,Quantidade,#IDInventario
from Tab_Chapas
END
Thank You!

Trigger After Update for a Specific Value

Is it possible to create a trigger on SQL Server that will execute when a column value is updated to a specific value. How can I do this?
Try with following
CREATE TRIGGER trgAfterUpdate ON [dbo].[Employee_Test]
FOR UPDATE
AS
declare #empid int;
declare #empname varchar(100);
declare #empsal decimal(10,2);
declare #audit_action varchar(100);
select #empid=i.Emp_ID from inserted i;
select #empname=i.Emp_Name from inserted i;
select #empsal=i.Emp_Sal from inserted i;
if update(Emp_Name)
set #audit_action='Updated Record -- After Update Trigger.';
if update(Emp_Sal)
set #audit_action='Updated Record -- After Update Trigger.';
insert into Employee_Test_Audit(Emp_ID,Emp_Name,Emp_Sal,Audit_Action,Audit_Timestamp)
values(#empid,#empname,#empsal,#audit_action,getdate());
PRINT 'AFTER UPDATE Trigger fired.'
GO
I write a simple trigger and hoping that it helps you.
CREATE TRIGGER [FUND].[TRU_FUND_FUND_PRICE] ON [FUND].[FUND_PRICE]
AFTER UPDATE
AS
BEGIN
SET NOCOUNT ON;
DECLARE #PRICE_ID BIGINT
DECLARE #UNIT_PRICE DECIMAL(18,7)
DECLARE #UNIT_PRICE_BEFORE_UPDATE DECIMAL(18,7)
DECLARE #TOTAL_SHARE_BEFORE_UPDATE DECIMAL(18,7)
DECLARE #TOTAL_SHARE DECIMAL(18,7)
DECLARE #RECORD_STATUS_BEFORE_UPDATE CHAR(1)
DECLARE #RECORD_STATUS CHAR(1)
SELECT #UNIT_PRICE_BEFORE_UPDATE=UNIT_PRICE , #TOTAL_SHARE_BEFORE_UPDATE = TOTAL_SHARE, #RECORD_STATUS_BEFORE_UPDATE =RECORD_STATUS FROM DELETED
SELECT #PRICE_ID = PRICE_ID,#UNIT_PRICE=UNIT_PRICE,#TOTAL_SHARE=TOTAL_SHARE,#RECORD_STATUS=RECORD_STATUS FROM INSERTED
--You can compare to specific values instead of deleted data
IF #UNIT_PRICE=#UNIT_PRICE_BEFORE_UPDATE AND #TOTAL_SHARE =#TOTAL_SHARE_BEFORE_UPDATE AND #RECORD_STATUS_BEFORE_UPDATE = #RECORD_STATUS
BEGIN
RETURN
END
INSERT INTO FUND.FUND_PRICE_LOG (
[PRICE_ID],
[FUND_ID],
[PRICE_DATE],
[UNIT_PRICE],
[UPDATE_USER_CODE],
[UPDATE_PROG_CODE],
[UPDATE_DATE],
[OPERATION],
[RECORD_STATUS],
[TOTAL_SHARE],
[LIMIT_CHANGE_AMOUNT]
)
SELECT [PRICE_ID], [FUND_ID], [PRICE_DATE],
[UNIT_PRICE],
[UPDATE_USER_CODE],
[UPDATE_PROG_CODE],
GETDATE(),
'U',
[RECORD_STATUS],
[TOTAL_SHARE] ,
([TOTAL_SHARE] - #TOTAL_SHARE_BEFORE_UPDATE)
FROM INSERTED
END
GO

Delete statement not working in Stored Procedure

I am trying delete multiple records from store procedure SQL-Server 2012. I have select and then delete statement, apparently my delete statement is not been called
ALTER PROCEDURE [dbo].[DeleteFunctionsNavigation]
#FunctionName nvarchar(250),
#Function_identity INT OUTPUT
AS
BEGIN
SET NOCOUNT ON;
SELECT Navigation_Functions.Function_ID
FROM Navigation_Functions
WHERE Navigation_Functions.FunctionName = #FunctionName
SET #Function_identity=SCOPE_IDENTITY()
DELETE FROM Navigation_FunctionHierarchy
WHERE Navigation_FunctionHierarchy.Function_IDs = #Function_identity
RETURN
END
The usage of SCOPE_IDENTITY() is incorrect in this context. Try this
ALTER PROCEDURE [dbo].[DeleteFunctionsNavigation]
#FunctionName nvarchar(250),
#Function_identity INT OUTPUT
AS
BEGIN
SET NOCOUNT ON;
SELECT #Function_identity = Navigation_Functions.Function_ID
FROM Navigation_Functions
WHERE Navigation_Functions.FunctionName = #FunctionName
DELETE FROM Navigation_FunctionHierarchy
WHERE Navigation_FunctionHierarchy.Function_IDs = #Function_identity
RETURN
END

Delete multiple rows by sql statement "delete from tableName" whereas TRIGGER "After Delete" had applied on that

I have applied "After Delete" trigger on one table, below is the script:
ALTER TRIGGER [dbo].[onDelete_N_UR]
ON [dbo].[Notification_UnRead]
AFTER delete
AS
BEGIN
SET NOCOUNT ON;
declare #roid int
set #roid=(select ReachOutID from deleted(nolock)
where deleted.NotificaionType='reachoutlike')
update CACHE_Reachout
set CACHE_Reachout.LIKEcount=(select [dbo].[getReachout_Notification_Count](#roid,'like') )
where CACHE_Reachout.ReachOutID=#roid
END
Now I am trying to delete some rows in bulk using following sql statement:
delete from Notification_UnRead where Notification_ID=****
And it's giving me error
Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= or when the subquery is used as an expression."
How can I delete multiple rows using above delete statement when delete trigger applied on it .
Try this one -
ALTER TRIGGER [dbo].[onDelete_N_UR]
ON [dbo].[Notification_UnRead]
AFTER DELETE
AS BEGIN
SET NOCOUNT ON;
DECLARE #roid INT
SET #roid =
(
SELECT TOP 1 ReachOutID
FROM DELETED d
WHERE d.NotificaionType = 'reachoutlike'
)
UPDATE CACHE_Reachout
SET CACHE_Reachout.LIKEcount = dbo.getReachout_Notification_Count(#roid, 'like')
WHERE CACHE_Reachout.ReachOutID = #roid
END
Or try this (more preferably for using) -
ALTER TRIGGER [dbo].[onDelete_N_UR]
ON [dbo].[Notification_UnRead]
AFTER DELETE
AS BEGIN
SET NOCOUNT ON;
UPDATE t
SET LIKEcount = dbo.getReachout_Notification_Count(d.ReachOutID, 'like')
FROM CACHE_Reachout t
JOIN DELETED d ON t.ReachOutID = d.ReachOutID
WHERE d.NotificaionType = 'reachoutlike'
END
Either
set #roid=(select ReachOutID from deleted(nolock)
where deleted.NotificaionType='reachoutlike')
Or
set CACHE_Reachout.LIKEcount=
(select [dbo].[getReachout_Notification_Count](#roid,'like') )
where CACHE_Reachout.ReachOutID=#roid
is returning more than 1 row of data.
Raj
ALTER TRIGGER [dbo].[onDelete_N_UR]
ON [dbo].[Notification_UnRead]
AFTER DELETE
AS
BEGIN
SET NOCOUNT ON;
DECLARE #roid INT
SET #roid =
(
SELECT TOP 1 ReachOutID
FROM DELETED(nolock)
WHERE DELETED.NotificaionType = 'reachoutlike'
)
UPDATE CACHE_Reachout
SET CACHE_Reachout.LIKEcount =
(
SELECT [dbo].[getReachout_Notification_Count](#roid, 'like')
)
WHERE CACHE_Reachout.ReachOutID = #roid
END
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER TRIGGER [dbo].[onDelete_N_UR]
ON [dbo].[Notification_UnRead]
AFTER delete
AS
BEGIN
SET NOCOUNT ON;
declare #roid int
CREATE TABLE #TempTable (ReachOutID INT)
INSERT INTO #TempTable (ReachOutID)
select ReachOutID from deleted(nolock) where deleted.NotificaionType='reachoutlike'
DECLARE #getAccountID CURSOR
SET #getAccountID = CURSOR FOR
SELECT ReachOutID
FROM #TempTable
OPEN #getAccountID
FETCH NEXT
FROM #getAccountID INTO #roid
WHILE ##FETCH_STATUS = 0
BEGIN
update CACHE_Reachout set CACHE_Reachout.LIKEcount=(select [dbo].[getReachout_Notification_Count](#roid,'like') ) where CACHE_Reachout.ReachOutID=#roid
FETCH NEXT
FROM #getAccountID INTO #roid
END
CLOSE #getAccountID
DEALLOCATE #getAccountID
drop table #TempTable
END

Resources