After Insert Trigger using the values from the INSERT - sql-server

I have the following query:
INSERT INTO LOAN (MemberSSN, VolumeID, LoanDate)
OUTPUT inserted.MemberSSN, inserted.VolumeID, inserted.LoanDate
VALUES ('488-40-', 2, GETUTCDATE())
I want a trigger that, upon insertion in the LOAN table, the following query is executed - an INSERT into the VOLUME_VOLUME_STATUS table:
INSERT INTO VOLUME_VOLUME_STATUS (VolumeID, StatusID, DateCreated)
VALUES (>>previouslyInsertedVolumeID<<, 2, getutcdate())
As you can see, I am unsure how to tell SQL the VolumeID that has just been inserted, which is 2.
Below is the trigger that I wrote:
CREATE TRIGGER LoanStatusUpdate_OnLoaning
AFTER INSERT
ON LOAN
BEGIN
INSERT INTO VOLUME_VOLUME_STATUS (VolumeID, StatusID, DateCreated)
VALUES (>>previouslyInsertedVolumeID<<, 2, getutcdate())
END
Therefore, what should be passed as the value for the VolumeID column so that the parameter is the one from the INSERT prior to the trigger being activated?
Figured some errors in the previous trigger. Here's the one with fixed syntax errors:
CREATE TRIGGER LoanStatusUpdate_OnLoaning
ON LOAN
AFTER INSERT
AS
INSERT INTO VOLUME_VOLUME_STATUS (VolumeID, StatusID, DateCreated)
VALUES (New.VolumeID, 2, getutcdate())
GO

I think you just want to use inserted:
CREATE TRIGGER LoanStatusUpdate_OnLoaning ON LOAN AFTER INSERT
BEGIN
INSERT INTO VOLUME_VOLUME_STATUS (VolumeID, StatusID, DateCreated)
SELECT i.VolumeId, 2, getutcdate()
FROM inserted i;
END;
You can also pull the StatusId from inserted as well. And DateCreated could be set as a default value in VOLUME_VOLUME_STATUS.

Related

Insert into with select statement where value is not null

I want to perform an insert operation based on the select statement from another table in SQL Server.
I have built this:
INSERT INTO Table1
SELECT table2.var1, table2.var2, 1, GETDATE(), 1, GETDATE(),0
FROM table2
The values in Table1 are all NOT NULL, and there is a couple of record of table2.var2 where there is a null value, I want to skip the Null and continue with the operation.
You can filter the rows where table2.var2 is null in a WHERE clause.
INSERT INTO table1
(<list of target columns>)
SELECT table2.var1,
table2.var2,
1,
getdate(),
1,
getdate(),
0
FROM table2
WHERE table2.var2 IS NOT NULL;
You should also explicitly list the targeted columns in any INSERT so that statements don't break if the number or order of columns change in the target table.

Inserting rows from one database table into two different tables in another database

I need to add about 600 records from one database to another one.
The first part inserts from a select like this:
INSERT INTO RelayMapper.dbo.radioSignals(CstarID, StarName, SystemName, StarSystemCount, SuperNova, DateCreated)
SELECT NEWID(), startName, systemName, 1, 1, getDate()
FROM AISourceMapper.dbo.radioSignals
WHERE rangeICW = 5
This is where it gets tricky and I don't know how to do it.
So for each row inserted above, I need to also insert related data into another table.
The NEWID() above would be used to insert a row and then I'd need to insert the starCoordinates as well from AISourceMapper.dbo.radioSignals and it would look something like this:
INSERT INTO RelayMapper.dbo.radioSources(CstarID, starCoordinates, isVerified)
VALUES('1150C651-5D9A-4C13-9BE7-EF4AZ2549112', 'R.A. 13h 27m, DEC. -47deg, 29m', 1)
starCoordinates is also from the same table and row that I'm SELECTing from(AISourceMapper.dbo.radioSignals)
Is there a way to do something like this?
One option is to copy all data from AISourceMapper.dbo.radioSignals into a temp table and at the same time assign GUIDS and then insert from this table into your destination tables.
SELECT NEWID() AS CstarID, *
INTO #TempTable
FROM AISourceMapper.dbo.radioSignals
WHERE rangeICW = 5
INSERT INTO RelayMapper.dbo.radioSignals( CstarID, StarName, SystemName, StarSystemCount, SuperNova, DateCreated )
SELECT CstarID, startName, systemName, 1, 1, getDate()
FROM #TempTable
INSERT INTO RelayMapper.dbo.radioSources( CstarID, starCoordinates, isVerified )
SELECT CstarID, starCoordinates, isVerified
FROM #TempTable
You can use OUTPUT clause to get the inserted values and then use them to insert into another table.
DECLARE #insertedId TABLE(CStartID UNIQUEIDENTIFIER)
INSERT INTO RelayMapper.dbo.radioSignals(CstarID, StarName, SystemName, StarSystemCount, SuperNova, DateCreated)
OUTPUT inserted.CStarID INTO #insertedId
SELECT NEWID(), startName, systemName, 1, 1, getDate()
FROM AISourceMapper.dbo.radioSignals
WHERE rangeICW = 5;
--with values clause
INSERT INTO RelayMapper.dbo.radioSources(CstarID, starCoordinates, isVerified)
SELECT CStarId
'R.A. 13h 27m, DEC. -47deg, 29m', 1
FROM #insertedId;
--WITH select clause
INSERT INTO RelayMapper.dbo.radioSources(CstarID, starCoordinates, isVerified)
SELECT i.CStarId, rs.starCoordinates, 1
FROM AISourceMapper.dbo.radioSignals AS rs
CROSS JOIN #insertedId AS i
WHERE rs.rangeICW = 5;

Insert OUTPUT Insert.id to another table in multiple values insert

Just for simplicity suppose I have two tables
user table (id, email)
user log table (id, date)
whatever id gets inserted in user table, same id should be inserted in user_log table also else transaction should fail.
How can I do this
BEGIN TRANSACTION
INSERT into user(id, email) OUTPUT Inserted.id (1, 'a#x.com', 'x'), (2, 'b#x.com', 'y')
// I also want to be able to do
INSERT into user_log(id, date) values(1, date), (2, date)
COMMIT TRANSACTION
You can insert the output directly into the user_log table:
BEGIN TRANSACTION
INSERT INTO [User] (ID, Email)
OUTPUT inserted.id, CURRENT_TIMESTAMP INTO user_log(id, date)
VALUES (1, 'a#x.com'), (2, 'b#x.com');
COMMIT TRANSACTION
Example on SQL Fiddle
If you need to return the ids you can just add a second OUTPUT clause:
BEGIN TRANSACTION
INSERT INTO [User] (ID, Email)
OUTPUT inserted.id, CURRENT_TIMESTAMP INTO user_log(id, date)
OUTPUT inserted.id
VALUES (1, 'a#x.com'), (2, 'b#x.com');
COMMIT TRANSACTION
Method 1 - "Double Insert" using OUTPUT
Pros: single statement, no hidden triggers (method 2).
Cons: only works in this statement i.e. doesn't capture all insert events
INSERT INTO dbo.users (id)
OUTPUT inserted.id
INTO user_log (id)
VALUES (9)
, (3)
, (7)
;
Method 2 - Trigger
Pros: Captures all insert events
Cons: Triggers are "hidden" mechanisms
CREATE TRIGGER user_log_after_insert
ON dbo.users
AFTER INSERT
AS
BEGIN
INSERT INTO dbo.user_log (id)
SELECT id
FROM inserted
;
END
;
Method 3 - Temp Table
Included for completeness for when using older versions of SQL Server that don't support method 1
CREATE TABLE #temp (
id int
);
INSERT INTO #temp (id) VALUES (9);
INSERT INTO #temp (id) VALUES (3);
INSERT INTO #temp (id) VALUES (7);
BEGIN TRAN
INSERT INTO dbo.users (id)
SELECT id
FROM #temp
;
INSERT INTO dbo.user_log (id)
SELECT id
FROM #temp
;
COMMIT TRAN

Create Trigger to update insert to table specific values only

I need to create trigger prevent insert and update to table employee under age 21 and over age 67
what next on the code?
CREATE TRIGGER allowInsertUpdateemployee ON dbo.employee
AFTER UPDATE, INSERT
AS
BEGIN
DECLARE #v_ageLow INT = 21,
#v_ageHigh INT = 67,
#v_dateLow date,
#v_dateHigh date
SET #v_dateLow = DATEADD(YEAR, -1 * #v_ageLow, GETDATE())
SET #v_dateHigh = DATEADD(YEAR, -1 * #v_ageHigh, GETDATE())
END
Since the upper and lower bounds are fixed, a check constraint might be a more appropriate solution than a trigger
ALTER TABLE employee ADD CONSTRAINT ck_employee_age CHECK
(DateOfBirth BETWEEN DATEADD(YEAR,-67,GETDATE()) AND DATEADD(YEAR,-21,GETDATE()))
Use "INSTEAD OF INSERT, UPDATE" trigger;
Use INSERTED table to check new incoming values, raiserror if needed;
Use DELETED table to detect if update is processing (this can
help);
Do manual insert or update then (if needed).
INSERT INTO
dbo.employee
SELECT
*
FROM
INSERTED I
I hope this will do
This will not fetch accurate age , However if your method gets you an accurate date you can use your code with it .
OR
you can also use below code to get age:
SELECT DATEDIFF(Day,'2011-11-03' , GETDATE()) /365
SELECT DATEDIFF(Day,#Age , GETDATE())
/365
CREATE TRIGGER allowInsertUpdateemployee ON dbo.employee
INSTEAD OF Insert
AS
BEGIN
DECLARE #v_ageLow INT,
#v_ageHigh INT,
#v_date date,
--#v_dateHigh date
SET #v_ageLow = SELECT DATEDIFF(Year,#v_date , GETDATE())
SET #v_ageHigh = SELECT DATEDIFF(Year,#v_date , GETDATE())
BEGIN
if(#v_ageLow <21 AND #v_ageHigh >67)
BEGIN
RAISERROR('Cannot Insert or Update where User is not in age limit);
ROLLBACK;
END
ELSE
BEGIN
// else write your insert update query
Insert into values ()
PRINT 'Unable to Insert-- Instead Of Trigger.'
END
END
You have to put OR in the where clause. The employee can't be under 21 AND more than 67.
Create TRIGGER tr_Too_young_or_too_old
ON TableName
AFTER INSERT
AS
if exists ( select *, DATEDIFF(yy, birthdate, GETDATE()) as age
from TableName
where DATEDIFF(yy, birthdate, GETDATE()) < 21 or DATEDIFF(yy, birthdate, GETDATE()) > 67 )
begin
rollback
RAISERROR ('Cannot Insert or Update where User is not in age limit', 16, 1);
end

Insert next records

I have requirement like, I have to insert the records whenever for one BID, one SID, if the execdate and stopbilldate exist, then I need to insert new record with NULL as Stopbilldate
sample example is as follows:
Sno BID SID LID Comapny Execdate StopBilldate
5 BLDG100 C 6500 Cole 1/5/2012 5/29/2012
6 BLDG100 C 000000 Vacant 5/30/2012 NULL
You can do this with a TRIGGER on your table. A trigger is a kind of stored procedure that will execute when an event occurs.
Here is a sample of what you could place on your table:
CREATE TRIGGER [trg_yourTable]
ON [yourTable]
AFTER INSERT
AS
BEGIN
SET NOCOUNT ON;
-- Insert statements for trigger here
INSERT INTO yourTable (bid, sid, lid, company, execdate, stopbilldate)
SELECT i.bid, i.sid, 0, 'Vacant', DATEADD(day, 1, i.stopbilldate), null
FROM inserted i
WHERE i.bid is not null
and i.sid is not null
END
When you INSERT data in the table, this will run and INSERT the additional row that you want added to the table.

Resources