I want to get the value of the row causing the execution of the trigger. So I can pass it (as a parameter) to a stored procedure.
The stored procedure accepts as input a table type which is defined in the script below:
CREATE TYPE PersonTableType AS TABLE
(
Id int primary key,
FirstName nvarchar(50),
LastName nvarchar(50)
)
The procedure (insert in the ArchivePerson table the inserted row from the trigger)
Create PROCEDURE sp1
#PersonType PersonTableType Readonly
As
BEGIN
Insert Into ArchivePerson
Select * From #PersonType
END
How do I declare my trigger?
I tried something like:
Alter TRIGGER insertPerson
ON Person
AFTER Insert
AS
BEGIN
declare #PersonType PersonTableType;
??
Exec sp1 #PersonType
END
The inserted table has the rows which were, well, inserted. It has the same columns with your original [Person] table, so use the appropriate columns:
Alter TRIGGER insertPerson
ON Person
AFTER Insert
AS
BEGIN
declare #PersonType PersonTableType;
insert #PersonType(Id,FirstName,LastName)
select <corresponding columns>
from inserted
Exec sp1 #PersonType
END
Related
When I execute a record while entering a record as a procedure, it succeeds, but there is no record in the tables, what should I do?
ALTER proc [dbo].[Hastayikayıtedelim](
#Ad nvarchar(50),
#Soyadı nvarchar(100),
#TcKimlik nchar(11),
#DogumTarihi date,
#TelefonNo nvarchar(11)
)
AS
BEGIN
Insert Into Hastalar(Ad,Soyadı,TcKimlik,DogumTarihi,TelefonNo)
values (#Ad,#Soyadı,#TcKimlik,#DogumTarihi,#TelefonNo)
exec Hastayikayıtedelim 'EmSir','YilZmaz','43924717343','1996.20.05','05533326789'
END
I think all you need to do is the following command, after you have executed your alter statement, into your script :
COMMIT;
I have a stored procedure which inserts values into a table.
Let's say its name is usp_InsertTableA with parameters #ID int and Name varchar(100).
I have a requirement to call this stored procedure multiple times from another stored procedure. I am thinking to call this stored procedure something like below
exp usp_InsertTableA
select ID, Name from #tempTable
Is this possible in SQL Server to execute this with the value of the table and send it into a stored procedure?
You can use table type parameters to stored procedure.
CREATE TYPE [dbo].[udt_MyCustomTable] AS TABLE(
[id] [int] NOT NULL,
[name] [nvarchar](100) NOT NULL
)
GO
And then you stored procedure would be:
CREATE PROC [dbo].[usp_InsertTableA]
(
#myCustomTable udt_MyCustomTable READONLY
)
AS
BEGIN
-- Your code goes in here
END
Is this possible in SQL Server to execute this with the value of the table and send it into a stored procedure?
No, not with the stored procedure you have there. There are ugly hacks that could make it happen, but it's not how you're supposed to do things in T-SQL. Everything you do in SQL Server is supposed to be optimized to work on a set of rows, not a single row / row by row
In practice what this means is, if you have a query like this that produces 100 rows:
select ID, Name from #tempTable
You would pass those 100 rows to your insert procedure and insert them in one operation:
--expanding on sam's advice
--create a type
CREATE TYPE [dbo].[udt_MyCustomTable] AS TABLE(
[id] [int] NOT NULL,
[name] [nvarchar](100) NOT NULL
)
--your insert procedure
CREATE PROC [dbo].[usp_InsertTableA]
(
#myCustomTable udt_MyCustomTable READONLY
)
AS
BEGIN
INSERT INTO TableA(idcolumn, namecolumn)
SELECT is, name FROM #myCustomTable
END
Now in your main sp that wants to insert 100 rows:
#DECLARE tmpVar udt_MyCustomTable;
--put 100 rows into table variable
INSERT INTO tmpVar(id,name)
select ID, Name from #tempTable
--pass 100 rows in variable to SP to insert all at once
EXECUTE usp_InsertTableA tmpVar
DECLARE #ID INT, #Name VARCHAR(255)
SELECT #ID = ID, #Name=Name FROM #tempTable -- assumes one record in the table.
EXEC dbo.usp_insertdata #id, #Name
I try to use sys.dm_exec_describe_first_result_set with query containing table variable to describe columns of the query.
But declare of table variable in this query is causing activation of DATABASE trigger for event AFTER CREATE_TABLE, which contains a calling of stored procedure with temp table.
Usual declare of table variable this trigger don't activate. Some ideas why is the trigger activated for table variable?
CREATE PROCEDURE SP1 AS
BEGIN
CREATE TABLE #A(b int)
INSERT INTO #A(b) VALUES(1)
DROP TABLE #A
END
GO
CREATE TRIGGER [CreateObjectDatabaseTrigger]
ON DATABASE
AFTER
CREATE_TABLE
AS
BEGIN
EXEC SP1
END
GO
ENABLE TRIGGER [CreateObjectDatabaseTrigger] ON DATABASE
DECLARE #SqlQuery NVARCHAR(MAX) = N'DECLARE #A TABLE (b int) SELECT * FROM #A'
SELECT error_message, name
FROM
sys.dm_exec_describe_first_result_set
(#SqlQuery, NULL, 0)
Result with enabled trigger: The metadata could not be determined because statement 'INSERT INTO #A(b) VALUES(1)' in procedure 'SP1' uses a temp table.
Triggers should not return result sets to the client. Doing so is deprecated behavior and will be removed from a future version of SQL Server per the documentation.
In this case, use PRINT to return the informational message instead of a result set. The side-effect of this practice is that sys.dm_exec_describe_first_result_set will return the desired meta-data:
CREATE TRIGGER [CreateObjectDatabaseTrigger]
ON DATABASE
AFTER
CREATE_TABLE
AS
BEGIN
PRINT 'Trigger activated';
END
GO
ENABLE TRIGGER [CreateObjectDatabaseTrigger] ON DATABASE;
DECLARE #SqlQuery NVARCHAR(MAX) = N'DECLARE #A TABLE (b int) SELECT * FROM #A';
SELECT error_message, name
FROM sys.dm_exec_describe_first_result_set
(#SqlQuery, NULL, 0);
I am trying to set up a stored proc that will have three variables
FK_List
String_of_Info
CreateId
I need to insert into the table one entry per foreign key from the FK_List. I was curious what the best way to structure the stored procedure to do this efficiently.
EDIT: Code snippet added
CREATE PROCEDURE StackOverFlowExample_BulkAdd
#FKList VARCHAR(MAX),
#Notes NVARCHAR(1000),
#CreateId VARCHAR(50)
AS
BEGIN
INSERT INTO [dbo].[StackOverflowTable] WITH (ROWLOCK)
([FKID], [Notes], [CreateId], [UpdateId])
VALUES (#FKList, <---- this is the problem spot
#Notes, #CreateId, #CreateId)
END
GO
Based off your comments, you simply need a slight edit
CREATE PROCEDURE StackOverFlowExample_BulkAdd
#Notes nvarchar(1000),
#CreateId varchar(50)
AS
BEGIN
INSERT INTO [dbo].[StackOverflowTable] WITH (ROWLOCK)
([FKID]
,[Notes]
,[CreateId]
,[UpdateId])
select
someID
,#Notes
,#CreateId
,#CreateId
from FKListTable
END
GO
Here is a simple demo
This will insert a row into your table for each FK reference in the reference table with the parameters you pass in. That's all there is to it!
Here's another demo that may be more clear as I use a GUID for the primary key on the secondary table.
SECOND EDIT
Based off your comments, you will need a string splitter. I have added a common one which was created by Jeff Moden. See the example here
The final proc, after you create the function, will be like below. You need to change the comma in the function to what ever the delimiter is for your application. Also, you should start using table valued parameters.
CREATE PROCEDURE StackOverFlowExample_BulkAdd
#FKList VARCHAR(MAX),
#Notes nvarchar(1000),
#CreateId varchar(50)
AS
BEGIN
INSERT INTO [dbo].[StackOverflowTable] WITH (ROWLOCK)
([FKID]
,[Notes]
,[CreateId]
,[UpdateId])
select item
,#Notes
,#CreateId
,#CreateId
from dbo.DelimitedSplit8K(#FKList,',')
END
And you can call it like so:
declare #FKList varchar(1000) = '1,2,3,4,5,6'
declare #Notes varchar(1000) = 'here is my note'
declare #CreatedId int = 1
exec StackOverFlowExample_BulkAdd #FKList, #Notes, #CreatedId
I just want a SIMPLE sql server trigger (after insert) to get the ID back from the table that was inserted into... So algorithm:
new record is inserted into table
trigger is called
trigger takes id from inserted record and called stored procedure
My failed attempt is below:
CREATE TRIGGER [dbo].[insertNewMarket]
ON [dbo].[markets]
AFTER insert
AS
BEGIN
declare #marketID int
SET NOCOUNT ON;
--SELECT ID from inserted
--set #marketID = Inserted.ID--get the inserted id and pass to stored proc
exec marketInsert #marketID
END
GO
In trigger, you can access an table with the name "INSERTED", which will have the newly inserted record details. small example below
CREATE TRIGGER [dbo].[insertNewMarket]
ON [dbo].[markets]
AFTER insert
AS
BEGIN
declare #marketID int
SET NOCOUNT ON;
SELECT #marketID = ID from inserted
exec marketInsert #marketID
END
GO