SQL Server triggers if else statement - sql

What is missing in this code? If I'm updating the status of worker and the deleted status is 6, it should only execute the first nested if statement, not in the second if else statement but in this scenario when i update the worker status even if the data that is deleted is 6 it execute the two if else statement.. Any help, or suggestions is a big help for me..
Here is my code
if exists(select * from inserted) and exists(select * from deleted)
begin
select
#Worker_id = ID,
#StatusID = StatusID,
#Date = GETDATE()
from
inserted;
select
#oldStatusID = StatusID
from
deleted;
if(#StatusID <> #oldStatusID)
if(#oldStatusID = 6)
if(#StatusID = 1 or #StatusID = 2 or #StatusID = 3)
begin
select
#Description = FirstName + ' ' + LastName + ' has been Hired'
from
inserted;
EXEC sp_history #Worker_id,'HIRED',#Description,#Date
end
else if(#oldStatusID = 1 or #oldStatusID = 2 or #oldStatusID = 3 or #oldStatusID = 4 or #oldStatusID = 5 or #oldStatusID = 9)
if(#StatusID = 1)
begin
select
#Description = FirstName + ' ' + LastName + ' has changed its status into Laborer'
from
inserted;
EXEC sp_history #Worker_id,'CHANGED STATUS(laborer)',#Description,#Date
end
if(#StatusID = 2)
begin
select
#Description = FirstName + ' ' + LastName + ' has changed its status into Main Office'
from inserted;
EXEC sp_history #Worker_id,'CHANGED STATUS(main office)',#Description,#Date
end
if(#StatusID = 3)
begin
select
#Description = FirstName + ' ' + LastName + ' has changed its status into Admin'
from inserted;
EXEC sp_history #Worker_id,'CHANGED STATUS(admin)',#Description,#Date
end
if(#StatusID = 4)
begin
select
#Description = FirstName + ' ' + LastName + ' has changed its status into Blocklisted'
from inserted;
EXEC sp_history #Worker_id,'BLOCKLISTED',#Description,#Date
end
if(#StatusID = 5)
begin
select
#Description = FirstName + ' ' + LastName + ' has changed its status into Terminated'
from inserted;
EXEC sp_history #Worker_id,'TERMINATED',#Description,#Date
end
if(#StatusID = 9)
begin
select
#Description = FirstName + ' ' + LastName + ' has changed its status into Resigned'
from inserted;
EXEC sp_history #Worker_id,'RESIGNED',#Description,#Date
end
end

Related

How can i optimize the Trigger

I have checked a lot of Question asked Previously but was not able to get how do optimize this trigger
ALTER trigger [dbo].[Expample]
on [dbo].[AdminUsers]
for update
as begin
declare #Id int
declare #new_val nvarchar(max)
declare #old_val nvarchar(max)
Declare #AuditString nvarchar(max)
Select *
into #TempTable
from inserted
While(Exists(Select Id from #TempTable))
Begin
Set #AuditString = ''
Select Top 1 #Id = Id,#new_val = Fname
from #TempTable
Select #old_val = Fname
from deleted where Id = #Id
Set #AuditString = 'Id = ' + Cast(#Id as nvarchar(4)) + ' changed'
if(#old_val <> #new_val)
Set #AuditString = #AuditString + ' NAME from ' + #old_val + ' to ' + #new_val
insert into [dbo].[tbl_audit] (Id,Auditdata) values(#Id,#AuditString)
-- Delete the row from temp table, so we can move to the next row
Delete from #TempTable where Id = #Id
end
end
How I have changed this code to
ALTER trigger [dbo].[Expample]
on [dbo].[AdminUsers]
for update
as begin
declare #Id int
declare #new_val nvarchar(max)
declare #old_val nvarchar(max)
Declare #AuditString nvarchar(max)
Begin
Set #AuditString = ''
Select Top 1 #Id=inserted.Id,#new_val =inserted.Fname,#old_val = deleted.Fname from inserted join deleted on inserted.Id=deleted.Id
-- Select Top 1 #Id = Id,#new_val = Fname
-- from #TempTable
--Select #old_val = Fname
--from deleted where Id = #Id
Set #AuditString = 'Id = ' + Cast(#Id as nvarchar(4)) + ' changed'
if(#old_val <> #new_val)
Set #AuditString = #AuditString + ' NAME from ' + #old_val + ' to ' + #new_val
insert into [dbo].[tbl_audit] (Id,Auditdata) values(#Id,#AuditString)
-- Delete the row from temp table, so we can move to the next row
end
end
Thanks for Help
I have not been able to test it, but it appears this is what you are trying to accomplish:
ALTER trigger [dbo].[Expample]
on [dbo].[AdminUsers]
for update
as begin
insert into [dbo].[tbl_audit] (Id, Auditdata)
select t1.Id, 'Id = ' + Cast(t1.Id as nvarchar(4)) + ' changed NAME from ' + t2.Fname + ' to ' + t1.Fname
from inserted t1
join deleted t2 on t2.Id = t1.Id and t2.Fname != t1.Fname

I am using cursor to fetch rows from a temp table but else if condtion is not working, is this a good approch to do these type of task on MSSQL?

i have a temp table having record id, module id and status id, now i have to check every row of that temp table and according to #levelid i have to update corresponding table with that status id,
but below code never goes to else if condition, i am new to mssql seeking for your valuable answers :)
DECLARE #MyCursor CURSOR;
DECLARE #LevleId INT,
#STATUS VARCHAR(max),
#RECID VARCHAR(max);
BEGIN
SET #MyCursor = CURSOR
FOR SELECT TOP 1000 level_id,
status_id,
record_id
FROM #temp_record_id_typ2
WHERE approval_typ_id = 2
OPEN #MyCursor
FETCH next FROM #MyCursor INTO #LevleId, #STATUS, #RECID
WHILE ##FETCH_STATUS = 0
BEGIN
IF ( #LevleId = 1
AND #STATUS != 3 )
BEGIN
SELECT #Update_Typ2_Rec = N'UPDATE hrms_approvals SET approval_status_id = ' +
#STATUS
+ ' WHERE record_id = ' + #RECID
+ ' AND module_id = ' + #Module_id +
' ';
--SELECT #Update_Typ2_Rec
EXECUTE Sp_executesql
#Update_Typ2_Rec;
SELECT #UPDATE_MODULE_TABLE = N'UPDATE ' + #TableName +
' SET approval_status_id = 9 WHERE id = '
+ #RECID + '';
--SELECT #UPDATE_MODULE_TABLE
EXECUTE Sp_executesql
#UPDATE_MODULE_TABLE;
PRINT 'LevleId = 1'
END
ELSE IF ( #LevleId = 2
AND #STATUS != 3 )
BEGIN
SELECT #Update_Typ2_Rec =
N'UPDATE hrms_approvals SET approval_status_id = '
+ #STATUS + ' WHERE record_id = '
+ #RECID + ' AND module_id = '
+ #Module_id + ' ';
--SELECT #Update_Typ2_Rec
EXECUTE Sp_executesql
#Update_Typ2_Rec;
SELECT
#UPDATE_MODULE_TABLE = N'UPDATE ' + #TableName
+ ' SET approval_status_id = 10 WHERE id = ' + #RECID + '';
--SELECT #UPDATE_MODULE_TABLE
EXECUTE Sp_executesql
#UPDATE_MODULE_TABLE;
PRINT 'LevleId = 2'
END
ELSE IF ( #LevleId = 3
AND #STATUS != 3 )
BEGIN
SELECT #STATUS,
#LevleId
PRINT 'LevleId = 3'
END
ELSE IF ( #LevleId = 4
AND #STATUS != 3 )
BEGIN
SELECT #STATUS,
#LevleId
PRINT 'LevleId = 4'
END
ELSE IF ( #LevleId = 5
AND #STATUS != 3 )
BEGIN
SELECT #STATUS,
#LevleId
PRINT 'LevleId = 5'
END
FETCH next FROM #MyCursor INTO #LevleId, #STATUS, #RECID
END;
CLOSE #MyCursor;
DEALLOCATE #MyCursor;
END;
Try this below code,You didn't declare this Parameters "#TableName and #ModuleId", Check your code and assign the value for #TableName and #ModuleId
Declare #Counter int=1
,#Tot_Count int=0
,#LevleId int
,#Status int
,#RecId int
,#Module_id int
,#TableName varchar(30)=''
Create Table #Temp_Table
(
Id int identity(1,1)
,level_id int
,status_id int
,record_id int
,Module_id int
)
Insert into #Temp_Table
(
level_id,status_id,record_id
)
Select level_id
,status_id
,record_id
,Module_id
from #temp_record_id_typ2
where approval_typ_id = 2
Select #Tot_Count=Count(1) from #Temp_Table
While #Tot_Count >= #Counter
Begin
Select #LevleId=level_id
,#Status=status_id
,#RecId=record_id
,#Module_id=Module_id
from #Temp_Table
where Id=#Counter
IF ( #LevleId = 1 AND #STATUS <> 3 )
BEGIN
Exec
('
UPDATE hrms_approvals
SET approval_status_id = ' + #STATUS + '
WHERE record_id = ' + #RECID + '
AND module_id = ' + #Module_id +'
UPDATE '+ #TableName +'
SET approval_status_id = 9
WHERE id = '+ #RECID + '
')
PRINT 'LevleId = 1'
END
ELSE IF ( #LevleId = 3 AND #STATUS <> 3 )
BEGIN
SELECT #STATUS,
#LevleId
PRINT 'LevleId = 3'
END
ELSE IF ( #LevleId = 4 AND #STATUS <> 3 )
BEGIN
SELECT #STATUS,
#LevleId
PRINT 'LevleId = 4'
END
ELSE IF ( #LevleId = 5 AND #STATUS <> 3 )
BEGIN
SELECT #STATUS,
#LevleId
PRINT 'LevleId = 5'
END
Set #Counter+=1
End
Drop table #Temp_Table

How to update table with while loop in Stored Procedure?

I want to update my dynamic table in while loop.
Here is my code:
While (#j<=#tmp_getRowCount)
Begin
Set #firstcolumn = (Select SplitFirst_tblAR from #result_AR Where rownumber = #j) //String//
Set #secondcolumn = (Select EMail_tblAR from #result_AR Where rownumber = #j) //String//
Set #thirdcolumn = (Select SplitFirst_tblKul from #result_AR Where rownumber = #j) //String//
Set #fourthcolumn = (Select EMail_tblKul from #result_AR Where rownumber = #j) //String//
insert into #test Values(#tmp_ID, #firstcolumn,#secondcolumn,#thirdcolumn,#fourthcolumn)
if ((#firstcolumn = #thirdcolumn) AND (#secondcolumn != #fourthcolumn) AND (#firstcolumn != ''))
begin
Set #q_updateTable = 'Update '+ quotename(#tablename) +' Set '+#columnname+' = ''' + #fourthcolumn + ''' Where ID = ' + #tmp_ID + ''
Exec sp_executesql #q_updateTable
end
SET #j = #j+1
End
My result_AR table:
I know the error is in here:
Where ID = ' + #tmp_ID + ''
When I change this Where clause as,
Where '+#columnname+' = ''' + #secondcolumn + ''' '
code works correctly.
Why can't I set as ID my where clause? I am getting ID value as integer.
The error is 'Query completed with errors'.
Thanks in advance.
you can not set Id in where clause because the id is integer value and you are concatenating it with string (varchar).
So first you have to convert it in (String)varchar and the you can use it where clause.
Like :
Set #q_updateTable = 'Update '+ quotename(#tablename) +' Set '+#columnname+' = ''' + #fourthcolumn + ''' Where ID = ' + convert(varchar,#tmp_ID) + ''
Exec sp_executesql #q_updateTable
you have to use "convert(varchar,#tmp_ID)" insted of "#tmp_ID"

Trigger should be, but is not, recursive, right?

New to triggers and trying to figure out why the nested IF at the end of this of this trigger doesn't seem to be recursive. What I would like is for it to trigger itself over and over again until it hits a #ProcessStatus of 4. It only goes to 1. Not really sure why, any suggestions?
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER TRIGGER [dbo].[tr_ProcessRecord] ON [dbo].[_ShipMain]
FOR UPDATE
AS
BEGIN TRANSACTION
declare #cqID nvarchar(24),
#carrier nvarchar(24),
#shipCode nvarchar(24),
#Note nvarchar(255),
#ProcessStatus nvarchar(24);
SELECT #cqID = i.ConnectQueryID from inserted i;
SELECT #carrier = i.Carrier from inserted i;
SELECT #shipCode = i.ShipCode from inserted i;
SELECT #ProcessStatus = i.Status from inserted i;
SELECT #Note = 'ID: ' + #cqID + ' ' +
'Carrier: ' + ' ' + convert(nvarchar(24), #carrier) + ' ' +
'Ship Code: ' + #shipCode + ' ' +
(SELECT CASE #ProcessStatus
WHEN 0 THEN 'Recieved'
WHEN 1 THEN 'Processing'
WHEN 2 THEN 'More Processing'
WHEN 3 THEN 'Finishing'
WHEN 4 THEN 'Processed'
END);
INSERT INTO [_ShipLog]
SELECT #cqID
,GETDATE()
,#Note
,#ProcessStatus
IF #ProcessStatus = 0
BEGIN
UPDATE [_ShipMain]
SET [Status] = #ProcessStatus + 1
WHERE [ConnectQueryID] = #cqID;
END
IF #ProcessStatus = 1
BEGIN
UPDATE [_ShipMain]
SET [Status] = #ProcessStatus + 1
WHERE [ConnectQueryID] = #cqID;
END
IF #ProcessStatus = 2
BEGIN
UPDATE [_ShipMain]
SET [Status] = #ProcessStatus + 1
WHERE [ConnectQueryID] = #cqID;
END
IF #ProcessStatus = 3
BEGIN
UPDATE [_ShipMain]
SET [Status] = #ProcessStatus + 1
WHERE [ConnectQueryID] = #cqID;
END
COMMIT TRANSACTION
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER TRIGGER [dbo].[tr_ProcessRecord] ON [dbo].[_ShipMain]
FOR UPDATE
AS
BEGIN TRANSACTION
declare #cqID nvarchar(24),
#carrier nvarchar(24),
#shipCode nvarchar(24),
#Note nvarchar(255),
#ProcessStatus nvarchar(24);
SELECT
#cqID = i.ConnectQueryID
,#carrier = i.Carrier
,#shipCode = i.ShipCode
,#ProcessStatus = i.Status
from inserted i;
SELECT #Note = 'ID: ' + #cqID + ' ' +
'Carrier: ' + ' ' + convert(nvarchar(24), #carrier) + ' ' +
'Ship Code: ' + #shipCode + ' ' +
(SELECT CASE #ProcessStatus
WHEN 0 THEN 'Recieved'
WHEN 1 THEN 'Processing'
WHEN 2 THEN 'More Processing'
WHEN 3 THEN 'Finishing'
WHEN 4 THEN 'Processed'
END);
INSERT INTO [_ShipLog]
SELECT #cqID
,GETDATE()
,#Note
,#ProcessStatus
UPDATE [_ShipMain]
SET [Status] = #ProcessStatus + 1
WHERE [ConnectQueryID] = #cqID
and #ProcessStatus in (0,1,2,3)
COMMIT TRANSACTION

Update TableType variable in dynamic SQL query

I had created User defined table type in my database. After that I had declared a variable of that table type in my procedure. And I had return my rest of the logic. At the end I am trying to update that table type variable using dynamic SQL.
But I got an error:
Msg 10700, Level 16, State 1, Line 1
The table-valued parameter "#ttbl_TagList" is READONLY and cannot be modified.
How can I solve the error?
User defined table type:
CREATE TYPE [dbo].[tt_TagList] AS TABLE(
[tagListId] [tinyint] IDENTITY(1,1) NOT NULL,
[tagId] [tinyint] NOT NULL DEFAULT ((0)),
[tagName] [varchar](100) NOT NULL DEFAULT (''),
[tagValue] [nvarchar](max) NOT NULL DEFAULT ('')
)
GO
Procedure:
CREATE PROCEDURE [dbo].[P_ReplaceTemplateTag]
AS
BEGIN
SET NOCOUNT ON;
DECLARE #ttbl_TagList dbo.tt_TagList, #V_TagId INT, #V_Counter TINYINT = 1,
#V_FinalQuery NVARCHAR(MAX) = '', #V_TagValue NVARCHAR(MAX);
INSERT INTO #ttbl_TagList (tagId, tagName, tagValue)
SELECT DISTINCT T.tagId, T.tagName, '' AS tagValue
FROM dbo.tbl_Tag T;
WHILE (1 = 1)
BEGIN
SET #V_TagValue = '';
SELECT #V_TagId = tagId FROM #ttbl_TagList WHERE tagListId = #V_Counter;
IF (##ROWCOUNT = 0)
BEGIN
BREAK;
END
IF (#V_TagId = 1)
BEGIN
/* Logic for getting tag value */
SET #V_TagValue = 'Tag Value 1';
END
ELSE IF (#V_TagId = 2)
BEGIN
/* Logic for getting tag value */
SET #V_TagValue = 'Tag Value 2';
END
ELSE IF (#V_TagId = 3)
BEGIN
/* Logic for getting tag value */
SET #V_TagValue = 'Tag Value 3';
END
ELSE IF (#V_TagId = 4)
BEGIN
/* Logic for getting tag value */
SET #V_TagValue = 'Tag Value 4';
END
IF (#V_TagValue != '')
BEGIN
SET #V_FinalQuery = #V_FinalQuery + ' WHEN ' + CONVERT(NVARCHAR(10), #V_Counter) + ' THEN ''' + #V_TagValue + '''';
END
SET #V_Counter = #V_Counter + 1;
END
IF (#V_FinalQuery != '')
BEGIN
SET #V_FinalQuery = N'UPDATE #ttbl_TagList SET tagValue = (CASE tagListId' + #V_FinalQuery + ' END)';
EXECUTE sp_executesql #V_FinalQuery, N'#ttbl_TagList dbo.tt_TagList readonly', #ttbl_TagList;
END
SELECT * FROM #ttbl_TagList;
END
TVP can not be updated directly. So try this one -
CREATE PROCEDURE [dbo].[P_ReplaceTemplateTag]
AS
BEGIN
SET NOCOUNT ON;
IF OBJECT_ID('tempdb.dbo.#t1') IS NOT NULL
DROP TABLE #t1
DECLARE
#ttbl_TagList dbo.tt_TagList
, #V_Counter TINYINT = 1
, #V_FinalQuery NVARCHAR(MAX) = ''
, #V_TagValue NVARCHAR(MAX);
INSERT INTO #ttbl_TagList (tagId, tagName, tagValue)
SELECT DISTINCT tagId, tagName, ''
FROM dbo.tbl_Tag;
WHILE (1 = 1) BEGIN
SELECT #V_TagValue =
CASE
WHEN tagId = 1 THEN 'Tag Value 1'
WHEN tagId = 2 THEN 'Tag Value 2'
WHEN tagId = 3 THEN 'Tag Value 3'
WHEN tagId = 4 THEN 'Tag Value 4'
ELSE ''
END
FROM #ttbl_TagList
WHERE tagListId = #V_Counter;
IF (##ROWCOUNT = 0) BREAK;
IF (#V_TagValue != '')
BEGIN
SET #V_FinalQuery = #V_FinalQuery + ' WHEN ' + CONVERT(NVARCHAR(10), #V_Counter) + ' THEN ''' + #V_TagValue + '''';
END
SET #V_Counter = #V_Counter + 1;
END
IF (#V_FinalQuery != '')
BEGIN
CREATE TABLE #t1
(
tagId TINYINT
, tagName VARCHAR(100)
, tagValue NVARCHAR(MAX)
)
SET #V_FinalQuery = N'
INSERT INTO #t1
SELECT tagId, tagName, (CASE tagListId' + #V_FinalQuery + ' END)
FROM #ttbl_TagList';
EXEC sys.sp_executesql
#V_FinalQuery
, N'#ttbl_TagList dbo.tt_TagList readonly'
, #ttbl_TagList;
END
SELECT * FROM #t1;
END