How to make trigger react on specific SP only - sql

create procedure UpdateIte(#iID int,#qtt int)
as begin
insert into updateItem
values(#iID,#qtt,getdate())
end
and
create procedure releseItem(#eid int,#qty int,#itemId int)
AS BEGIN
declare #no int,#qt int
select #no=qty
from Stock
where itemID=#itemID
if(#no>#qty)
BEGIN
update Stock
set qty=qty-#qty
where itemID=#itemID
select #qt=qty
from Stock
where itemID=#itemID
insert into release
values(#eid,#itemId,#qty,getdate())
if(#qt<=10)
BEGIN
print'Item needs to replace'
END
else
print'Success'
END
else
BEGIN
print'Not Enough items in stock'
END
END
i want to create trigger, when release items that update the release table with employee id. when i create trigger it trigger with both procedures. But i want it to trigger with releaseItem. How do i do that?
create trigger CheckQty
ON Stock
for Update
as begin
declare #qty int, #emp int, #q int,#ItemId int
select #qty= qty, #emp=eid, #ItemId=ItemId
from inserted
select #q=qty
from Stock
where ItemId=#ItemId
if(#qty>0)
begin
insert into releseItem
values (#eid,#ItemId,#qty)
end
else
rollback transaction
end

You can just exececute store procedure in trigger as below.
create trigger CheckQty ON Stock for Update as begin declare #qty int, #emp int, #q int,#ItemId int
select #qty= qty, #emp=eid, #ItemId=ItemId
from inserted
select #q=qty
from Stock
where ItemId=#ItemId
if(#qty>0)
begin
exec releseItem #eid, #ItemId, #qty
end
else
rollback transaction
end

Related

Trigger to block insert into SQL Server

I have a requirement to prevent insert into table using after insert based on certain condition. When I am calling insert statement directly, it is executing perfectly without any problem. Whereas when am using procedure for insert statement with transaction scope, I am getting this error
The ROLLBACK TRANSACTION request has no corresponding BEGIN TRANSACTION.
My code:
create table test
(
id int ,
name varchar(10)
)
create table test1
(
id int ,
name varchar(10)
)
ALTER PROCEDURE test_insert
#id INT, #name NVARCHAR(10)
AS
BEGIN
BEGIN TRY
BEGIN TRANSACTION
INSERT INTO test1 (id, name)
VALUES (#id, #name)
INSERT INTO test (id, name)
VALUES (#id, #name)
COMMIT
END TRY
BEGIN CATCH
ROLLBACK;
DECLARE #errormsg NVARCHAR(MAX)
SELECT #errormsg = ERROR_MESSAGE();
THROW 500001, #errormsg, 1;
END CATCH
end
ALTER TRIGGER TRG_test
ON dbo.test
AFTER INSERT AS
BEGIN
DECLARE #idNum INT
SELECT #idNum = id FROM inserted
IF #idNum = 1
BEGIN
RAISERROR('error', 1,1);
ROLLBACK TRANSACTION
RETURN
END
END
Please let me know if am missing anything
Remove the ROLLBACK TRANSACTION inside the Trigger, remember that DML statements within the trigger will use the transaction context of the statement that fired the trigger, in this case, it would be covered by:
Your SP ==>
BEGIN TRANSACTION
--Fired the trigger and is involved by the same Transaction from the SP
insert into test1 (id,name) values(#id,#name)
insert into test (id,name) values(#id,#name)
COMMIT
Remove the ROLLBACK from the trigger and raise and error with severity 11 or higher so that the stored procedure CATCH block is entered. The code below also uses the simplified version of THROW to reraise the trigger error instead of throwing a new one and uses EXISTS to handle multi-row inserts.
alter proc test_insert #id int, #name nvarchar(10)
as
begin
BEGIN TRY
BEGIN TRANSACTION
insert into test1 (id,name) values(#id,#name)
insert into test (id,name) values(#id,#name)
COMMIT
END TRY
BEGIN CATCH
IF ##TRANCOUNT > 0 ROLLBACK;
THROW;
END CATCH
end
GO
alter TRIGGER TRG_test
ON dbo.test
AFTER INSERT AS
BEGIN
if EXISTS(select 1 from inserted WHERE id = 1)
begin
RAISERROR('error', 16,1);
RETURN
end
END
GO
From my understanding,
alter TRIGGER TRG_test
ON dbo.test
instead of insert as --- Trigger type is changed. Trigged before insert
BEGIN
declare #idNum int
select #idNum = id from inserted
if #idNum <> 1 ------ Condition is changed
begin
/* Do what you want.*/
RETURN
end
END
update 1:
create table test(
id int ,
name varchar(10)
)
create table test11(
id int ,
name varchar(10)
)
alter proc test_insert #id int, #name nvarchar(10)
as
begin
BEGIN TRY
BEGIN TRANSACTION
insert into test11(id,name) values(#id,#name)
insert into test (id,name) values(#id,#name)
COMMIT
END TRY
BEGIN CATCH
ROLLBACK;
declare #errormsg nvarchar(max)
select #errormsg=ERROR_MESSAGE();
THROW 500001, #errormsg, 1;
END CATCH
end
alter TRIGGER TRG_test
ON dbo.test
instead of insert as --- Trigger type is changed. Trigged before insert
BEGIN
declare #idNum int, #name int
select #idNum = id, #name=name from inserted
if #idNum <> 1 ------ Condition is changed
begin
insert into test (id,name) values(#idNum,#name)
end
else begin
print 'You insert invalid value 1'
end
END
test_insert 1, 2 -- error will be arised.
select * from test
select * from test11
test_insert 2, 2 -- insertion is occurs.
select * from test
select * from test11

SQL transaction/ErrorHandling/TryandCatch

Taking a SQL programming(2012 version) class and totally stuck, program wont work no matter how many times I try. The requirements (Questions) as well as what I have so far are below. Below the dashed line is another proc I wrote for error handling. Please help me finish this...please!
/*Create a Stored Procedure that accepts StockName, NewOpenPrice, NewClosePrice.
a. If the Stock Name does not EXIST a new record should be added into the dbo.Stocks table
b. If the Stock Name does EXIST, the OpenPrice an ClosePrice will be updated with the newly inserted Prices.
c. Insert and Update statements should be built using a transaction (Repeatable Read Isolation Level)
d. A Try Catch Statement should be used for the Update and Insert statements. If there is an error, the dbo.error_handler Stored Procedure should be called.
*/
CREATE PROCEDURE spc_Stocks
#Name varchar(25), #NewOpenPrice money, #NewClosePrice money
as
BEGIN
CREATE TABLE dbo.Stocks (
StockID int IDENTITY(1,1),
StockName varchar(50),
OpenPrice money,
ClosePrice money )
INSERT INTO dbo.Stocks
SELECT 'Walmart',21.58,22.98 UNION
SELECT 'Target',17.32,15.23 UNION
SELECT 'Taco Bell',4.58,12.98 UNION
SELECT 'Microsoft',7.15,8.15 UNION
SELECT 'Apple',10.79,9.89
Select StockName from stocks
where StockName = #Name
------Name does NOT exist
if (#Name = NULL)
Begin
Insert into dbo.Stocks (StockName)
Values (#Name)
END
----If name DOES exist
ELSE
BEGIN
Begin TRY
Begin SET TRANSACTION ISOLATION LEVEL REPEATABLE READ
UPDATE dbo.Stocks SET OpenPrice =#NewOpenPrice, ClosePrice= #NewClosePrice where StockName = #Name
Commit transaction
END TRY
BEGIN CATCH
?!?!?!?!?!?
*This is my ErrorHandler stored proc query
ALTER PROCEDURE dbo.error_handler
as
BEGIN
DECLARE #errnum INT,
#severity INT,
#errstate INT,
#proc NVARCHAR(126),
#line INT,
#message NVARCHAR(4000)
-- capture the error information that caused the CATCH block to be invoked
SELECT #errnum = ERROR_NUMBER(),
#severity = ERROR_SEVERITY(),
#errstate = ERROR_STATE(),
#proc = ERROR_PROCEDURE(),
#line = ERROR_LINE(),
#message = ERROR_MESSAGE()
end
Create PROCEDURE [dbo].[USP_Stocks]
(#Name varchar(25), #OpenPrice MONEY, #ClosePrice MONEY)
AS
BEGIN
-----Name does NOT exist
IF NOT EXISTS (SELECT StockName FROM [dbo].[Stocks]
WHERE StockName = #Name)
BEGIN
BEGIN TRY
SET TRANSACTION ISOLATION LEVEL REPEATABLE READ
BEGIN TRAN
INSERT INTO dbo.Stocks (StockName, OpenPrice, ClosePrice)
VALUES (#Name ,#OpenPrice, #ClosePrice)
COMMIT TRANSACTION
END TRY
BEGIN CATCH
EXEC dbo.error_handler
ROLLBACK
END CATCH
END
----If name DOES exist
ELSE
BEGIN
BEGIN TRY
SET TRANSACTION ISOLATION LEVEL REPEATABLE READ
BEGIN TRAN
UPDATE dbo.Stocks SET OpenPrice =#OpenPrice, ClosePrice= #ClosePrice
where StockName = #Name
Commit transaction
END TRY
BEGIN CATCH
ROLLBACK TRUANSACTION
EXEC dbo.error_handler
END CATCH
END
END

i want to decrease the quantity field and decrease its number

CREATE PROCEDURE dbo.IssueBook
(
#bookid nvarchar(50),
#ano nvarchar(50),
#mid int,
#librarian varchar(10),
#quantity int
)
AS
declare #cnt int
declare #msg varchar(100)
if not exists( select * from books where bookid = #bookid and quantity = #quantity)
begin
raiserror('Book is not available',16,1);
return;
end;
select #cnt = count(bookid) from issues where mid = #mid;
if ( #cnt >= 2 )
begin
raiserror('Maximum Limit Has Been Reached For Member!',16,1);
return;
end;
begin tran
begin try
update books set quantity =#quantity-1 where bookid= #bookid;
insert into issues values (#bookid, #mid, getdate(), #librarian, #ano);
commit tran
end try
begin catch
rollback tran
/* select #msg = error_message() */
raiserror( 'Unknown Error', 16,1);
end catch
i want to change value of quantity field in sql table how can i do that please help me i tried many things but they are not working i will be very thankful to you...
I think the problem is in this part: set quantity =#quantity-1. If I understand you correctly, it should either be
set quantity = quantity-1 -- Decreease the book quantity by 1
or
set quantity = quantity - #quantity -- Decreease the book quantity by #quantity

Sql Stored Procedure to insert and update

I am new to Stored Procedures and SQL. Looking in to various articles, I found how to insert an record using stored procedure and it works.
CREATE PROCEDURE [dbo].[stprOrder]
#OrderDate date,
#OrderID nchar(50),
#ShipToID nchar(50),
#TotalAmt decimal(18,2),
AS
BEGIN
SET NOCOUNT ON;
INSERT INTO ORDER(OrderDate,OrderID,ShipToID,TotalAmt)
Values(#OrderDate,#OrderID,#ShipToID,#TotalAmt)
END
I am not sure how to update an record using the same stprOrder stored procedure. Like the stored procedure should do inserting and updating depending on the OrderID.
Most likely you're looking for something like this
CREATE PROCEDURE [dbo].[stprOrder]
#OrderDate date,
#OrderID nchar(50),
#ShipToID nchar(50),
#TotalAmt decimal(18,2),
AS
BEGIN
SET NOCOUNT ON;
IF (SELECT TOP (1) 1 FROM ORDER WHERE OrderID = #OrderID) IS NULL
INSERT INTO ORDER(OrderDate,OrderID,ShipToID,TotalAmt)
Values(#OrderDate,#OrderID,#ShipToID,#TotalAmt)
ELSE
UPDATE ORDER SET OrderDate = #OrderDate, ShipToID = #ShipToID, TotalAmt = #TotalAmt
WHERE OrderID = #OrderID
END
First it checks if order with given ID already exists - if it doesn't - a new entry is created, otherwise existing record is updated
CREATE PROCEDURE [dbo].[stprOrder]
#OrderDate date,
#OrderID nchar(50),
#ShipToID nchar(50),
#TotalAmt decimal(18,2),
AS
BEGIN
SET NOCOUNT ON;
IF EXISTS (SELECT null FROM ORDER WHERE id = #orderID)
BEGIN
UPDATE ORDER SET ..... WHERE id = #orderID
END
ELSE
BEGIN
INSERT INTO ORDER(OrderDate,OrderID,ShipToID,TotalAmt)
VALUES(#OrderDate,#OrderID,#ShipToID,#TotalAmt)
END

Stored Procedure OutPut Parameters

i need to write a stored procedure which will return a string.logic is
when user try to insert a new record i need to check whether that record already exist.if exist need to return msg "Record exist" else return "Inserted"
following is what i have done for the moment and i'm stuck here.can some one help me to complete the procedure
CREATE PROCEDURE [dbo].[spInsetPurpose]
#Purpose VARCHAR(500),
#Type VARCHAR(6),
#Result VARCHAR(10)= NULL OUTPUT
AS
BEGIN
Declare #Position VARCHAR(20)
DECLARE #TempTable TABLE (Purpose VARCHAR(500))
INSERT INTO #TempTable
SELECT Purpose FROM tblPurpose WHERE Purpose=#Purpose
INSERT INTO tblPurpose(Purpose,[Type]) VALUES(#Purpose,#Type)
END
To check if the row already exists you can do
If Exists (Select Top 1 1 from tblPurpose where Purpose = #Purpose and [Type] = #Type)
Begin
Insert Into tblPurpose
(Purpose, [Type])
Select
#Purpose, #Type
SET #Result = 'Inserted'
End
Else
Begin
SET #Result = 'Record exists'
End