SQL Server trigger if update() with condition - sql

I have a table in SQL Server that has 3 columns: ID, NAME, VALUE.
This table has 2 rows with ID=1 and ID=2.
(The value of ID doesn't change).
Every moment of time the value of column VALUE changes. Every time the column VALUE changes, I want to insert this updated value into a table (Device1 for ID=1, Device1 for ID=2).
I created a trigger for updating as if update(VALUE) begin...but it doesn't do the work.
Is there a way to add a condition in if update(VALUE) to work in each row
I used this query
Create Trigger insertIntoDevices
On ITEMS
For Update
As
If Update(VALUE)
Begin
Insert Into table device1
Where ID = 1
Insert Into table device2
Where ID = 2
End
With this query each update in column VALUE inserts VALUE into device1 and device1 and that duplicates values in my tables device1 and device2.

Table creation on the below ;
CREATE TABLE TestTable(
ID INT IDENTITY(1,1),
Name VARCHAR(5),
VALUE NVARCHAR(50)
)
GO
CREATE TABLE device1(
VALUE NVARCHAR(50)
)
GO
CREATE TABLE device2(
VALUE NVARCHAR(50)
)
GO
Insertion for ID=1 and ID=2
GO
INSERT INTO TestTable(Name,Value)
VALUES('Test1','test1'),('TEST2','test2')
Firstly,To find new values for each row you can use 'inserted' but it can be include non-changed data. For example: ID =1,Name='test1' and VALUE='test1' and updation of name column will be also included in inserted.
Secondly,To find old values for each row you can use 'deleted'.
After that we find the values that only includes updation for VALUE.
To Sump Up,
Finding Inserted rows and deleted rows will give us the result of each rows new and old values. We used intersection (INNER JOIN ) to find only changed values.
CREATE TRIGGER [dbo].[insertIntoDevices]
ON [dbo].[TestTable]
AFTER UPDATE
AS
BEGIN
DECLARE #InsertedTable table (
InsertedID INT,
InsertedName VARCHAR(5),
InsertedVALUE NVARCHAR(50)
)
DECLARE #DeletedTable table (
DeletedID INT,
DeletedName VARCHAR(5),
DeletedVALUE NVARCHAR(50)
)
INSERT INTO #InsertedTable(InsertedID,InsertedName,InsertedVALUE)
SELECT ID,[Name],[Value] FROM inserted;
INSERT INTO #DeletedTable(DeletedID,DeletedName,DeletedVALUE)
SELECT ID,Name,Value FROM deleted;
INSERT INTO device1(VALUE)
SELECT UpdatedValue = it.InsertedVALUE
FROM #InsertedTable as it
INNER JOIN #DeletedTable as dt ON it.InsertedID = dt.DeletedID AND ISNULL(dt.DeletedVALUE,'') <> ISNULL(it.InsertedVALUE,'')
WHERE it.InsertedID = 1
INSERT INTO device2(VALUE)
SELECT UpdatedValue = it.InsertedVALUE
FROM #InsertedTable as it
INNER JOIN #DeletedTable as dt ON it.InsertedID = dt.DeletedID AND ISNULL(dt.DeletedVALUE,'') <> ISNULL(it.InsertedVALUE,'')
WHERE it.InsertedID = 2
END
To test I used the updation queries on the below;
--Example 1
UPDATE TestTable
SET Value='selam'
WHERE ID = 1
--Example 2
UPDATE TestTable
SET Value='hi'
WHERE ID = 2

Related

I need to create 3 rows in Student_Fee table when 1 row is inserted in Student table using trigger

Following is the trigger
Create TRIGGER [dbo].[Student]
ON [dbo].[Student]
After INSERT
AS
BEGIN
Insert Into Student_Fee([StudentID],[InstID],[PersonID],[FeeSubmiteTime],[FeeMsg],[Type])
Select NULL,3,PersonID,getdate(),'Student submitted on','Student' from INSERTED
END
I need to create 3 rows in Student_Fee table when 1 row is inserted in Student table.First row in Student_fee must have StudentID Null and for other two rows student ID is filled obtained from previous table. Also, Feemsg should be different for the 3 rows. It is text and could be any value. And for type there are two types Student and Admin and the types are also not fixed. They can vary while inserting rows.
How can I do that by using trigger?
here you go :
CREATE TABLE Temp1abhari (
id INT identity(1, 1)
,number INT
);
CREATE TABLE Temp2abhari (
id INT
,number INT
);
CREATE TRIGGER TTemp1abhari ON Temp1abhari
FOR INSERT
AS
BEGIN
INSERT INTO Temp2abhari
VALUES (
NULL
,1
);
INSERT INTO Temp2abhari
SELECT ID
,2
FROM Inserted;
INSERT INTO Temp2abhari
SELECT ID
,3
FROM Inserted;
END

ignoring last value if its the same as current value

I have an table where i would like to query the following:
The data comes in batches . This data is combined with an id.
This ID only gets send ones when the new batch comes in. After that the ID only changes when there is a new batch . In the mean time the value stays null
What i need to do is if new data comes in and it has the same id as the previous batch i have to continue the insert with null in the id field instead of pushing a new row with the same id value.
Beneath is a simplistic view of the table
ID Values
1 10
null 20
null 20
null 20
null 20
2 20
null 20
null 20
null 20
null 20
1 20
null 20
If you could help me point in a directions that would help me a lot.
Maybe to clearify the id value is a set of tags. So there are some definied tags(100 or more) and when a new batch comes the batch gets a tag with it. And if that tag is the same as the previous the null has to continue instead of inserting the same tag
You'll need to add an identity field (or a timestamp) in order to be able to query the latest ID.
ALTER TABLE MyTable ADD MyIdent INT IDENTITY(1, 1) NOT NULL
Then on your insert (if your Id value is NULL) you can call
INSERT INTO MyTable (Id, Values)
SELECT TOP 1 Id, #ValuesVariable
FROM MyTable
WHERE Id IS NOT NULL
ORDER BY MyIdent DESC
This below Sp may helps to inert data try this
IF OBJECT_ID('tempdb..#Temp')IS NOT NULL
DROP TABLE #Temp
CREATE TABLE #Temp (ID INT,[Values] INT)
CREATE PROCEDURE usp_Insert
(
#Id INT,
#Values INT
)
AS
BEGIN
IF NOT EXISTS (SELECT 1 FROM #Temp WHERE ID = #ID)
BEGIN
INSERT INTO #Temp(ID,[Values])
SELECT #Id,#Values
END
ELSE
INSERT INTO #Temp(ID,[Values])
SELECT NULL,#Values
END
EXEC usp_Insert 2,12
SELECT * FROM #Temp

How to capture the unique identifier after the insert [duplicate]

This question already has answers here:
How do I return a new IDENTITY column value from an SQLServer SELECT statement?
(7 answers)
Closed 8 years ago.
I have to create new email records in an existing table in the joining table I would like to update a field that would denote that this is a new record.
Example:
INSERT INTO dbo.email.email (dbo.email.eml_address, dbo.email.eml_customer_key)
SELECT new_email, new_customer_key
FROM NEW_TABLE
Update dbo.email_ext
Set dbo.email_ext.new_eml = '1'
Where dbo.email_ext.eml_key_ext = 'Recently create key from insert statement shown above'
You'll want to use the SCOPE_IDENTITY() value, this will contain the ID of the record just created, but only one.
Assuming you're handling ONE record:
DECLARE #ID INT
INSERT INTO dbo.email (eml_address, eml_customer_key)
SELECT new_email, new_customer_key
FROM NEW_TABLE
SET #ID = SCOPE_IDENTITY()
Update dbo.email_ext
Set new_eml = '1'
Where eml_key_ext = #ID
If you're inserting multiples you need to output the list into a table (in this case a table variable) and you can update them all at once.
DECLARE #myIDs TABLE (NEWID INT)
INSERT INTO dbo.email (eml_address, eml_customer_key)
OUTPUT inserted.ID INTO #myIDs
SELECT new_email, new_customer_key
FROM NEW_TABLE
Update t
Set new_eml = '1'
from dbo.email_ext t
join #myIDs m
on t.eml_key_ext = m.ID
Use an OUTPUT clause to capture autogenerated ids/guids/defaults/etc.
CREATE TABLE #test (
id int identity(1,1) primary key,
uid uniqueidentifier DEFAULT NEWID(),
value varchar(max)
)
INSERT #test (value)
OUTPUT inserted.*
SELECT 'test'
id guid value
----------- ------------------------------------ ---------
1 72B70577-2679-4C2A-A575-62D30807B9D2 test
(1 row(s) affected)

Loop through rows and add a number for a column for each of them automatically in SQL Server

I have got an over 500 rows table with a column called ID which is of datetype INT. Currently the values are all NULL.
What I want to achieve is to populate the ID column with an incremental number for each row, say 1, 2, 3, 4, ..., 500 etc.
Please give me a help with any idea how to achieve this by SQL script.
using ROW_NUMBER in a CTE is one way, but here's an alternative; Create a new id1 column as int identity(1,1), then copy over to id, then drop id1:
-- sample table
create table myTable(id int, value varchar(100));
-- populate 10 rows with just the value column
insert into myTable(value)
select top 10 'some data'
from sys.messages;
go
-- now populate id with sequential integers
alter table myTable add id1 int identity(1,1)
go
update myTable set id=id1;
go
alter table myTable drop column id1;
go
select * from myTable
Result:
id value
----------- -------------
1 some data
2 some data
3 some data
4 some data
5 some data
6 some data
7 some data
8 some data
9 some data
10 some data
While you could also drop and recreate ID as an identity, it would lose its ordinal position, hence the temporary id1 column.
#create one temporary table
CREATE TABLE Tmp
(
ID int NOT NULL
IDENTITY(1, 1),
field(s) datatype NULL
)
#suppose your old table name is tbl,now pull
#Id will be auto-increment here
#dont select Id here as it is Null
INSERT INTO Tmp (field(s) )
SELECT
field(s)
FROM tbl
#drop current table
DROP TABLE tbl
#rename temp table to current one
Exec sp_rename 'Tmp', 'tbl'
#drop your temp table
#write alter command to set identitry to Id of current table
good luck

Select data, setting a calculated value into a column

I'm selecting data from a table within a trigger (FOR UPDATE). Some rows I'm selecting have been updated by a transaction, that initiated the trigger, and some rows are not. I'd like to write somewhere in the dataset a flag for every row, which value would be calculated as "id IN (SELECT [id] FROM INSERTED)". This flag would show, is a row updated with the last transaction or not.
Is it possible in SQL?
Sure, I can do 2 separate queries, with 2 different conditions, but the trigger perfomance is real bottleneck...
Here's an example for SQL Server:
if object_id('TriggerTest') is not null
drop table TriggerTest
create table TriggerTest (id int identity, name varchar(50), inLastUpdate bit)
insert TriggerTest (name) values ('joe'), ('barrack'), ('george'), ('dick')
go
create trigger dbo.TriggerTestDelete
on TriggerTest
after update
as begin
declare #date datetime
set #date = GETDATE()
update dbo.TriggerTest
set inLastUpdate =
case when id in (select id from inserted) then 1
else 0
end
end
go
update TriggerTest set name = name where id in (1,2)
update TriggerTest set name = name where id in (1,3)
select * from TriggerTest
This prints:
id name inLastUpdate
1 joe 1
2 barrack 0
3 george 1
4 dick 0