SQL Server trigger is not firing on insert? - sql-server

For some reason this trigger does not fire.
The trigger is active and data is being inserted to p2 every 20 seconds. I have also tried try catch blocks and there is no exception.
ALTER TRIGGER [dbo].[load_to_p_2]
ON [dbo].[p2]
AFTER INSERT
AS
BEGIN
SET NOCOUNT ON;
INSERT INTO [Log].[dbo].[Log] ([type], [message], [created_at])
VALUES ('trigger load_to_p_2', '----', GETUTCDATE());
END
And this is the code that inserts the data into p2:
ALTER PROCEDURE [dbo].[LoadTop2]
AS
SET NOCOUNT ON
DECLARE #r INT;
SET #r = 1;
WHILE #r > 0
BEGIN
BEGIN TRANSACTION;
DELETE TOP (1000)
FROM pa3_log
OUTPUT deleted.id, deleted.browser INTO p2 (id, browser)
SET #r = ##ROWCOUNT;
COMMIT TRANSACTION;
END

Related

Parallel insert stored procedure fails in SQL SERVER

The below SP fails when running parallely in multiple threads.
Tried to use different isolation levels in the SP, but still i face the same error.
Violation of UNIQUE KEY constraint
'AK_MerchantTransactionEnd_MerchantReferenceCode_BankReferenceCode'.
Cannot insert duplicate key in object 'dbo.EpayTransaction'. The
duplicate key value is (20160503171525689435, 20160329221725169, 0).
Table has UNIQUE Constraint for MerchantReferenceCode_BankReferenceCode
CREATE PROCEDURE [dbo].[uspUpdateEpayConfirmation]
#merchantReferenceCode VARCHAR(30) ,
#bankGatewayCode VARCHAR(30) ,
#transactionNumber VARCHAR(100)
AS
BEGIN
SET NOCOUNT ON;
SET XACT_ABORT ON;
BEGIN TRY
DECLARE #timestamp DATETIME;
SET #timestamp = GETDATE();
IF EXISTS ( SELECT 1
FROM [dbo].EpayTransaction WITH (NOLOCK)
WHERE [dbo].EpayTransaction.[MerchantReferenceCode] = #merchantReferenceCode
)
BEGIN
RETURN 0;
END;
SET TRANSACTION ISOLATION LEVEL REPEATABLE READ;
BEGIN TRANSACTION;
-- update the epayment transaction information with the merchent reference code
-- updating the status of the transaction
UPDATE [dbo].[CustomerTransaction]
SET [dbo].[CustomerTransaction].[ModifiedBy] = 1 ,
[dbo].[CustomerTransaction].[ModifiedOn] = #timestamp
WHERE [dbo].[CustomerTransaction].[MerchantReferenceCode] = #merchantReferenceCode;
-- adding a record to EpayTransaction table to conclude the transaction is successful
INSERT INTO [dbo].EpayTransaction
( [dbo].EpayTransaction.[BankReferenceCode] ,
[dbo].EpayTransaction.[BankTransactionDate] ,
[dbo].EpayTransaction.[MerchantReferenceCode]
)
VALUES ( #bankGatewayCode ,
#timestamp ,
#merchantReferenceCode
);
COMMIT TRANSACTION;
RETURN 1;
END TRY
BEGIN CATCH
IF ##TRANCOUNT > 0
ROLLBACK TRANSACTION;
-- Raise an error with the details of the exception
DECLARE #errMsg NVARCHAR(4000) ,
#errSeverity INT;
SELECT #errMsg = ERROR_MESSAGE() ,
#errSeverity = ERROR_SEVERITY();
RAISERROR(#errMsg, #errSeverity, 1);
END CATCH;
END;

Getting rows affected in stored procedure INSERT statement with NOCOUNT OFF

I have a stored procedure in SQL Server 2014 where I first delete data from a table and execute another stored procedure as shown below. I don't care about rows affected on this code so I use SET NOCOUNT ON. I then perform an Insert statement first setting SET NOCOUNT OFF. I would expect the stored procedure to return the rows affected automatically from the INSERT but that has not proven to be the case. I searched SO and found the ##ROWCOUNT and that is working. However, is that really required? Why wouldn't the INSERT statement in the code below return the records affected?
ALTER PROCEDURE [dbo].[SaveTextSetting]
#UserId INT ,
#SettingType INT = 0 ,
#SettingValue NVARCHAR(MAX)
AS
BEGIN
BEGIN
SET NOCOUNT ON;
DELETE FROM Settings
WHERE UserId = #UserId
AND SettingType = #SettingType;
EXEC dbo.PurgeExpiredSettings;
END;
BEGIN
SET NOCOUNT OFF;
INSERT INTO dbo.Settings
( UserId ,
SettingsText ,
SettingType
)
VALUES ( #UserId ,
#SettingValue ,
#SettingType
);
RETURN ##ROWCOUNT; --without this we don't get the rows affected
END;
END;
Are you sure?
CREATE PROCEDURE spTest AS RETURN
GO
ALTER PROCEDURE spTest
AS
BEGIN
SET NOCOUNT OFF
DECLARE #rt int
CREATE TABLE #t (
v int NOT NULL
)
INSERT INTO #t (v)
SELECT v FROM (VALUES (1), (1), (2)) AS t (v)
SET #rt = ##ROWCOUNT
DROP TABLE #t
RETURN #rt
END
GO
DECLARE #rt int
EXEC #rt = spTest
SELECT #rt
GO
DROP PROCEDURE spTest
GO
I would use an output param something like.....
ALTER PROCEDURE [dbo].[SaveTextSetting]
#UserId INT ,
#SettingType INT = 0 ,
#SettingValue NVARCHAR(MAX),
#RowCount INT OUTPUT
AS
BEGIN
SET NOCOUNT ON;
DELETE FROM Settings
WHERE UserId = #UserId
AND SettingType = #SettingType;
EXEC dbo.PurgeExpiredSettings;
INSERT INTO dbo.Settings( UserId ,SettingsText ,SettingType)
VALUES ( #UserId ,#SettingValue ,#SettingType);
SET #RowCount= ##ROWCOUNT;
END

If else doesn't work in stored procedures

I have two stored procedures to select and insert values.When I choose an item from Listbox and click the add button, the code calls SP$select. Then a new Form appears and I give the data into the textbox. When I click save button, SP$insert works. But all the data can be only inserted into the first(Base) column. When I do all actions in SP$insert (select and insert) then it doesn't work. What's wrong with it?
Procedure 1 [SP$select]
use env
go
create proc [SP$select](
#p2 nvarchar(20),
#debug bit = 0)
as
begin
set nocount on
begin try
if #p2='User Name'
begin
SELECT user_name FROM env.dbo.Base
end
else if #p2='Serial Number'
begin
SELECT ser_num FROM env.dbo.Base
end
end try
begin catch
IF #debug = 1
throw;
end catch
end
set nocount off
go
Procedure 2 [SP$insert]
use env
go
create proc [SP$insert](
#p1 nvarchar(100),
#id int output,
#debug bit = 0)
as
begin
set nocount on
begin try
if exists(select user_name from env.dbo.Base)
begin
INSERT INTO envanter.dbo.Base(user_name) VALUES (#p1)
SELECT #id = ##IDENTITY
end
else if exists(select ser_num from env.dbo.Base)
begin
INSERT INTO env.dbo.Base(ser_num) VALUES (#p1)
SELECT #id = ##IDENTITY
end
end try
begin catch
if #debug = 1
throw;
end catch
set nocount off
end
go
try this code
use env
go
create proc [SP$insert](
#p1 nvarchar(100),
#id int output,
#debug bit = 0)
as
begin
set nocount on
begin try
if exists(select user_name from env.dbo.Base)
begin
INSERT INTO envanter.dbo.Base(user_name) VALUES (#p1)
SELECT #id = ##IDENTITY
end
if exists(select ser_num from env.dbo.Base)
begin
INSERT INTO env.dbo.Base(ser_num) VALUES (#p1)
SELECT #id = ##IDENTITY
end
end try
begin catch
if #debug = 1
throw;
end catch
set nocount off
end
go
Not sure what you are trying to do here. If there is at least one row on table Base the statement "if exists(select user_name from env.dbo.Base)" whill always be TRUE regardless of whether the user_name value is null or not, therefore the "else if" part will never happen.

Retrieving a particular value in SQL Server

I have this stored procedure that has a value:
BEGIN TRY
BEGIN TRANSACTION;
-- Insert statements for procedure here
DECLARE #return_value int
DECLARE #media_id uniqueidentifier
'INSERT SQL STATEMENT HERE
SELECT [media_id] FROM [media] WHERE 1 = 1
-- One row affected
RETURN 1
END TRY
BEGIN CATCH
IF ##TRANCOUNT > 0
BEGIN
ROLLBACK TRANSACTION;
END
-- Rollback, no row affected
RETURN 0
END CATCH;
I want to call the [media_id] value from another stored procedure. How do I get that value?
Table Definition
CREATE TABLE MY_EMPLOYEE
(EMPID INT, NAME VARCHAR(20),
LANGUAGEID INT , ID UNIQUEIDENTIFIER DEFAULT NEWID())
GO
Stored Procedure
ALTER PROCEDURE usp_ProcName
#Emp_ID INT = null,
#Name VARCHAR(20) = null,
#LanguageID int = null,
#NewID UNIQUEIDENTIFIER OUTPUT
AS
BEGIN
SET NOCOUNT ON;
BEGIN TRY
BEGIN TRANSACTION;
-- Insert statements for procedure here
INSERT INTO [Practice_DB].[dbo].[MY_EMPLOYEE](EMPID, NAME, LANGUAGEID)
VALUES (#Emp_ID, #Name, #LanguageID);
-- Populating the OUTPUT variable using the other variables that were passed
-- for INSERT statement.
SELECT #NewID = ID
FROM [Practice_DB].[dbo].[MY_EMPLOYEE]
WHERE EMPID = #Emp_ID
-- One row affected
COMMIT TRANSACTION
RETURN 1
END TRY
BEGIN CATCH
IF ##TRANCOUNT > 0
BEGIN
ROLLBACK TRANSACTION;
END
-- Rollback, no row affected
RETURN 0
END CATCH
END
GO
Calling Stored Procedure
DECLARE #value int, #ID VARCHAR(100)
EXECUTE #value = usp_ProcName
#Emp_ID = 50,
#Name = 'John',
#LanguageID = 50,
#NewID = #ID OUTPUT --<-- passing this variable with OUTPUT key word this will be
-- populated inside the Procedure and then you can SELECT it or
-- whatever you want to do with this value.
SELECT #ID
SELECT #value
This should help: Return Data from a Stored Procedure
I think this should work
BEGIN TRY
BEGIN TRANSACTION;
-- Insert statements for procedure here
DECLARE #return_value int
DECLARE #media_id uniqueidentifier
--get the value from the stored procedure here
Declare #SQL varchar(max)
set #SQL='INSERT SQL STATEMENT HERE
SELECT #media_id FROM [media] WHERE 1 = 1'
exec #SQL
-- One row affected
RETURN 1
END TRY

How to know TSQL Stored Procedure Update Executed

How can I check if my TSQL stored procedure updated within the stored procedure in order to create a proper message?
Example:
ALTER PROCEDURE [dbo].[pUpdate]
#id uniqueidentifier,
#status int,
#message VARCHAR(100) OUTPUT
AS
BEGIN
SET NOCOUNT ON;
UPDATE [database].[dbo].[user]
SET status = #status
WHERE Id = #id
END
IF (SUCCESSFUL)
BEGIN
#message = 'Success!'
END
What are some possible ways to check if successful without using the parameters again?
This is what I currently use:
SELECT COUNT(*)
WHERE status = #status AND id = #id
Are there any other ways? I want to know for my knowledge and reference. Thanks.
Have you checked out ##ROWCOUNT? Might be what you're looking for (see this for details: http://technet.microsoft.com/en-us/library/ms187316.aspx). Basically it returns the number of rows affected by the last statement. I'd imagine if it were not "successful", it would be zero rows.
ALTER PROCEDURE [dbo].[pUpdate]
#id uniqueidentifier,
#status int,
#message VARCHAR(100) OUTPUT
AS
BEGIN
SET NOCOUNT ON;
UPDATE [database].[dbo].[user]
SET status = #status
WHERE Id = #id
END
IF (##ROWCOUNT > 0)
BEGIN
#message = 'Success!'
END
ELSE
BEGIN
#message = 'Not success!'
END
You can use a try catch block and log the success or failure to a table.
BEGIN TRY
BEGIN TRANSACTION
-- Add Your Code Here
-- Log Success to a log table
COMMIT
END TRY
BEGIN CATCH
-- Log failure to a log table
ROLLBACK
END CATCH
I would use ##ERROR system variable to check whether the last sentence was successfull (error # = 0) or not (error # > 0 ):
USE Database;
GO
BEGIN
UPDATE TableName
SET ColumnA = 4
WHERE ColumnB = 1;
END
IF (##ERROR = 0)
BEGIN
PRINT N'Successfull Update';
GO
END
You can go deeper into Microsoft MSDN here: http://technet.microsoft.com/es-es/library/ms188790.aspx
ALTER PROCEDURE [dbo].[pUpdate]
#id uniqueidentifier,
#status int,
#message VARCHAR(100) OUTPUT
AS
BEGIN
SET NOCOUNT ON;
UPDATE [database].[dbo].[user]
SET status = #status
WHERE Id = #id
END
IF (##ROWCOUNT > 0)
BEGIN
SELECT #message = 'Success!'
END
ELSE
BEGIN
SELECT #message = 'Not success!'
END

Resources