I want to write a trigger which updates some fields in another master table record in TRN_PT_TESTS_DET table gets updated for a specific test.
EG. when driving license in PTD_READING_TEXT column is updated in TRN_PT_TESTS_DET table, we want to update PT_DRIVER_LIC column in MST_PATIENT where PT_ID = ENC_PT_ID, which will also look in TST_CODE = 'SC32105' in MST_TESTS table (code 'SC32105' stands for driving license).
Reference query:
select top 10 ENC_PT_ID, PTD_READING_TEXT
from trn_pt_tests_Det
inner join trn_pt_tests_head on ptd_pth_id = pth_id
inner join trn_encounters on pth_enc_id = enc_id
where ptd_test_id = (select TST_ID from MST_TESTS where TST_CODE = 'SC32105');
While doing that we also want to add a record in TRN_NOTES with TN_TYPE = 'PC', TN_OBJECT_ID = PT_ID and TN_NOTE =
"Updated Patient <PT_LAST_NAME>, <PT_FIRST_NAME> Driver License Old:XXX New:YYYY"
I have created a below trigger which is not updating the PT_DRIVER_LIC column in MST_PATIENT and also inserting incorrect record into TRN_NOTES table.
Can someone please tell me what I am doing wrong?
When I execute below update query.
update TRN_PT_TESTS_DET
set PTD_READING_TEXT = 'aaaaa'
where PTD_TEST_ID = 11025
and PTD_PTH_ID = 134
the value is updated and trigger is called but #pt_id, #enc_id, #pt_last_name and #pt_first_name declared variable in trigger fetch different ID's and insert different values in TRN_NOTES table and the update MST_PATIENT table part don't work at all.
Can some please review below trigger and help me to fin out what I am doing wrong.
Trigger:
CREATE TRIGGER update_driver_lic_and_notes
ON TRN_PT_TESTS_DET
AFTER UPDATE
AS
IF (UPDATE (PTD_READING_TEXT))
BEGIN
IF EXISTS (SELECT 1
FROM trn_pt_tests_Det
INNER JOIN trn_pt_tests_head ON ptd_pth_id = pth_id
INNER JOIN trn_encounters ON pth_enc_id = enc_id
WHERE PTH_ID = PTD_PTH_ID
AND EXISTS (SELECT 1
FROM MST_TESTS
WHERE TST_CODE = 'VTWTLBS'))
BEGIN
DECLARE #old_dl varchar(255);
DECLARE #new_dl varchar(255);
DECLARE #pt_id int;
DECLARE #enc_id int;
DECLARE #pt_last_name varchar(255);
DECLARE #pt_first_name varchar(255);
SELECT #old_dl = PT_DRIVER_LIC
FROM MST_PATIENT
INNER JOIN trn_encounters ON PT_ID = ENC_PT_ID
INNER JOIN trn_pt_tests_head ON pth_enc_id = enc_id
INNER JOIN TRN_PT_TESTS_DET ON ptd_pth_id = pth_id
WHERE ptd_test_id = (SELECT TST_ID FROM MST_TESTS
WHERE TST_CODE = 'VTWTLBS');;
SELECT #new_dl = PTD_READING_TEXT,
#pt_id = ENC_PT_ID,
#enc_id = enc_id,
#pt_last_name = PT_LNAME,
#pt_first_name = PT_FNAME
FROM MST_PATIENT
INNER JOIN trn_encounters ON PT_ID = ENC_PT_ID
INNER JOIN trn_pt_tests_head ON pth_enc_id = enc_id
INNER JOIN TRN_PT_TESTS_DET ON ptd_pth_id = pth_id
WHERE ptd_test_id = (SELECT TST_ID FROM MST_TESTS
WHERE TST_CODE = 'VTWTLBS');
-- IF (#old_dl != #new_dl)
UPDATE MST_PATIENT
SET PT_DRIVER_LIC = #new_dl
WHERE PT_ID = #pt_id;
INSERT INTO TRN_NOTES (TN_TYPE, TN_OBJECT_ID, TN_ENC_ID, TN_MOD_USER, TN_NOTES, TN_MOD_TIMESTAMP)
VALUES ('PC', #pt_id, #enc_id,0, 'Updated Patient ' + #pt_last_name + ', ' + #pt_first_name + ' Driver License Old:' + #old_dl + ' New:' + #new_dl, GETDATE());
END
END
Thank you.
Related
I tried this, but it didn't work. I wanted to use the "valor" row to make this trigger.
CREATE TRIGGER valor_total ON Detalhe_Venda
AFTER INSERT
AS
DECLARE #vendaid INT
DECLARE #produtoid INT
DECLARE #qtd_produtos INT
DECLARE #valor FLOAT
SELECT #vendaid = venda_id, #produtoid = produto_id, #qtd_produtos = quantidadeprod
FROM INSERTED
SELECT #valor = valor
FROM Produtos
WHERE id = #produtoid
UPDATE Venda
SET valortotal = valortotal + (#valor * #qtd_produtos)
WHERE id = #vendaid
You are misunderstanding a lot of things about triggers in SQL Server. The most important is that INSERTED is a set of rows, not a single row.
In fact, you can simplify your whole trigger to a single query:
CREATE TRIGGER valor_total ON Detalhe_Venda
AFTER INSERT
AS
BEGIN
UPDATE v
SET valortotal = v.valortotal + (p.valor * i.quantidadeprod)
FROM Venda v JOIN
Inserted i
ON v.id = i.venda_id JOIN
Produtos p
ON p.id = i.produtoid;
END;
EDIT:
SMore makes a good point. Aggregation is probably desirable before the join:
CREATE TRIGGER valor_total ON Detalhe_Venda
AFTER INSERT
AS
BEGIN
UPDATE v
SET valortotal = v.valortotal + ip.valor
FROM Venda v JOIN
(SELECT i.venda_id,
SUM(p.valor * i.quantidadeprod) as valor
FROM Inserted i JOIN
Produtos p
ON p.id = i.produtoid
GROUP BY i.venda_id
) ip
ON v.id = ip.venda_id
END;
So I understand recursive triggers. Got to be careful of deadlocks etc. However this is only after an insert not after insert and update. Also, I have an audit trigger table that I am updating to make sure all is well. And querying after to double check. All looks fine but no update happens.
if exists (select 'a' from sys.triggers where name = 'invoicememologic')
begin
drop trigger invoicememologic
end
go
create trigger invoicememologic
on transactiontable
after insert
as
begin
declare #inum varchar(1000)
select #inum = min(transactioninvnum)
from
(select transactioninvnum
from inserted i
inner join project p on left(i.projectid, charindex(':', i.projectid)) = p.projectid
where right(i.projectid, 1) <> ':'
and abs(p.UseProjectMemoOnInv) = 1
group by transactioninvnum) b
while #inum is not null
begin
declare #rCount int
select #rCount = count(*)
from transactiontable
where TransactionInvNum = #inum
if #rCount = 1
begin
declare #tid varchar(100)
select #tid = transactionid
from transactiontable
where TransactionInvNum = #inum
declare #pmemo varchar(MAX)
select #pmemo = p.projectMemo
from transactiontable tt
inner join project p on left(tt.projectid, charindex(':', tt.projectid)) = p.projectid
where transactionInvNum = #inum
insert into audittrigger
values (#pmemo, #tid)
update transactiontable
set transactionmemo2 = #pmemo
where ltrim(rtrim(transactionid)) = ltrim(rtrim(#tid))
end
select #inum = min(transactioninvnum)
from
(select transactioninvnum
from inserted i
inner join project p on left(i.projectid, charindex(':', i.projectid)) = p.projectid
where abs(transactionjointinv) = 1
and right(i.projectid, 1) <> ':'
and abs(p.UseProjectMemoOnInv) = 1
group by transactioninvnum ) a
where transactioninvnum > #inum
end
end
Reason for trigger. 1 Invoice can be multiple rows in the database. 3 rows. So it only should update any one of the 3 rows. Doesn't matter. And it must grab the memo from the parent project of the phases that are being inserted into the database. hence the inner join on the left with charindex.
So I check the audit table. All looks well there. MEMO is there and the transactionid is there. I query after the trigger fires. TransactionID exists in the transactiontable but the memo2 is not being updated.
TransactionMemo2 is type of ntext. I thought it might be varchar with a direct update command will fail. I tried to update manually through setting a var as the text string and call the update manually with the transactionid being required. all worked fine. I am lost
I have just implemented a new database on our live environment, this database is fed information by a service brokers from our two transactional databases. When the messages come into the new database we have a series of stored procedures which manipulate the feed for each specific user.
I also have another set of stored procedures which re-manipulate the data by user instead of by vehicle, these are used by our maintenance screens to ensure we can change users visibility of the data.
The below stored procedure keeps locking up I have now amended this sp to update a temp table first and then just undertake one update against the main database, however this has not aided the situation, I have also amended so I can update in smaller batches and if this fails keep retrying until it is successful. This works 100% on our dev environment but on live it keeps locking. The throughput on the servicebrokers is not great enough to register the number of failures, I therefore believe I am locking myself within this sp?
I have included ---'THIS UPDATE KEEPS LOCKING' at the point of failure.
What could be causing this locking behavior?
USE [Isight]
GO
/** Object: StoredProcedure [dbo].[UserVisibilityForVehicles] Script Date: 07/18/2014 14:43:04 **/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[UserVisibilityForVehicles]
-- Add the parameters for the stored procedure here
#Username VARCHAR(50)
WITH RECOMPILE
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
PRINT 'UserVisibilityForVehicles Started'
-- Now Start to check security for user.
IF EXISTS ( SELECT ID FROM dbo.SecurityTable WHERE userid = #Username AND Deleted = 0)
BEGIN
CREATE TABLE #VehicleToUsers(ID BIGINT, NewRecord BIT DEFAULT(0))
CREATE CLUSTERED INDEX IDX_VehicleToUsers ON #VehicleToUsers(ID)
CREATE NonCLUSTERED INDEX IDX_NewRecord ON #VehicleToUsers(ID)
INSERT INTO #VehicleToUsers
( ID )
(
SELECT Distinct Veh.[ID]
FROM [iSight].[dbo].[Vehicle] Veh WITH (NOLOCK)
INNER JOIN SecurityTable WITH (NOLOCK) ON Veh.[System] = SecurityTable.[System]
WHERE SecurityType = 1 AND UserID = #Username AND SecurityTable.deleted = 0
)
INSERT INTO #VehicleToUsers
( ID )
(
SELECT DISTINCT Veh.[ID]
FROM [iSight].[dbo].[Vehicle] Veh WITH (NOLOCK)
INNER JOIN SecurityTable WITH (NOLOCK) ON Veh.[System] = SecurityTable.[System] AND Veh.CurrentSite = SecurityTable.[Site]
WHERE SecurityType = 2 AND UserID = #Username AND SecurityTable.deleted = 0
)
BEGIN
PRINT 'UserVisibilityForVehicles: ' + #Username
INSERT INTO #VehicleToUsers
( ID )
(
SELECT DISTINCT Vehicle.ID
FROM Manufacturer WITH (NOLOCK) INNER JOIN
ManufacturerAgreementSubcustomer WITH (NOLOCK) ON Manufacturer.ID = ManufacturerAgreementSubcustomer.ManufacturerID INNER JOIN
ManufacturerMake WITH (NOLOCK) ON Manufacturer.ID = ManufacturerMake.ManufacturerID INNER JOIN
Vehicle WITH (NOLOCK) ON ManufacturerMake.Make = Vehicle.Make AND ManufacturerAgreementSubcustomer.Agreement = Vehicle.CurrentAgreement INNER JOIN
SecurityTable WITH (NOLOCK) ON Manufacturer.ManufacturerGroupID = SecurityTable.ManufacturerGroupID AND Vehicle.System = SecurityTable.System
WHERE (SecurityTable.SecurityType = 3) AND (SecurityTable.UserID = #Username) AND ManufacturerMake.Deleted = 0 AND ManufacturerAgreementSubcustomer.Deleted = 0 AND SecurityTable.deleted = 0
)
INSERT INTO #VehicleToUsers
( ID )
(
SELECT DISTINCT Vehicle.ID
FROM Manufacturer WITH (NOLOCK) INNER JOIN
ManufacturerAgreementSubcustomer WITH (NOLOCK) ON Manufacturer.ID = ManufacturerAgreementSubcustomer.ManufacturerID INNER JOIN
ManufacturerMake WITH (NOLOCK) ON Manufacturer.ID = ManufacturerMake.ManufacturerID INNER JOIN
Vehicle WITH (NOLOCK) ON ManufacturerMake.Make = Vehicle.Make AND ManufacturerAgreementSubcustomer.Agreement = Vehicle.CurrentAgreement INNER JOIN
SecurityTable WITH (NOLOCK) ON Vehicle.System = SecurityTable.System AND Manufacturer.ID = SecurityTable.ManufacturerID
WHERE (SecurityTable.SecurityType = 4) AND (SecurityTable.UserID = #Username) AND ManufacturerMake.Deleted = 0 AND ManufacturerAgreementSubcustomer.Deleted = 0 AND SecurityTable.deleted = 0
)
INSERT INTO #VehicleToUsers
( ID )
(
SELECT DISTINCT Vehicle.ID
FROM Manufacturer WITH (NOLOCK) INNER JOIN
ManufacturerAgreementSubcustomer WITH (NOLOCK) ON Manufacturer.ID = ManufacturerAgreementSubcustomer.ManufacturerID INNER JOIN
ManufacturerMake WITH (NOLOCK) ON Manufacturer.ID = ManufacturerMake.ManufacturerID INNER JOIN
Vehicle WITH (NOLOCK) ON ManufacturerMake.Make = Vehicle.Make AND ManufacturerAgreementSubcustomer.Agreement = Vehicle.CurrentAgreement INNER JOIN
SecurityTable WITH (NOLOCK) ON Vehicle.System = SecurityTable.System AND Manufacturer.ID = SecurityTable.ManufacturerID AND
ManufacturerAgreementSubcustomer.ID = SecurityTable.ManufacturerAgreementSub INNER JOIN
ManufacturerUserAgreementSubcustomer WITH (NOLOCK) ON
ManufacturerAgreementSubcustomer.ID = ManufacturerUserAgreementSubcustomer.ManufacturerAgreementSubcustomerID AND
SecurityTable.ManufacturerID = ManufacturerUserAgreementSubcustomer.ManufacturerID AND
SecurityTable.UserID = ManufacturerUserAgreementSubcustomer.UserName
WHERE (SecurityTable.SecurityType = 5) AND (SecurityTable.UserID = #Username) AND (ManufacturerMake.Deleted = 0) AND
(ManufacturerAgreementSubcustomer.Deleted = 0) AND (ManufacturerUserAgreementSubcustomer.Deleted = 0) AND SecurityTable.deleted = 0
)
INSERT INTO #VehicleToUsers
( ID )
(
SELECT DISTINCT Vehicle.ID
FROM Manufacturer WITH (NOLOCK) INNER JOIN
ManufacturerAgreementSubcustomer WITH (NOLOCK) ON Manufacturer.ID = ManufacturerAgreementSubcustomer.ManufacturerID INNER JOIN
ManufacturerMake WITH (NOLOCK) ON Manufacturer.ID = ManufacturerMake.ManufacturerID INNER JOIN
Vehicle WITH (NOLOCK) ON ManufacturerMake.Make = Vehicle.Make AND ManufacturerAgreementSubcustomer.Agreement = Vehicle.CurrentAgreement AND
ManufacturerAgreementSubcustomer.Subcustomer = Vehicle.CurrentSubCustomer INNER JOIN
SecurityTable WITH (NOLOCK) ON Vehicle.System = SecurityTable.System AND Manufacturer.ID = SecurityTable.ManufacturerID AND
ManufacturerAgreementSubcustomer.ID = SecurityTable.ManufacturerAgreementSub INNER JOIN
ManufacturerUserAgreementSubcustomer WITH (NOLOCK) ON
ManufacturerAgreementSubcustomer.ID = ManufacturerUserAgreementSubcustomer.ManufacturerAgreementSubcustomerID AND
SecurityTable.UserID = ManufacturerUserAgreementSubcustomer.UserName AND
SecurityTable.ManufacturerID = ManufacturerUserAgreementSubcustomer.ManufacturerID
WHERE (SecurityTable.SecurityType = 6) AND (SecurityTable.UserID = #Username) AND (ManufacturerMake.Deleted = 0) AND
(ManufacturerAgreementSubcustomer.Deleted = 0) AND (ManufacturerUserAgreementSubcustomer.Deleted = 0) AND SecurityTable.deleted = 0
)
END
CREATE TABLE #VehicleToUserCopy(ID BIGINT, vehicleTableID BIGINT, Deleted BIT DEFAULT(1), UpdatedAt DATETIME DEFAULT (GETDATE()), UpdatedBy VARCHAR(50) DEFAULT('UserVisibilityForVehicles-Update'), NextToUpdate BIT DEFAULT(0))
CREATE CLUSTERED INDEX idx_ID ON #VehicleToUserCopy(ID)
CREATE NONCLUSTERED INDEX idx_VehicleTableID ON #VehicleToUserCopy(vehicleTableID)
CREATE NONCLUSTERED INDEX idx_NextToUpdate ON #VehicleToUserCopy(NextToUpdate)
INSERT INTO #VehicleToUserCopy
( ID ,
vehicleTableID ,
Deleted
)
(
SELECT ID, vehicleTableID, Deleted
FROM dbo.VehicleToUser WITH (nolock)
WHERE Username = #Username
)
PRINT 'Starting to do updates'
--Not required as default set to 1
----UPDATE VehicleToUser
----SET DELETED = 1
----,UpdatedAt = GETDATE()
----,UpdatedBy = 'UserVisibilityForVehicles'
----FROM dbo.VehicleToUser WITH (NOLOCK)
----LEFT JOIN #VehicleToUsers AS UsersVehicles ON VehicleToUser.VehicleTableID = UsersVehicles.ID
----WHERE UserName = #Username AND UsersVehicles.ID IS null
PRINT 'Starting to do updates - Set Deleted = 0'
SET LOCK_TIMEOUT 1000 -- set to second
DECLARE #Tries tinyint
UPDATE #VehicleToUserCopy
SET Deleted = 0
FROM #VehicleToUserCopy AS VehicleToUserCopy
inner JOIN #VehicleToUsers AS UsersVehicles ON VehicleToUserCopy.VehicleTableID = UsersVehicles.ID
INSERT INTO VehicleToUser(UserName, VehicleTableID, DELETED, UpdatedAt, UpdatedBy)
(
SELECT DISTINCT #Username, TempVehicle.ID, 0 , GETDATE(), 'UserVisibilityForVehicles-Insert'
FROM #VehicleToUsers AS TempVehicle
LEFT JOIN (
SELECT VehicleTableID
FROM #VehicleToUserCopy WITH (NOLOCK)
) AS [VehicleToUser] ON TempVehicle.ID = [VehicleToUser].VehicleTableID
WHERE [VehicleToUser].VehicleTableID IS null
)
DECLARE #ID bigint
SELECT #ID = ID FROM #VehicleToUserCopy
WHILE ##rowcount > 0
BEGIN
SET ROWCOUNT 1000
SELECT #Tries = 1
WHILE #Tries <= 3
BEGIN
BEGIN TRANSACTION
BEGIN TRY
UPDATE #VehicleToUserCopy SET NextToUpdate = 1
---'THIS UPDATE KEEPS LOCKING'
UPDATE dbo.VehicleToUser
SET Deleted = VehicleToUserCopy.Deleted
, UpdatedAt = GETDATE()
, UpdatedBy = VehicleToUserCopy.UpdatedBy
FROM VehicleToUser
inner JOIN #VehicleToUserCopy AS VehicleToUserCopy ON VehicleToUser.ID = VehicleToUserCopy.ID
WHERE VehicleToUserCopy.NextToUpdate = 1
PRINT 'WORKED'
DELETE FROM #VehicleToUserCopy WHERE NextToUpdate = 1
COMMIT
-- therefore we can leave our loop
BREAK
END TRY
BEGIN CATCH
ROLLBACK --always rollback
PRINT 'Rolled Back '
-- Now check for Blocking errors 1222 or Deadlocks 1205 and if its a deadlock wait for a while to see if that helps
SELECT ERROR_MESSAGE()
IF ERROR_NUMBER() = 1205 OR ERROR_NUMBER() = 1222
BEGIN
-- if its a deadlock wait 2 seconds then try again
IF ERROR_NUMBER() = 1205
BEGIN -- wait 2 seconds to see if that helps the deadlock
WAITFOR DELAY '00:00:02'
END
-- no need to wait for anything for BLOCKING ERRORS as our LOCK_TIMEOUT is going to wait for half a second anyway
-- and if it hasn't finished by then (500ms x 3 attempts = 1.5 seconds) there is no point waiting any longer
END
SELECT #Tries = #Tries + 1 -- increment and try again for 3 goes
-- we carry on until we reach our limit i.e 3 attempts
CONTINUE
END CATCH
END
SELECT #ID = ID FROM #VehicleToUserCopy
End
SET ROWCOUNT 0
DROP TABLE #VehicleToUsers
END
ELSE
BEGIN
DELETE FROM dbo.VehicleToUser WHERE username = #Username
DELETE FROM dbo.VehicleToUser_UserCurrentImageCount WHERE username = #Username
DELETE FROM dbo.VehicleToUser_UsersCurrentVehicles WHERE username = #Username
End
Try changing your update slightly. I have seen some inconsistent results when using an update like this and you update the base table. You should instead update the alias.
UPDATE v
SET Deleted = VCopy.Deleted
, UpdatedAt = GETDATE()
, UpdatedBy = VCopy.UpdatedBy
FROM VehicleToUser v
inner JOIN #VehicleToUserCopy AS VCopy ON v.ID = VCopy.ID
WHERE VCopy.NextToUpdate = 1
Below is a SQL Server 2005 update trigger. For every update on the email_subscriberList table where the isActive flag changes we insert an audit record into the email_Events table. This works fine for single updates but for bulk updates only the last updated row is recorded. How do I convert the below code to perform an insert for every row updated?
CREATE TRIGGER [dbo].[Email_SubscriberList_UpdateEmailEventsForUpdate_TRG]
ON [dbo].[Email_subscriberList]
FOR UPDATE
AS
DECLARE #CustomerId int
DECLARE #internalId int
DECLARE #oldIsActive bit
DECLARE #newIsActive bit
DECLARE #email_address varchar(255)
DECLARE #mailinglist_name varchar(255)
DECLARE #email_event_type varchar(1)
SELECT #oldIsActive = isActive from Deleted
SELECT #newIsActive = isActive from Inserted
IF #oldIsActive <> #newIsActive
BEGIN
IF #newIsActive = 1
BEGIN
SELECT #email_event_type = 'S'
END
ELSE
BEGIN
SELECT #email_event_type = 'U'
END
SELECT #CustomerId = customerid from Inserted
SELECT #internalId = internalId from Inserted
SELECT #email_address = (select email from customer where customerid = #CustomerId)
SELECT #mailinglist_name = (select listDescription from Email_lists where internalId = #internalId)
INSERT INTO Email_Events
(mailshot_id, date, email_address, email_event_type, mailinglist_name)
VALUES
(#internalId, getDate(), #email_address, #email_event_type,#mailinglist_name)
END
example
untested
CREATE TRIGGER [dbo].[Email_SubscriberList_UpdateEmailEventsForUpdate_TRG]
ON [dbo].[Email_subscriberList]
FOR UPDATE
AS
INSERT INTO Email_Events
(mailshot_id, date, email_address, email_event_type, mailinglist_name)
SELECT i.internalId,getDate(),c.email,
case i.isActive when 1 then 'S' else 'U' end,e.listDescription
from Inserted i
join deleted d on i.customerid = d.customerid
and i.isActive <> d.isActive
join customer c on i.customerid = c.customerid
join Email_lists e on e.internalId = i.internalId
Left outer joins, for in case there are no related entries in customer or email_Lists (as is possible in the current code) -- make them inner joins if you know there will be data present (i.e. foreign keys are in place).
CREATE TRIGGER [dbo].[Email_SubscriberList_UpdateEmailEventsForUpdate_TRG]
ON [dbo].[Email_subscriberList]
FOR UPDATE
AS
INSERT INTO Email_Events
(mailshot_id, date, email_address, email_event_type, mailinglist_name)
select
i.InternalId
,getdate()
,cu.Email
,case i.IsaActive
when 1 then 'S'
else 'U'
end
,el.ListDescription
from inserted i
inner join deleted d
on i.CustomerId = d.CustomerId
and i.IsActive <> d.IsActive
left outer join Customer cu
on cu.CustomerId = i.CustomerId
left outer join Email_Lists el
on el.InternalId = i.InternalId
Test it well, especially for concurrency issues. Those joins within the trigger make me nervous.
This posting is an update (with trigger code) from my earlier posting yesterday
I am using SQL Server 2000. I am writing a trigger that is executed when a field Applicant.AppStatusRowID
Table Applicant is linked to table Location, table Company & table AppStatus.
My issue is creating the joins in my query.
When Applicant.AppStatusRowID is updated, I want to get the values from Applicant.AppStatusRowID, Applicant.FirstName, Applicant.Lastname, Location.LocNumber, Location.LocationName, Company.CompanyCode, AppStatus.DisplayText
The joins would be :
Select * from Applicant A
Inner Join AppStatus ast on ast.RowID = a.AppStatusRowID
Inner Join Location l on l.RowID = a.LocationRowID
Inner Join Company c on c.RowID = l.CompanyRowID
This is to be inserted into an Audit table (fields are ApplicantID, LastName, FirstName, Date, Time, Company, Location Number, Location Name, StatusDisposition, User)
The trigger query is:
SET QUOTED_IDENTIFIER OFF
GO
SET ANSI_NULLS ON
GO
CREATE TRIGGER tri_UpdateAppDispo ON dbo.Test_App
For Update
AS
declare #Approwid int
Declare #triggername sysname
Set #rowCnt = ##rowcount
Set #triggername = object_name(##procid)
If #rowCnt = 0
RETURN
If Update(appstatusrowid)
BEGIN
-----------------------------------------------------------------------------
-- insert a record to the AppDispo table, if AppstatusRowid
-- is being Updated
-----------------------------------------------------------------------------
Insert AppDispo(AppID, LastName, FirstName, [DateTime],Company,Location,LocationName,
StatusDispo,[Username])
Select d.Rowid,d.LastName, d.FirstName, getDate(),C.CompanyCode,l.locnum,l.locname, ast.Displaytext,
SUSER_SNAME()+' '+User
From deleted d with(nolock)
Inner join Test_App a with (nolock) on a.RowID = d.rowid
inner join location l with (nolock) on l.rowid = d.Locationrowid
inner join appstatus ast with (nolock) on ast.rowid = d.appstatusrowid
inner join company c with (nolock) on c.rowid = l.CompanyRowid
--Inner Join Deleted d ON a.RowID = d.RowID
--Where (a.rowid = #Approwid)
END
GO
Any ideas?
Try with this code
SET QUOTED_IDENTIFIER OFF
GO
SET ANSI_NULLS ON
GO
CREATE TRIGGER tri_UpdateAppDispo ON dbo.Test_App
For Update
AS
declare #Approwid int
Declare #triggername sysname
Set #rowCnt = ##rowcount
Set #triggername = object_name(##procid)
If #rowCnt = 0
RETURN
If Update(appstatusrowid)
BEGIN
-----------------------------------------------------------------------------
-- insert a record to the AppDispo table, if AppstatusRowid
-- is being Updated
-----------------------------------------------------------------------------
Insert AppDispo(AppID, LastName, FirstName, [DateTime],Company,Location,LocationName,
StatusDispo,[Username])
Select d.Rowid,d.LastName, d.FirstName, getDate(),C.CompanyCode,l.locnum,l.locname, ast.Displaytext,
SUSER_SNAME()+' '+User
From deleted d with(nolock),location l with (nolock),appstatus ast with (nolock),company c with (nolock)
where d.Locationrowid =l.rowid and
d.appstatusrowid = ast.rowid and
c.rowid = l.CompanyRowid
END GO
whith this code you get the update-deleted row(the old_value)
see you.