I'm having trouble creating a trigger for my database.
I Have two tables, lets call them A and AHistory.
A has an ID and a value.
I want AHistory to keep track of the value and date for a set time.
AHistory Has an Auto Incremented ID, the value and a timestamp.
this is as far as I have gotten:
CREATE TRIGGER Atrigger
ON A
AFTER INSERT
AS
BEGIN
INSERT INTO AHistory
SELECT value FROM INSERTED
END
GO
Assuming that your db schema looks like
CREATE TABLE a
(id int identity primary key,
value varchar(32));
CREATE TABLE ahistory
(id int identity primary key,
aid int, value varchar(32),
eventdate datetime);
Your trigger might look like
CREATE TRIGGER atrigger ON A
AFTER INSERT AS
INSERT INTO ahistory (aid, value, eventdate)
SELECT id, value, GETDATE() FROM INSERTED;
Here is SQLFddle demo
Related
I'm trying to insert a bunch of values in a table but it doesn't have IDENTITY column, and I need to insert a unique value in that field.
And the sequential number should be start based on the previous value present in that same field.
lets say I have a table like this
create table testTable (id int, fieldA varchar (20))
insert into testTable
values (6,'Nick'),(7,'Tom')
Now the next value I insert in ID field should take be 8 and next row should be 9 and so on...
And below is the sequence I created; and is not working
CREATE SEQUENCE testTable_seq
declare #maxy int = ((select max(ID) from testTable) + 1)
START WITH #maxy
INCREMENT BY 1
I expect the below insert should get the next value from the sequence I created or just tto get the next sequential number from previous ID field
insert into testTable
values (testTable_seq.next value,'Harry')
You can't do that, if you see the arguments in the docs CREATE SEQUENCE it already stated that the value of START WITH should be a constant value, same as INCREMENT BY, MINVALUE and MAXVALUE
START WITH constant
I don't understand why you want to create a SEQUENCE to insert values into a table, and also MAX() won't do as you expect, instead you can simply
CREATE TABLE TestTable(
ID INT IDENTITY(1, 1) NOT NULL,
AColumn VARCHAR(20),
CONSTRAINT PK_TestTable_ID PRIMARY KEY(ID)
);
I have seen some articles mention the possibility of a Trigger on a View, triggering on either insert, updates or deletes to one of the base tables from which the View is created.
However I am not able to get a simple example to work.
CREATE TABLE [Test].[Data] (
Id INT PRIMARY KEY IDENTITY (1,1),
Data VARCHAR(255) NOT NULL,
);
GO
CREATE VIEW [Test].[View] AS SELECT * FROM [Test].[Data];
GO
CREATE TABLE [Test].[Queue] (
Id INT PRIMARY KEY IDENTITY (1,1),
DataId INT NOT NULL,
Action VARCHAR(255) NOT NULL,
Timestamp DATETIME NOT NULL,
);
GO
CREATE TRIGGER InsertTrigger ON [Test].[View] INSTEAD OF INSERT AS
BEGIN
DECLARE #DataId INT;
DECLARE #Timestamp DATETIME;
SET #DataId = (SELECT Id FROM INSERTED);
SET #Timestamp = GETDATE();
INSERT INTO [Test].[Queue] (DataId, Action, Timestamp) VALUES (#DataId, 'Insert', #Timestamp)
END
GO
ENABLE TRIGGER InsertTrigger ON [Test].[View];
GO
INSERT INTO [Test].[Data] (Data) VALUES ('Testdata');
The trigger is not firing, is the above not possible or is there something wrong with my Sql?
Edit: Although answered I would like to clarify the question. The idea was to get the trigger on the View to fire, when there was an Insert to the base table and not the View itself.
A trigger on a view will only work on inserts into that view, not on any inserts into tables to which the view references.
In your script you're not inserting into that view, you're inserting into a table.
In addition to not testing this correctly, your view is wrong. You are not considering that inserted represents multiple rows, not one.
So:
CREATE TRIGGER InsertTrigger ON [Test].[View] INSTEAD OF INSERT AS
BEGIN
INSERT INTO [Test].[Queue] (DataId, Action, Timestamp)
SELECT i.Id, 'Insert', GETDATE()
FROM Inserted;
END;
GO
INSERT INTO [Test].[View] (Data)
VALUES ('Testdata');
I have two tables:
Rooms:
ID (auto-incrementing primary key, int)
Topic (varchar(50))
MangerId (varchar(50))
Rooms_Users:
UserId (varchar(50))
RoomId (varchar(50))
both fields together are the primary key
I want to insert a room but I also must insert the manger to the table rooms_users.
Here is what I have so far:
ALTER PROCEDURE [dbo].[Creat_Room] #MangerId varchar(50) ,#Topic varchar(50)
AS
BEGIN
SET NOCOUNT
insert into Rooms(ManagerId,Topic) values(#MangerId,#Topic)
insert into Rooms_Users(UserId,RoomId) values(#MangerId,?????????????)
END
The ????????????? is the problem: I don't know what to put here i want to put the roomid i insert above.
You can use the output clause. Look at MSDN here: OUTPUT Clause (Transact-SQL)
Example:
declare #tbl table
(
NewID int
)
insert into Rooms(ManagerId,Topic)
output inserted.ID into #tbl
values(#MangerId,#Topic)
Then the table variable will contains the new id given to the row you inserted
Use the SCOPE_IDENTITY() function:
ALTER PROCEDURE [dbo].[Create_Room]
#ManagerId varchar(50),
#Topic varchar(50)
AS
BEGIN
DECLARE #NewRoomID INT
insert into Rooms(ManagerId, Topic) values(#MangerId, #Topic)
SELECT #NewRoomID = SCOPE_IDENTITY()
insert into Rooms_Users(UserId, RoomId) values(#ManagerId, #NewRoomID)
END
This function will return the last inserted IDENTITY value in this particular scope - the scope of your stored procedure.
I've created a insert stored procedure with two tables like in the exapmle:
Table NameAge
CREATE TABLE [dbo].[Assignment3_NameAge]
(
userID int PRIMARY KEY IDENTITY(1,1),
Name varchar(255) NOT NULL,
Age int NOT NULL
)
Table Hobbies
CREATE TABLE [dbo].[Assignment3_Hobbies]
(
hobbiesID int Identity(1,1) Primary Key,
userID int Foreign Key references Assignment3_NameAge(userID),
hobbies varchar(255) NOT NULL,
)
Insert Stored Procedure
CREATE PROCEDURE [dbo].p_Assignment3Join_ins
#Name nvarchar(100),
#Age int,
#Hobbies nvarchar(100)
AS
INSERT INTO [TABLE].[dbo].[Assignment3_NameAge]
([Name]
,[Age])
VALUES (#Name,#Age)
INSERT INTO [TABLE].[dbo].[Assignment3_Hobbies]
([Hobbies])
VALUES (#Hobbies)
The problem is that when i run the stored procedure the table Hobbies has a null value for userid(the foreign key)
What am i doing wrong?
You should provide the key of the Assignment3_NameAge value you want to insert into Assignment3_Hobbies.
If you want the last inserted you can use SCOPE_IDENTITY() from SQL Server(if you're using SQL Server) or equivalent. It will give you the last inserted value from Assignment3_NameAge
I am guessing this is SQL Server based on the IDENTITY column. Correct?
The first insert creates a user, but there is no user ID being set on the insert of the hobby. You need to capture the identity value from the first insert to be used in the second insert. Have you gon over the system functions available?
You're not supplying a value for it, SQL won't automagically fill the value in for you even though you've created a Foreign Key relationship. It's your job to populate the tables.
I have a primary key set up to auto increment.
I am doing multiple queries and I need to retrieve that primary key value to use as a foreign key in another table (IsIdentity = TRUE).
Is there any elegant way to get back the primary key value when I do an insert query? Right now I am requerying and getting the highest value in that column which seems really hacky.
Any suggestions?
If you are using SQL Server 2005 or later, you can use the OUTPUT clause.
create table T(
pk int identity primary key,
dat varchar(20)
);
go
insert into T
output inserted.pk
values ('new item');
go
drop table T;
The output can be directed to a table as well as to the client. For example:
create table T(
pk int identity primary key,
dat varchar(20)
);
create table U(
i int identity(1001,1) primary key,
T_pk int not null,
d datetime
);
go
insert into T
output inserted.pk, getdate()
into U(T_pk,d)
values ('new item'), ('newer item');
go
select * from T;
select * from U;
go
drop table T, U;
Beginning with SQL Server 2008, you can use "composable DML" for more possibilities.
insert into YourTable values (...)
get the new PK with scope_identity()
select scope_identity()
INSERT INTO YourTable (1, 2, etc.)
OUTPUT inserted.yourIDcolumn
VALUES (value1, value2, value...)
Note: This is for MS SQL 2005 and greater
SCOPE_IDENTITY() is probably what you want. It returns the ID of the last record inserted by the same code context in which it executes.
IDENT_CURRENT('tablename') is subject to concurrency issues. That is, there's no guarantee that another record won't be inserted between the INSERT and the call to IDENT_CURRENT.
I must confess, I'm not sure to what source of amazement the VillageIdiot's outburst refers, but I myself am quite astonished that this question does not appear to be a duplicate at all.
holy crap!!!
just call SCOPE_IDENTITY() function:
insert into your_talble(col1,col2) values('blah','more blah')
select scope_identity()
because selecting highest value will return error if any other statement make an insert. the function scope_identity() returns the identity created in current context (that is by your statement)
You should use scope_identity(). And I recommend to wrap insert statement and scope_identity() into transaction.