Can anybody help to resolve simple t-sql script\'s issue with triggers onboard? I use very simple trigger to copy data from one table to another(there are no relationship be
I'm not sure what the point of the BEGIN TRY
block is. It's clear you want to make sure there is a Role
named Author
- but do you really need to check this in the trigger every time? Can't you populate it now, and never have to check again?
BEGIN/END
wrapper around module body, and added SET NOCOUNT ON;
COUNT(*) from inserted
to IF EXISTS
. There's no reason to bother retrieving the actual count when you really don't care if it's 1 or 10 or 6000.inserted
. As @marc_s pointed out, you can't rely on this because triggers are fired per statement, not per row. So if you have a multi-row insert, your existing trigger would have only ever processed one arbitrary row.TRY/CATCH
block. In most cases it is more efficient to check for violations yourself than to have SQL Server do it for you, and in a trigger especially so because it has an effect not only on the trigger code but also the outer transaction (as you have seen). Especially in your case, where an exception would be raised probably every time after the first time this trigger runs.Author
. Please always include your column list in SELECT and INSERT statements. In addition to the reasons stated in that post, it also makes it easier for others to help you re-write your code.CREATE TRIGGER dbo.AuthorInsert ON dbo.Author INSTEAD OF INSERT
AS
BEGIN
SET NOCOUNT ON;
IF EXISTS (SELECT 1 FROM inserted)
BEGIN
DECLARE @emps TABLE(id INT, NameID INT);
DECLARE @RoleID INT;
SELECT @RoleID = RoleID FROM dbo.Roles WHERE RoleName = 'Author';
IF @RoleID IS NULL
BEGIN
-- probably not necessary to do this over and over again
-- unless someone is sabotaging your Roles table.
INSERT dbo.Roles(RoleName) SELECT 'Author';
SELECT @RoleID = SCOPE_IDENTITY();
END
INSERT dbo.Employee(NameID, ReestrCodeID, RoleID, PassportDataID,
AddressID, PhoneID) OUTPUT inserted.EmployeeID, inserted.NameID
INTO @emps SELECT NameID, ReestrCodeID, @RoleID, PassportDataID,
AddressID, PhoneID FROM inserted;
-- this seems redundant. If an author is linked to an employee,
-- why do we need to store all of this information again?
INSERT dbo.Author(EmployeeID, NameID, ReestrCodeID, RoleID,
PassportDataID, AddressID, PhoneID)
SELECT e.id, i.NameID, i.ReestrCodeID, @RoleID,
i.PassportDataID, i.AddressID, i.PhoneID FROM @emps AS e
INNER JOIN inserted AS i ON e.NameID = i.NameID;
END
END
GO