Trying to create a trigger for a table - sql-server

I have a table [dbo].[main] composed of 4 columns:
MovieGenre
MusicGenre
PodcastGenre
CombinedColumn
I want to create a trigger where if anything is inserted in MovieGenre, PodcastGenre, MusicGenre that it also gets inserted into CombinedColumn.
CREATE TRIGGER trgAfterInsert ON [dbo].[Main]
FOR INSERT
AS
???
GO

--dbo.main` needs a key column (let's say its a identity column 'id1')
CREATE TRIGGER trgAfterInsert
ON [dbo].[Main]
FOR INSERT AS
declare #allcols varchar(500)
declare #key1 int
set #key1 = ident_current('dbo.main')
select #allcols = MovieGenre+' '+ PodcastGenre+' '+ MusicGenre from inserted
update dbo.main set CombindedColumn= #allcols where id1 = #key1

Okay, this will add values to Combined Column one after another. "Stacking" them as you want:
CREATE TRIGGER trgAfterInsert on dbo.main
AFTER INSERT
AS
INSERT INTO yourTable(CombinedColumn)
SELECT MovieGenre
FROM inserted
UNION ALL
SELECT PodcastGenre
FROM inserted
UNION ALL
SELECT MusicGenre
FROM inserted
GO

Related

Trigger to insert multiple record

I'm trying to create a trigger to insert all the value that I delete from a table in a "Backup" table,
Ex:
Table 1: NomePilota, ModelloVettura, NomeScuderia
BackupTable1 (Table 2): NomePilota, ModelloVettura, NomeScuderia
What I want from the trigger to do: Insert into 'Table 2' deleted values from table 1.
I tried like this:
CREATE TRIGGER Backup ON dbo.Table1 AFTER (i can only use after) DELETE AS
BEGIN
DECLARE #Pilota VARCHAR(20) = (SELECT NomePilota FROM deleted)
DECLARE #Vettura VARCHAR(50) = (SELECT ModelloVettura FROM deleted)
DECLARE #Scuderia VARCHAR(20) = (SELECT NomeScuderia FROM deleted)
INSERT INTO Table2 (NomePilota, ModelloVettura, NomeScuderia) VALUES (#Pilota, #Vettura, #Scuderia)
But it send a error:
Cannot insert multiple records in #Pilota, #Vet, #Scud
How can I fix that? Does the deleted table already have a default ID column to use like in a for? Can I use something like vectors? (like #Nome[] = SELECT * FROM Tabella, Insert into Tabella2 (Nome) VALUES #Nome[#Numero (numero is like the record number of nome]).
Why not make life simple?
INSERT INTO Table2 (NomePilota, ModelloVettura, NomeScuderia)
SELECT NomePilota, ModelloVettura, NomeScuderia FROM deleted
The insert statment can work on the results of a select -- here we leverage this to simplify the task at hand.

Creating a temporary table within a TRIGGER with GROUP BY

I need to create and use a temporary table with GROUP BY clause within a trigger, but I'm having difficulties doing so.
My attempt:
Here I'm trying to use two temporary tables which are dropped after the trigger reach an end.
First I create a #Temptable and the trigger.
CREATE TABLE #TempTable (admID smallint, diagID smallint);
CREATE TRIGGER tr_newTest
ON Adm_Diag
FOR INSERT
AS
BEGIN
...
END
Since the table inserted only contains rows for a current INSERT and UPDATE statements I'm passing several INSERT and UPDATE statements to #TempTable.
DECLARE #admID smallint
SELECT #admID = Adm_ID
FROM inserted
DECLARE #diagID smallint
SELECT #diagID=Diag_ID
FROM inserted
INSERT INTO #TempTable VALUES (#admID, #diagID)
Now with this data I want to create a temporary table that groups the rows of #TempTable:
SELECT *
INTO #TempGroupTable
FROM
(
SELECT admID, COUNT(*) as Diag
FROM #TempTable
GROUP BY admID
) t1
WHERE Diag > 2
The whole script
CREATE TABLE #TempTable (admID smallint, diagID smallint);
CREATE TRIGGER tr_newTest
ON Adm_Diag
FOR INSERT
AS
BEGIN
DECLARE #admID smallint
SELECT #admID = Adm_ID
FROM inserted
DECLARE #diagID smallint
SELECT #diagID=Diag_ID
FROM inserted
INSERT INTO #TempTable VALUES (#admID, #diagID)
-- Below I'm tring to create #TempGroupTable
SELECT *
INTO #TempGroupTable
FROM
(
SELECT admID, COUNT(*) as Diag
FROM #TempTable
GROUP BY admID
) t1
WHERE Diag > 2
END
After executing the trigger I get an error:
Msg 208, Level 16, State 0, Line 41 Invalid object name
'#TempGroupTable'.
How can I create #TempGroupTable?
Not quote sure what you are trying to do but would a global temporary tables which starts with ## work for you? So make the #TempGroupTable into ##TempGroupTable?
Why not dispense with all the overhead of temp tables and variables? Try:
CREATE TRIGGER tr_newTest
ON Adm_Diag
INSTEAD OF INSERT
AS
BEGIN
INSERT INTO Adm_Diag (adminID, Diag)
SELECT admID, COUNT(*) as Diag
FROM inserted
GROUP BY admID
END

Historical Table in SQL Server

I have two tables; the first named PAYMENT and the second is a historical table named RecordPay.
I have two triggers, the first one is for insert in order to insert into the historical tables records from Payment table.
Here is the code:
ALTER TRIGGER [dbo].[INSERT_HIST]
ON [dbo].[PAYMENT]
FOR INSERT
AS
BEGIN
DECLARE #User_op varchar(50)
DECLARE #RGNO varchar(50)
DECLARE #PAYEUR varchar(50)
DECLARE #DATESYS SMALLDATETIME
DECLARE #RG_DATE SMALLDATETIME
DECLARE #RG_Montant varchar(50)
SELECT #User_op = cbUserName
FROM cbUserSession
WHERE cbSession = ##SPID
SELECT #PAYEUR = CT_NumPayeur FROM INSERTED
SELECT #DATESYS = GETDATE()
SELECT #RG_Montant = RG_Montant FROM INSERTED
SELECT #RG_DATE = RG_DATE FROM INSERTED
SELECT #RGNO = RG_No FROM INSERTED
INSERT INTO RecordPay (RG_NO, PAYEUR, CAISSIER, Montant, DATESYS, DATECAI)
VALUES (#RGNO, #PAYEUR, #user_op, #RG_Montant, #DATESYS, #RG_DATE)
This works well, my problem when I delete a row from PAYMENT, in RecordPay the record exists, and then when I insert another row in PAYMENT I had two RG_NO whith the same number.
For example I insert a row in PAYMENT with RG_NO=1 then I deleted, and I create another row with RG_NO=2, in the recordPay (historical table) i get two lines with RG_NO=1.
Here is the trigger for delete but it does not work
ALTER TRIGGER [dbo].[DEL_HIST]
ON [dbo].[PAYMENT]
AFTER DELETE
AS
BEGIN
DECLARE #User_op varchar(50)
DECLARE #RGNO varchar(50)
DECLARE #PAYEUR varchar(50)
DECLARE #DATESYS SMALLDATETIME
DECLARE #RG_DATE SMALLDATETIME
DECLARE #RG_Montant varchar(50)
SELECT #PAYEUR = CT_NumPayeur FROM DELETED
SELECT #RG_Montant = RG_Montant FROM DELETED
SELECT #RG_DATE = RG_DATE FROM DELETED
SELECT #RGNO = RG_No FROM DELETED
DELETE FROM RECORDPAY WHERE
RG_NO=#RGNO and PAYEUR= #PAYEUR and CAISSIER=#user_op and Montant=#RG_Montant
END
Your trigger will BREAK as soon as an INSERT statement inserts more than 1 row at a time - because in that case, your trigger gets called once for the INSERT statement, and Inserted will contain multiple rows.
Which one of those 10 rows are you selecting from here??
SELECT #PAYEUR = CT_NumPayeur FROM INSERTED
SELECT #RG_Montant = RG_Montant FROM INSERTED
SELECT #RG_DATE = RG_DATE FROM INSERTED
SELECT #RGNO = RG_No FROM INSERTED
It's arbitrary and non-deterministic - and you will simply ignore all other rows in Inserted.
You need to rewrite your trigger to take this into account:
ALTER TRIGGER [dbo].[INSERT_HIST]
ON [dbo].[PAYMENT]
FOR INSERT
AS
BEGIN
DECLARE #User_op varchar(50)
SELECT #User_op = cbUserName
FROM cbUserSession
WHERE cbSession = ##SPID
-- insert a record for ALL the rows that were inserted into
-- your history table in a single, elegant, set-based statement
INSERT INTO RecordPay (RG_NO, PAYEUR, CAISSIER, Montant, DATESYS, DATECAI)
SELECT
RG_No, CT_NumPayeur, #User_op, RG_Montant, SYSDATETIME(), RG_Date
FROM
Inserted

Use Trigger to insert value when Value is inserted into any column in another table

I have a GenreTable:
I have a "CombinedTable":
I have a trigger:
ALTER TRIGGER [dbo].[trgAfterUpdate] on [dbo].[Genre]
AFTER UPDATE
AS
INSERT INTO [dbo].[CombinedTags]([Combined])
SELECT TOP 1 PodcastGenre
FROM Genre
ORDER BY rowID DESC
I am trying the trigger so that when a value is in ether of the columns in the "GenreTable" [(MovieGenre), (MusicGenre), (PodcastGenre)]
It inserts the "RowID" into the "ForeignRowID" column of the "CombinedTable" AND the "value" that's being inserted into ether of the columns of the "GenreTable" into the "Combined". Thank you for your help.
AS
declare #rowid int
declare #insfld varchar(max)
select #rowid = rowid from inserted
-- assume that only one field has value....
select #insfld = case when moviegenre is not null then moviegenre
when musicgenre is not null then musicgenre
else podcastgenre end whichone
from inserted
INSERT INTO [dbo].[CombinedTags]([Combined], foreignkeyid) values
( #insfld,#rowid)

sqlserver assigning last inserted Id to another column in one query

when this query is executed
DECLARE #Temp TABLE (ID INT IDENTITY,Name VARCHAR(50),ID2 INT NULL)
INSERT INTO #Temp ([Name]) VALUES ('Ali')
UPDATE #Temp SET ID2= (SELECT SCOPE_IDENTITY()) WHERE [ID]=(SELECT SCOPE_IDENTITY())
INSERT INTO #Temp ([Name]) VALUES ('Veli')
UPDATE #Temp SET ID2= (SELECT SCOPE_IDENTITY()) WHERE [ID]=(SELECT SCOPE_IDENTITY())
SELECT * FROM #Temp
We can get this table
ID-NAME-ID2
1 - Ali - 1
2 - Veli - 2
is there a way to do this in one insert query ( Assigning inserted id to another column without using idendity property in that column) ?
thanks a lot.
You want to make it a computed column like below
create TABLE Temp(ID INT IDENTITY,Name
VARCHAR(50),
ID2 AS ID PERSISTED);
Then insert rows ... your ID values will be persisted in ID2 column
INSERT INTO Temp ([Name])
VALUES ('Ali');
INSERT INTO Temp ([Name])
VALUES ('Veli');
INSERT INTO Temp ([Name])
VALUES ('Neli');
Which will results in
See a demo fiddle here http://sqlfiddle.com/#!3/59fca/1
EDIT:
If you can't change your table structure then the only way insert ID value to ID2 column is the way you are currently doing it cause in same insert statement the identity value is still not available and so it will be null.

Resources