Unable to insert into table with Identity Column - sql

I have this procedure:
create proc insertfactors_pf
(
#FactorID int,
#CustomersID int,
#Number int,
#TotalPrice decimal(18, 0),
#PaidPrice decimal(18, 0),
#Date Date,
#ProductID int,
#QTY int
)
AS
BEGIN TRANSACTION
SET IDENTITY_INSERT facetors on
INSERT INTO Factor VALUES (#FactorID, #CustomersID, #Number, #TotalPrice, #PaidPrice,#Date)
SET IDENTITY_INSERT factors off
IF ##ERROR <> 0
BEGIN
ROLLBACK
RETURN
END
SET IDENTITY_INSERT Product_Factor on
INSERT INTO Produc_Factor values(#FactorID,#ProductID,#QTY)
SET IDENTITY_INSERT Product_Factor off
IF ##ERROR <> 0
BEGIN
ROLLBACK
RETURN
END
COMMIT
But when I run it I get this error:
Msg 8101, Level 16, State 1, Procedure insertfactors_pf, Line 20 [Batch Start Line 0]
An explicit value for the identity column in table 'Factor' can only be specified when a column list is used and IDENTITY_INSERT is ON.
What am I doing wrong?

The error message seems pretty clear: FactorId is an identity column. You shouldn't set the value for FactorID yourself. Sql Server will set it for you. But if you really want to set it for some insane reason, you need to include a column list in the query like this:
SET IDENTITY_INSERT facetors on
INSERT INTO Factor
(FactorID, CustomerID, Number, TotalPrice, PaidPrice, Date)
VALUES
(#FactorID, #CustomersID, #Number, #TotalPrice, #PaidPrice,#Date)
SET IDENTITY_INSERT factors off
Even better, you should do something more like this, where you don't have to mess with identity insert issues:
create proc insertfactors_pf
(
#CustomersID int,
#Number int,
#TotalPrice decimal(18, 0),
#PaidPrice decimal(18, 0),
#Date Date,
#ProductID int,
#QTY int
)
AS
--Move this to inside the procedure definition. Don't ask for it as an argument
DECLARE #FactorID int
BEGIN TRANSACTION
--Don't mention FactorID anywhere here. Sql Server will take care of it
INSERT INTO Factor
(CustomersID, Number, TotalPrice, PaidPrice, Date)
VALUES
(#CustomersID, #Number, #TotalPrice, #PaidPrice,#Date);
IF ##ERROR <> 0
BEGIN
ROLLBACK
RETURN
END
--use scope_idenity() to get the FactorID value Sql Server just created
SELECT #FactorID = scope_identity();
INSERT INTO Produc_Factor
(FactorID, ProductID, Qty)
VALUES
(#FactorID,#ProductID,#QTY)
IF ##ERROR <> 0
BEGIN
ROLLBACK
RETURN
END
COMMIT

Related

Insert into table within function

I would like to insert the #OBV's value into a table inside the function. What is the correct way to achieve it?
alter function CalculateOnBalanceVolume (
#operation varchar(3),
#volume money
)
returns char(4) as
begin
declare #prevOBV as money,
#OBV as money
set #prevOBV = (
select top 1 OnBalanceVolume
from OnBalanceVolume
order by EventTime desc
)
if (#operation = 'add') set #OBV = #prevOBV + #volume
if (#operation = 'sub') set #OBV = #prevOBV - #volume
insert into OBVTable values (#OBV) // error
return #OBV
end;
Functions cannot perform any actions known as side-effecting which includes inserting or updating or deleting from tables, so you cannot use a Function for this.
To use a stored procedure you might have:
create procedure CalculateOnBalanceVolume
#operation varchar(3),
#volume decimal(9,2),
#OBV decimal(9,2) output
as
select top (1) #Obv=OnBalanceVolume +
case when #Operation='add' then #volume else -#volume end
from OnBalanceVolume
order by EventTime desc
insert into OBVTable values (#OBV)
go
And then to invoke the procedure and get your output value you would do for example:
declare #OBV decimal(9,2)
exec CalculateOnBalanceVolume 'add', 100, #OBV output
select #OBV as OutputValue

THROW ERROR Still Executes Query And Inserts Data Into Table

Basically, I am trying to compare a date the user will enter and if it is greater than todays date (GETDATE()), then it throws the error and doesn't enter the data. The query throws the error but it still enters the data with the result at the bottom.
USE EMR
GO
IF EXISTS (SELECT DB_ID('CheckDate'))
DROP TRIGGER CheckDate
GO
CREATE TRIGGER CheckDate
ON VISIT
AFTER INSERT, UPDATE
AS
BEGIN TRAN
DECLARE #ErrorMessage VARCHAR(200)
DECLARE #Date VARCHAR(20) = CAST ((SELECT CONVERT (DATE, GETDATE())) AS VARCHAR(20))
SET #ErrorMessage = 'Date Must Be On Or Before ' + #Date + '';
DECLARE #CheckDate DATE = (SELECT Date_Of_Service FROM inserted);
IF CAST((#CheckDate) AS DATE) <= CAST(GETDATE() AS DATE)
COMMIT TRAN
ELSE
RAISERROR(#ErrorMessage, 1, 1)
This is my insert statement:
INSERT INTO VISIT (PK_VISIT_ID, Date_Of_Service)
VALUES (02913, '2018-12-03')
And get this:
Date Must Be On Or Before 2016-02-17
Msg 50000, Level 1, State 1
(1 row(s) affected)
You are raising error with severity = 1 which means to server that it's just info message.Check out replies to this post: TSQL: Prevent trigger suppressing error but rolling back transactionThere is also a link to severity table on msdn.
Your code is giving doing insert even after raiserror because trigger for insert runs the trigger after the rows are inserted.You can use check constraint or instead of insert as follows:
alter trigger tr2 on bb
instead of insert
as
begin
begin try
begin transaction
if exists(select * from inserted where date1 > getdate())
begin
raiserror('date greater then today''s date',16,1)
end
else
begin
insert into bb
select * from inserted
if ##trancount > 0
commit transaction
end
end try
begin catch
declare #msg varchar(100) = error_message()
if ##trancount > 0
begin
raiserror(#msg,16,1)
rollback transaction
end
end catch
end

IN statement error in SQL triggers

I have a trigger that insert value to a another table based on a condition,
in my condition thare is an IN statement within IF condition when im trying to insert multiple values using "INSERT INTO SELECT FROM"
it returns following error
"Subquery returned more than 1 value. This is not permitted when..."
here is my code
ALTER TRIGGER [dbo].[WentOut] ON [dbo].[TB_EVENT_LOG]
AFTER INSERT
AS
BEGIN
DECLARE #AID int
SET NOCOUNT ON;
IF ((SELECT nTNAEvent from inserted) IN(1,2,3))
BEGIN
INSERT INTO Cen.WentOutLog (AutoID, nUserID, nOutDateTime,nOutTNAEvent ,nReaderID) select nEventLogIdn,nUserID, nDateTime,nTNAEvent, nReaderIdn from inserted
END
END
it works for single value but not for multiple value inserting "INSERT INTO SELECT FROM"
thanks in advance
As mentioned by Mitch trigger doesn't fire for each row. If am not wrong this is what you need.
ALTER TRIGGER [dbo].[WentOut]
ON [dbo].[TB_EVENT_LOG]
AFTER INSERT
AS
BEGIN
DECLARE #AID INT
SET NOCOUNT ON;
IF EXISTS(SELECT nTNAEvent
FROM inserted
WHERE nTNAEvent IN ( 1, 2, 3 ))
BEGIN
INSERT INTO Cen.WentOutLog
(AutoID,nUserID,nOutDateTime,nOutTNAEvent,
nReaderID)
SELECT nEventLogIdn,nUserID,nDateTime,nTNAEvent,
nReaderIdn
FROM inserted
WHERE nTNAEvent IN ( 1, 2, 3 )
END
IF EXISTS(SELECT nTNAEvent
FROM inserted
WHERE nTNAEvent IN ( 0 ))
BEGIN
--statement
END
END

Not able to access Table Valued Parameter for queries in sql

I have two queries in the single stored procedure.
I have one table table valued parameter & that TVP I am using for both the queries.
One of my query is working fine (Update Query is working fine) but If I am using that same TVP for the insert query then it is not inserting the values to it.
I dont know what is happening & also error is also not coming.
Here's my query :
CREATE TYPE Mapping_n_Info_Master_Type AS TABLE
(
quantity INT,
product_id INT,
sell_order_no VARCHAR(20),
selling_product_id VARCHAR(20),
tax_id INT
);
GO
CREATE PROC spInsert_Rs_Sell_Order_Master
(
#tvp_Mapping_n_Info_Master Mapping_n_Info_Master_Type READONLY
)
AS
BEGIN
SET NOCOUNT ON
BEGIN TRY
BEGIN TRANSACTION
--Start This Part is not Working
INSERT INTO
RS_Sells_Invoice_Info_Master
SELECT
sell_order_no,product_id,selling_product_id,tax_id,qty
FROM
#tvp_Mapping_n_Info_Master
--End This Part is not Working
--Insert Logic For Sell Order Mapping
UPDATE
RS_Sell_Order_Mapping
SET
quantity = TVP.quantity
FROM
#tvp_Mapping_n_Info_Master tvp
INNER JOIN RS_Sell_Order_Mapping AS SOM ON
TVP.product_id = SOM.product_id AND TVP.sell_order_no = SOM.sell_order_no
WHERE
SOM.product_id = TVP.product_id
AND
SOM.sell_order_no = TVP.sell_order_no
COMMIT TRANSACTION
END TRY
BEGIN CATCH
DECLARE #ERROR_MSG NVARCHAR(MAX), #SEVERITY INT, #STATE INT
SELECT #SEVERITY = ERROR_SEVERITY(), #STATE = ERROR_STATE()
,#ERROR_MSG = ERROR_MESSAGE() + ' err src line: ' + CAST( ERROR_LINE() AS NVARCHAR(20)) + ' ' + ISNULL(ERROR_PROCEDURE(), '');
--#ERROR_MSG = ERROR_MESSAGE()
ROLLBACK;
-- RE-THROW EXCEPTION FOR DIAGNOSTIC VISIBILITY
RAISERROR (#ERROR_MSG ,#SEVERITY, #STATE);
RETURN
END CATCH
END
My Table looks like this
Do I want to change the sequence of parameter that I have supplied to the insert query.
Please give your suggestions to this
Write as:
INSERT INTO
RS_Sells_Invoice_Info_Master (sell_order_no,
product_id,
selling_product_id,
tax_id,
qty)
SELECT MIM.sell_order_no,
MIM.product_id,
MIM.selling_product_id,
MIM.tax_id,
MIM.quantity
FROM
#tvp_Mapping_n_Info_Master as MIM;

Insert/Update Stored Procedure has conversion error

I am trying to make one stored procedure only in SQL Server that lets the user to choose if he/she wants to add or update a record. Below is my code for my stored pro:
CREATE PROCEDURE Sproc_INSERTUPDATE_tblProducts
#ProductID bigint,
#ProductName varchar(50),
#Description varchar(50),
#Price money,
#DateCreated datetime,
#DateUpdated datetime,
#Choice bit output
AS
BEGIN
Select #Choice
If #Choice = 0
Begin
Insert into tblProducts (
ProductID,
ProductName,
Description,
Price,
DateCreated,
DateUpdated)
values (#ProductID,
#ProductName,
#Description,
#Price,
#DateCreated,
#DateUpdated)
Select * from tblProducts
End
Else If #Choice = 1
Begin
Update tblProducts Set ProductID = #ProductID,
ProductName = #ProductName,
Description = #Description,
Price = #Price,
DateCreated = #DateCreated,
DateUpdated = #DateUpdated
Select * from tblProducts
End
Else
Begin
Print 'Invalid choice. Please choose 0 or 1 only.'
End
END
GO
And here is my code for executing the stored pro I made:
USE StoreDB
Execute Sproc_INSERTUPDATE_tblProducts 4, 'Lotus', 'Flower', 85, GetDate, GetDate, 0
I don't encounter any errors with my stored pro but when I try to execute using a new query, I get this error message:
GetDate(): Error converting data type nvarchar to datetime.
You cannot pass a function such as getdate() into a stored proc. Declare a datetime variable and use that instead.
Declare #now datetime = getdate();
Execute Sproc_INSERTUPDATE_tblProducts 4, 'Lotus', 'Flower', 85, #now, #now, 0
Try this?
Execute Sproc_INSERTUPDATE_tblProducts 4, 'Lotus', 'Flower', 85, GetDate(), GetDate(), 0