SQL Server Cannot insert duplicate key in object - c#

I have a problem with high frequency inserts. I use a stored procedure to insert data into my table, but I get this error:
System.Data.SqlClient.SqlException (0x80131904): Violation of PRIMARY KEY constraint 'PK_MyTable'. Cannot insert duplicate key in object 'dbo.MyTable'. The duplicate key value is (3001749001, 0, 02/09/2016, abc).
The statement has been terminated.
This is my code:
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[SetData]
#Key1 nvarchar(50),
#Key2 int,
#Key3 nvarchar(50),
#Key4 nvarchar(50),
#Data1 nvarchar(100)
AS
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
BEGIN TRANSACTION;
IF EXISTS (SELECT 1
FROM [dbo].[MyTable]
WHERE [Key1] = #Key1 AND [Key2] = #Key2 AND [Key3] = #Key3 AND [Key4] = #Key4)
BEGIN
UPDATE [dbo].[MyTable]
SET [Data1] = #Data1
,[UpdateTime] = getdate()
WHERE [Key1] = #Key1 AND [Key2] = #Key2 AND [Key3] = #Key3 AND [Key4] = #Key4
END
ELSE
BEGIN
INSERT INTO [dbo].[MyTable]
([Key1]
,[Key2]
,[Key3]
,[Key4]
,[Data1]
,[UpdateTime])
VALUES
(#Key1,
#Key2,
#Key3,
#Key4,
#Data1,
getdate())
END
COMMIT TRANSACTION;

Related

Transaction mismatch. Previous count = 1, current count = 0 , Entity Framework only

I have 3 SQL Objects:
Table Employee with three fields (id, name, salary)
Procedure Insert_employee [to insert in employee table]
Trigger [to make validation for table]
My problem: if call Insert_employee by Entity Framework,
Transaction count after EXECUTE indicates a mismatching number of BEGIN and COMMIT statements. Previous count = 1, current count = 0.
ALTER PROC [dbo].[Insert_Employees]
(
#id AS INT,
#name AS NVARCHAR(max),
#salary AS NUMERIC(18,3)
)
AS
BEGIN
DECLARE #error AS NVARCHAR(max)
BEGIN TRANSACTION
INSERT INTO employee(Id, Name,Salary)
SELECT #id, #name , #salary
SELECT #error = ##ERROR
IF #error = 0 COMMIT ELSE ROLLBACK
END
ALTER TRIGGER [dbo].[INS_employee] ON [dbo].[Employee]
INSTEAD OF INSERT
AS
BEGIN
IF EXISTS (SELECT * FROM inserted WHERE inserted.name = '')
BEGIN
RAISERROR('name is empty',16,1);
END
ELSE
INSERT INTO employee(id, Name, Salary)
SELECT id, Name, Salary FROM inserted
END

Complex types show no result for a stored procedure

I have a stored procedure I would like to use its result in a Web API (C#).
I must miss something since I'm getting no result nor in Complex Types (in EF model) neither in Functions Imports (I can see the stored procedure in Functions Imports but it does not return any value, as expected).
This is my stored procedure (I have erased some non-important data in order to make it shorter)
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
#main_id BIGINT,
#id_ze_mish BIGINT,
#id_nof BIGINT,
#loggedInUser VARCHAR(20)
AS
BEGIN
SET NOCOUNT ON;
BEGIN TRY
BEGIN TRANSACTION [TransactionUniteSingles]
OPEN SYMMETRIC KEY io_key DECRYPTION BY CERTIFICATE chn_cert
-- Step 1
UPDATE [dbo].[t1]
SET deleted = 1,
WHERE id_nof = #id_nof
AND id_ze = #id_ze_mish
-- Step 2
UPDATE [dbo].[t_no_nir]
SET update_stamp = GETDATE(),
[user_name] = #loggedInUser
WHERE id_nof = #id_nof
AND ms_zehut_mazmin = #id_ze_mish
-- Step 3
CREATE TABLE #mainPrice
(
id INT,
fName VARCHAR(20),
lName VARCHAR(20)
)
INSERT INTO #mainPrice
EXEC [dbo].[io_sp_get_some_data_foo] #id
IF(EXISTS(select * from #mainPrice))
BEGIN
DECLARE #totalAmount INT;
SELECT #totalAmount = (main_price + price_tip + price_visa)
FROM #mainPrice
DROP TABLE #mainPrice
UPDATE [dbo].[t_4]
SET amount = #totalAmount,
update_stamp = GETDATE(),
[user_name] = #loggedInUser
WHERE id_nof = #id_nof
AND id = #main_id
CLOSE ALL SYMMETRIC KEYS
COMMIT TRANSACTION [TransactionUniteSingles]
SELECT CAST(1 as BIT) as 'Status', 'Succeeded' as 'ReturnMessage'
END
ELSE
BEGIN
SELECT CAST(0 as BIT) as 'Status', 'ADMIN - Unite Singles as 'ReturnMessage'
END
END TRY
BEGIN CATCH
ROLLBACK TRANSACTION [TransactionUniteSingles]
SELECT CAST(0 as BIT) as 'Status', 'ADMIN - Unite Singles' as 'ReturnMessage'
END CATCH
END
Please note - when running the stored procedure as standalone, it works perfectly and return what expected.
Check what happens when you call your procedure with NULL input parameters. If the result is not a table then EF will not generate the complex result.
Try following:
-- declare table at SP begin
DECLARE #ResultTable TABLE(
Status BIT NOT NULL,
ResultMessage NVARCHAR(50) NOT NULL
)
-- insert data where you need
INSERT INTO #ResultTable
(
Status,
ResultMessage
)
VALUES
( NULL, -- Status - bit
N'' -- ResultMessage - nvarchar(50)
)
-- at SP end select result from table
SELECT * FROM #ResultTable
I found out that my problem is with my temp table.
when using SET FMTONLY OFF at the top of my SP or above the temp table(#mainPrice in my case) then everything works like a charm and suddenly the Complex Types shows my SP.
Another solution is using a variable table: DECLARE TABLE #mainPrice.
Both do the work.
I'll be happy to know why it happens and why C# refused to get a temp table as part of my SP , but at the moment I found the solution needed.

Cannot insert explicit value for identity column in table

Code:
SET ANSI_NULLS OFF
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[AddUpdateCustomer]
#CustomerID NCHAR(5),
#ContactName NVARCHAR(30),
#CompanyName NVARCHAR(40)
AS
BEGIN
SET NOCOUNT ON;
IF EXISTS(SELECT * FROM Customers WHERE CustomerID = #CustomerID)
BEGIN
UPDATE [Customers]
SET [CompanyName] = #CompanyName
,[ContactName] = #ContactName
WHERE CustomerID = #CustomerID
END
ELSE
BEGIN
INSERT INTO [Customers]
([CustomerID]
,[CompanyName]
,[ContactName])
VALUES
(#CustomerID
,#CompanyName
,#ContactName)
END
SELECT [CustomerID]
,[CompanyName]
,[ContactName]
FROM Customers
END
When I am inserting data in textbox this error occurs:
Cannot insert explicit value for identity column in table 'Customers' when IDENTITY_INSERT is set to OFF
ALTER PROCEDURE [dbo].[AddUpdateCustomer]
#CustomerID INT OUTPUT,
#ContactName NVARCHAR(30),
#CompanyName NVARCHAR(40)
AS
BEGIN
SET NOCOUNT ON;
IF EXISTS(SELECT * FROM Customers WHERE CustomerID = #CustomerID)
BEGIN
UPDATE [Customers]
SET [CompanyName] = #CompanyName
,[ContactName] = #ContactName
WHERE CustomerID = #CustomerID
END
ELSE
BEGIN
INSERT INTO [Customers]
([CompanyName]
,[ContactName])
VALUES
(#CompanyName
,#ContactName)
SET #CustomerID = SCOPE_IDENTITY()
END
SELECT [CustomerID]
,[CompanyName]
,[ContactName]
FROM Customers
WHERE [CustomerID] = #CustomerID
END
To an identity column you cannot insert data explicitly. To insert data into an identity column explicitly you need to set the IDENTITY_INSERT to ON.You can do it by using the below.
SET IDENTITY_INSERT Database.table_name ON

How to set identity for a columns in destination table while importing from msaccess to sql

I have successfully imported database from msaccess to sql server using linked servers but it doesn't set is identity prpoerty to columns in destination table.
I have written one stored procedure with setting the identity_insert on before the select * into query but it is being gotten error.
This is my procedure
create proc
SP_Create(#servername nvarchar(100),
#datasr nvarchar(MAX),#table nvarchar(100),
#table1 nvarchar(100),#db nvarchar(100))
as begin EXEC sp_addlinkedserver #server = #servername,
#provider = 'Microsoft.Jet.OLEDB.4.0',
#srvproduct = 'OLE DB Provider for Jet',
#datasrc = #datasr,#provstr=''
exec sp_addlinkedsrvlogin #rmtsrvname=#servername,
#useself = N'false',#locallogin = NULL,#rmtuser = N'Admin',
#rmtpassword = NULL declare #sql nvarchar(MAX)
set #sql=' SET IDENTITY_INSERT '+#table1+' ON; select * into '+#table1+' from '+#servername+'...'+#table+' with (nolock) SET IDENTITY_INSERT '+#table1+' ON '
Exec(#sql)
declare #sql1 nvarchar(MAX) set #sql1 ='EXEC master.sys.sp_dropserver '+#servername+',''droplogins''' exec(#sql1)
end
would u pls resolve this

Passing value to one table and updating in parent table

I have two tables.
dbo.Emp
EmpID(PK) | Name | TypeID(FK)
dbo.EmpType
TypeID(PK) | Type
TypeID: AutoIncrement only in dbo.EmpType
When I update value for TypeID in Emptype, it needs get stored in TypeID of dbo.Emp
I used SP which is not working.
Create Procedure bridge_Type(
#EmpID INT,
#Name varchar(50),
#Mob2 numeric(10,0),
#Email varchar(50),
#Type varchar(50)
)
AS
DECLARE #TYPEID int
Set NOCOUNT OFF
BEGIN TRANSACTION
Insert into dbo.Emp VALUES (#EmpID, #Name, #Mob2, #Email, #TYPEID)
IF ##ERROR <> 0
BEGIN
ROLLBACK
RETURN
END
INSERT INTO dbo.EmpType VALUES (#Type)
IF ##ERROR <> 0
BEGIN
ROLLBACK
RETURN
END
declare #id int
SET #id= #TYPEID;
Update Dbo.Emp
Set #TYPEID= (Select TypeID from dbo.EmpType
WHERE TypeID=#typeID)
COMMIT
Try This SP, This will first insert the EmpType, and From SCOPE_IDENTITY() it will get the Inserted Identity Value, and then insert emp.
Create Procedure bridge_Type(
#EmpID INT,
#Name varchar(50),
#Mob2 numeric(10,0),
#Email varchar(50),
#Type varchar(50)
)
AS
DECLARE #TYPEID int
Set NOCOUNT OFF
BEGIN TRANSACTION
INSERT INTO dbo.EmpType VALUES (#Type)
SET #TYPEID = SCOPE_IDENTITY()
IF ##ERROR <> 0
BEGIN
ROLLBACK
RETURN
END
Insert into dbo.Emp VALUES (#EmpID, #Name, #Mob2, #Email, #TYPEID)
IF ##ERROR <> 0
BEGIN
ROLLBACK
RETURN
END
COMMIT
Not 100% sure why you would be updating the typeID in your EmpType table (particularly as it is an autoincrement key), however, you could look at updating your FK constraint to 'cascade on update':
When to use "ON UPDATE CASCADE"
http://msdn.microsoft.com/en-us/library/aa933119(v=sql.80).aspx

Categories