MSSQL after insert trigger no working - sql-server

USE [mydatabase]
GO
/****** Object: Trigger [dbo].[trgAfterInsert] Script Date: 14.11.2014 2:30:22 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER TRIGGER [dbo].[trgAfterInsert] ON [dbo].[MYTABLE]
FOR INSERT
AS
declare #ID int;
declare #DATE date;
declare #WHEN smalldatetime;
declare #WHO NVARCHAR(50);
declare #WHAT NVARCHAR(max);
declare #AUDIT_ACTION varchar(100);
select #ID = i.ID from inserted i;
select #DATE = i.DATE from inserted i;
select #WHEN = i.WHEN from inserted i;
select #WHO = i.WHO from inserted i;
select #WHAT = i.WHAT from inserted i;
UPDATE MYTABLE
SET WHEN = GETDATE(),
WHO = USER_NAME(USER_ID())
FROM dbo.MYTABLE
INNER JOIN inserted ON MYTABLE.ID = inserted.ID
insert into AUDIT_LOG
(DATE,WHEN,WHO,WHAT,USER,AUDIT_ACTION,AUDIT_TIMESTAMP)
values
(#DATE,#WHEN,#WHO,#WHAT,USER_NAME(USER_ID()),'NEW ENTRY',GETDATE());
When run,'when' and 'who' dont get inserted into AUDIT_LOG.
What I am trying to do here is to first update the table and then log
altogether.
What am I doing wrong?

I Think The SQL Editor dealing with the Column 'WHEN' as if it is a reserved keyword, so try to put it between brackets like this [WHEN]

Related

Create trigger in stored procedure

I am trying to create a trigger inside stored procedure as it will be removed when the table is dropped.
I am getting an error and am not able to execute it.
CREATE PROCEDURE EC5Trigger2
AS
CREATE TRIGGER trVendorProductsPST
ON VendorProducts
FOR INSERT
AS
BEGIN
SET NOCOUNT ON
DECLARE #SKU VARCHAR(64)
SELECT #SKU = I.SKU FROM inserted AS I
INSERT INTO ProductStockTransactions (SKU, stockingCode)
VALUES (#SKU, 'A')
END
RETURN 0
Here is how you create your trigger inside a stored procedure using dynamic SQL, which is the only way to do it.
CREATE PROCEDURE EC5Trigger2
AS
BEGIN
SET NOCOUNT ON;
DECLARE #TriggerCode NVARCHAR(max);
SET #TriggerCode = 'CREATE TRIGGER trVendorProductsPST
ON VendorProducts
FOR INSERT
AS
BEGIN
SET NOCOUNT ON
DECLARE #SKU VARCHAR(64)
SELECT #SKU = I.SKU from INSERTED as I
INSERT INTO ProductStockTransactions (SKU, stockingCode)
VALUES (#SKU, ''A'')
END';
EXEC(#TriggerCode);
RETURN 0;
END;

Getting rows affected in stored procedure INSERT statement with NOCOUNT OFF

I have a stored procedure in SQL Server 2014 where I first delete data from a table and execute another stored procedure as shown below. I don't care about rows affected on this code so I use SET NOCOUNT ON. I then perform an Insert statement first setting SET NOCOUNT OFF. I would expect the stored procedure to return the rows affected automatically from the INSERT but that has not proven to be the case. I searched SO and found the ##ROWCOUNT and that is working. However, is that really required? Why wouldn't the INSERT statement in the code below return the records affected?
ALTER PROCEDURE [dbo].[SaveTextSetting]
#UserId INT ,
#SettingType INT = 0 ,
#SettingValue NVARCHAR(MAX)
AS
BEGIN
BEGIN
SET NOCOUNT ON;
DELETE FROM Settings
WHERE UserId = #UserId
AND SettingType = #SettingType;
EXEC dbo.PurgeExpiredSettings;
END;
BEGIN
SET NOCOUNT OFF;
INSERT INTO dbo.Settings
( UserId ,
SettingsText ,
SettingType
)
VALUES ( #UserId ,
#SettingValue ,
#SettingType
);
RETURN ##ROWCOUNT; --without this we don't get the rows affected
END;
END;
Are you sure?
CREATE PROCEDURE spTest AS RETURN
GO
ALTER PROCEDURE spTest
AS
BEGIN
SET NOCOUNT OFF
DECLARE #rt int
CREATE TABLE #t (
v int NOT NULL
)
INSERT INTO #t (v)
SELECT v FROM (VALUES (1), (1), (2)) AS t (v)
SET #rt = ##ROWCOUNT
DROP TABLE #t
RETURN #rt
END
GO
DECLARE #rt int
EXEC #rt = spTest
SELECT #rt
GO
DROP PROCEDURE spTest
GO
I would use an output param something like.....
ALTER PROCEDURE [dbo].[SaveTextSetting]
#UserId INT ,
#SettingType INT = 0 ,
#SettingValue NVARCHAR(MAX),
#RowCount INT OUTPUT
AS
BEGIN
SET NOCOUNT ON;
DELETE FROM Settings
WHERE UserId = #UserId
AND SettingType = #SettingType;
EXEC dbo.PurgeExpiredSettings;
INSERT INTO dbo.Settings( UserId ,SettingsText ,SettingType)
VALUES ( #UserId ,#SettingValue ,#SettingType);
SET #RowCount= ##ROWCOUNT;
END

using ##ROWCOUNT in Dynamic SQL

I am using Dynamic SQL to retrieve datasets from multiple tables in order to monitor our daily data extraction from the iSeries system.
I have the below dynamic SQL code which works fine, but I want to only run the data to get each tables records if data has been extracted for the day
-- Create a table variable to store user data
DECLARE #myTable TABLE
(
docID INT IDENTITY(1,1),
docRef VARCHAR(50),
letterDir VARCHAR(500)
);
insert #myTable select docRef, saveDir from alpsMaster.dbo.uConfigData
-- Get the number of rows in the looping table
DECLARE #RowCount INT, #SQL nvarchar(500), #LoopSQL nvarchar(2000), #Date varchar(20)
set #Date='29 Oct 2013'
SET #RowCount = (SELECT COUNT(docID) FROM #myTable)
-- Declare an iterator
DECLARE #I INT
-- Initialize the iterator
SET #I = 1
-- Loop through the rows of a table #myTable
WHILE (#I <= #RowCount)
BEGIN
-- Declare variables to hold the data which we get after looping each record
DECLARE #docRef VARCHAR(10), #saveDir VARCHAR(500)
-- Get the data from table and set to variables
SELECT #docRef = docref FROM #myTable WHERE docID = #I
SELECT #saveDir = letterDir FROM #myTable WHERE docID = #I
-- Display the looped data
--PRINT 'Row No = ' + CONVERT(VARCHAR(2), #I) + '; docRef = ' + #docRef
select #LoopSQL='
use alpsProduction;
declare #SQL nvarchar(500);
IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(''[dbo].['+#docRef+']''))
begin
if exists(select * from sys.columns
where Name = ''YPTMPID'' and Object_ID = OBJECT_ID(''[dbo].['+#docRef+']''))
begin
set #SQL=''SELECT t.template_name,'''''+#saveDir+''''', Y.*
FROM [alpsProduction].[dbo].'+#docRef+' Y, alpsMaster.dbo.uDocumentTemplates t
where DTEINP='''''+#Date+''''' and t.template_Id=y.YPTMPID and t.docRef='''''+#docRef+'''''''
exec sp_executesql #SQL
end
end
'
--print #LoopSQL
exec sp_executesql #LoopSQL
-- Increment the iterator
SET #I = #I + 1
END
so I tried using
IF ##ROWCOUNT >0
Begin
exec sp_executesql #SQL
end
but it seems to never populate the ##Rowcount.
Whats the best way to only run that statement (exec sp_executesql #SQL) if the current table (identified by #docRef) has records in it for todays date (in the format dd mmm yyyy)
Create job to execute a sql script in which u must check inserted data on current day then execute your sp. like this.
IF EXISTS ( SELECT * FROM #TABLE T WHERE DATEDIFF(DD, GETUTCDATE(), T.CREATEDON) = 0 )
BEGIN
EXEC SP_EXECUTESQL #SQL
END

Insert update delete trigger

Dear all I´m having trouble with my trigger.
Am I doing this at all right, right now it only works for Insert. I think I´m pretty close tho please help me if you have the time. I´m trying to store all the inserts, updates and deletes into the table customers_changelog via trigger. There is something wrong with the code I cant delete or update customers I can only insert new ones. Please help my I have been spending plenty of hours on this and just cant get this to work! :)
create table customers (
customerid int identity primary key,
name varchar(100) not null,
address varchar(100)
)
go
create table customers_changelog (
customerid int,
name varchar(100) not null,
address varchar(100),
change_user varchar(32),
change_time datetime,
change_action char(1) default 'I',
check (change_action = 'I' or change_action = 'D')
)
go
CREATE TRIGGER log_changes
ON customers
AFTER INSERT, UPDATE, DELETE
AS
BEGIN
SET NOCOUNT ON;
--
-- Check if this is an INSERT, UPDATE or DELETE Action.
--
DECLARE #customerid1 as int;
DEClARE #name1 as varchar(32);
DECLARE #address1 as varchar(100);
DECLARE #change_action1 as char(1);
DECLARE #change_time1 as datetime;
DECLARE #change_user1 as varchar(32);
select #customerid1 = c.customerid, #name1 = c.name, #address1 = c.address
from customers c, inserted i
where c.customerid = i.customerid
SET #change_time1 = CURRENT_TIMESTAMP;
SET #change_user1 = CURRENT_USER;
INSERT INTO customers_changelog(customerid,name,address,change_action,change_time,change_user)
VALUES(#customerid1,#name1,#address1,'I',#change_time1,#change_user1)
IF EXISTS(SELECT * FROM DELETED)
BEGIN
IF EXISTS(SELECT * FROM INSERTED)
INSERT INTO customers_changelog VALUES(#customerid1,#name1,#address1,'U',#change_time1,#change_user1)
ELSE
INSERT INTO customers_changelog VALUES(#customerid1,#name1,#address1,'D',#change_time1,#change_user1)
END
ELSE
IF NOT EXISTS(SELECT * FROM INSERTED) RETURN;
END
Assuming MS-SQL from syntax - So couple issues here:
1. Need to specify column lists in the "update" and "delete" inserts because the column order in the table doesn't match your inserts.
2. Can't use "inserted" data for delete insert
ALTER TRIGGER [dbo].[log_changes] ON [dbo].[customers] AFTER INSERT, UPDATE, DELETE AS
BEGIN
SET NOCOUNT ON;
DECLARE #customerid1 as int;
DEClARE #name1 as varchar(32);
DECLARE #address1 as varchar(100);
DECLARE #change_action1 as char(1);
DECLARE #change_time1 as datetime;
DECLARE #change_user1 as varchar(32);
select #customerid1 = c.customerid, #name1 = c.name, #address1 = c.address
from customers c, inserted i
where c.customerid = i.customerid
SET #change_time1 = CURRENT_TIMESTAMP;
SET #change_user1 = CURRENT_USER;
IF EXISTS(SELECT * FROM DELETED)
BEGIN
IF EXISTS(SELECT * FROM INSERTED)
INSERT INTO customers_changelog(customerid,name,address,change_action,change_time,change_user)
VALUES(#customerid1,#name1,#address1,'U',#change_time1,#change_user1)
ELSE
BEGIN
select #customerid1 = d.customerid, #name1 = d.name, #address1 = d.address
from deleted d
INSERT INTO customers_changelog(customerid,name,address,change_action,change_time,change_user)
VALUES(#customerid1,#name1,#address1,'D',#change_time1,#change_user1)
END
END
ELSE
BEGIN
IF NOT EXISTS(SELECT * FROM INSERTED) RETURN;
INSERT INTO customers_changelog(customerid,name,address,change_action,change_time,change_user)
VALUES(#customerid1,#name1,#address1,'I',#change_time1,#change_user1)
END
END

Call Stored Procedure within Create Trigger in SQL Server

I have a stored procedure named insert2Newsletter with parameters
(#sex nvarchar(10),
#f_name nvarchar(50),
#l_name nvarchar(70),
#email nvarchar(75),
#ip_address nvarchar(50),
#hotelID int,
#maArt nchar(2))
I want call this stored procedure in an insert trigger. How do I retrieve the corresponding fields from inserted and how do i call insert2Newsletter within the trigger?
I tried without success:
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TRIGGER RA2Newsletter
ON [dbo].[Reiseagent]
AFTER INSERT
AS
DECLARE #rAgent_Name nvarchar(50),
DECLARE #rAgent_Email nvarchar(50),
DECLARE #rAgent_IP nvarchar(50),
DECLARE #hotelID int
BEGIN
SET NOCOUNT ON;
-- Insert statements for trigger here
Select #rAgent_Name=rAgent_Name, #rAgent_Email=rAgent_Email, #rAgent_IP=rAgent_IP, #hotelID=hotelID From Inserted
EXEC insert2Newsletter '','',#rAgent_Name,#rAgent_Email,rAgent_IP,#hotelID,'RA'
END
GO
thx a lot for your feedback... greetings...
I think you will have to loop over the "inserted" table, which contains all rows that were updated. You can use a WHERE loop, or a WITH statement if your primary key is a GUID. This is the simpler (for me) to write, so here is my example. We use this approach, so I know for a fact it works fine.
ALTER TRIGGER [dbo].[RA2Newsletter] ON [dbo].[Reiseagent]
AFTER INSERT
AS
-- This is your primary key. I assume INT, but initialize
-- to minimum value for the type you are using.
DECLARE #rAgent_ID INT = 0
-- Looping variable.
DECLARE #i INT = 0
-- Count of rows affected for looping over
DECLARE #count INT
-- These are your old variables.
DECLARE #rAgent_Name NVARCHAR(50)
DECLARE #rAgent_Email NVARCHAR(50)
DECLARE #rAgent_IP NVARCHAR(50)
DECLARE #hotelID INT
DECLARE #retval INT
BEGIN
SET NOCOUNT ON ;
-- Get count of affected rows
SELECT #Count = Count(rAgent_ID)
FROM inserted
-- Loop over rows affected
WHILE #i < #count
BEGIN
-- Get the next rAgent_ID
SELECT TOP 1
#rAgent_ID = rAgent_ID
FROM inserted
WHERE rAgent_ID > #rAgent_ID
ORDER BY rAgent_ID ASC
-- Populate values for the current row
SELECT #rAgent_Name = rAgent_Name,
#rAgent_Email = rAgent_Email,
#rAgent_IP = rAgent_IP,
#hotelID = hotelID
FROM Inserted
WHERE rAgent_ID = #rAgent_ID
-- Run your stored procedure
EXEC insert2Newsletter '', '', #rAgent_Name, #rAgent_Email,
#rAgent_IP, #hotelID, 'RA', #retval
-- Set up next iteration
SET #i = #i + 1
END
END
GO
I sure hope this helps you out. Cheers!
Finally ...
set ANSI_NULLS ON
set QUOTED_IDENTIFIER ON
GO
ALTER TRIGGER [dbo].[RA2Newsletter]
ON [dbo].[Reiseagent]
AFTER INSERT
AS
declare
#rAgent_Name nvarchar(50),
#rAgent_Email nvarchar(50),
#rAgent_IP nvarchar(50),
#hotelID int,
#retval int
BEGIN
SET NOCOUNT ON;
-- Insert statements for trigger here
Select
#rAgent_Name = rAgent_Name,
#rAgent_Email = rAgent_Email,
#rAgent_IP = rAgent_IP,
#hotelID = hotelID
From Inserted
EXEC insert2Newsletter
'',
'',
#rAgent_Name,
#rAgent_Email,
#rAgent_IP,
#hotelID,
'RA',
#retval
END
The following should do the trick - Only SqlServer
Alter TRIGGER Catagory_Master_Date_update ON Catagory_Master AFTER delete,Update
AS
BEGIN
SET NOCOUNT ON;
Declare #id int
DECLARE #cDate as DateTime
set #cDate =(select Getdate())
select #id=deleted.Catagory_id from deleted
print #cDate
execute dbo.psp_Update_Category #id
END
Alter PROCEDURE dbo.psp_Update_Category
#id int
AS
BEGIN
DECLARE #cDate as DateTime
set #cDate =(select Getdate())
--Update Catagory_Master Set Modify_date=''+#cDate+'' Where Catagory_ID=#id --#UserID
Insert into Catagory_Master (Catagory_id,Catagory_Name) values(12,'Testing11')
END
You pass an undefined rAgent_IP parameter in EXEC instead of the local variable #rAgent_IP.
Still, this trigger will fail if you perform a multi-record INSERT statement.

Resources