Fire trigger with cursor using Bulk Insert - c#

I am using BulkInsert - works fine - and trigger - works fine - with cursor which is not working I think. Would you please look at my code and tell me what is my mistake?
Thank you very much.
ALTER TRIGGER [dbo].[CheckProducts]
ON [dbo].[ProductsTemp]
AFTER INSERT
AS
BEGIN
DECLARE #Name NVARCHAR(MAX);
DECLARE #Manufacturer NVARCHAR(MAX);
DECLARE #Source NVARCHAR(50);
DECLARE #SOurceDetailUrl NVARCHAR(MAX);
DECLARE #MainPrice DECIMAL;
DECLARE #SalesPrice DECIMAL;
DECLARE #Description NVARCHAR(MAX);
DECLARE #ImageUrl NVARCHAR(MAX);
DECLARE #GroupId INT;
DECLARE #ParentCategoryId INT;
DECLARE #CategoryId INT;
DECLARE curs CURSOR FOR
SELECT Name, Manufacturer, Source, SourceDetailUrl, MainPrice, SalesPrice, [Description], ImageUrl, GroupId, ParentCategoryId, CategoryId
FROM INSERTED
OPEN curs
FETCH NEXT FROM curs INTO #Name, #Manufacturer, #SourceDetailUrl, #MainPrice, #SalesPrice, #Description, #ImageUrl, #GroupId, #ParentCategoryId, #CategoryId
WHILE ##FETCH_STATUS = 0
BEGIN
IF EXISTS (SELECT * FROM Products WHERE Name = #Name AND Manufacturer = #Manufacturer AND Source = #Source AND SourceDetailUrl = #SourceDetailUrl)
BEGIN
UPDATE Products SET MainPrice = #MainPrice, SalesPrice = #SalesPrice WHERE Name = #Name AND Manufacturer = #Manufacturer AND Source = #Source AND SourceDetailUrl = #SourceDetailUrl
END
ELSE
BEGIN
INSERT INTO Products (Name, Manufacturer, MainPrice, SalesPrice, [Description], Source, SourceDetailUrl, ImageUrl, GroupId, ParentCategoryId, CategoryId)
VALUES (#Name, #Manufacturer, #MainPrice, #SalesPrice, #Description, #Source, #SourceDetailUrl, #ImageUrl, #GroupId, #ParentCategoryId, #CategoryId)
END
DELETE FROM ProductsTemp WHERE Name = #Name AND Manufacturer = #Manufacturer AND Source = #Source AND SourceDetailUrl = #SourceDetailUrl
FETCH NEXT FROM curs INTO #Name, #Manufacturer, #SourceDetailUrl, #MainPrice, #SalesPrice, #Description, #ImageUrl, #GroupId, #ParentCategoryId, #CategoryId
END
CLOSE curs
DEALLOCATE curs
END

Related

Get SQL Cursor Fetched Data in list of Asp.net MVC

I have multiple queries in nested for each loop with millions of records its tack long to process queries with each iteration of loop from asp.net MVC then I have create a cursor instead of executing multiple queries from the action but can't retrieve fetched rows in list/variable.
SQL:
ALTER proc [dbo].[sp_get_AllofPostings]
#comp nvarchar(max),
#TNumber int
as
begin
DECLARE #Id NVARCHAR(128), #AccountCode varchar(max), #TrasactionNumber int, #LedgerNumber int, #RefCode varchar(50), #IsDebit bit, #Amount float, #pcomp nvarchar(max), #CreateDate datetime, #status bit
-- declare cursor
DECLARE postings_cursor CURSOR FOR
SELECT * FROM Postings where TrasactionNumber = #TNumber and CoId=#comp and Amount IS NOT NULL
OPEN postings_cursor;
FETCH NEXT FROM postings_cursor INTO #Id, #AccountCode, #TrasactionNumber, #LedgerNumber, #RefCode, #IsDebit, #Amount, #pcomp, #CreateDate, #status
WHILE ##FETCH_STATUS = 0
BEGIN
--do somthing here
Declare #LAccountName nvarchar(max), #LGLAccount int, #GLName nvarchar(max), #Gaccountcode varchar(50)
SET #LAccountName = (select AccountName from Ledgers where CoId=#comp and AccountCode=#AccountCode)
SET #LGLAccount = (select GLAccount from Ledgers where CoId=#comp and AccountCode=#AccountCode)
SET #GLName = (select GLName from GLAccounts where CoId=#comp and Keyid = #LGLAccount)
SET #Gaccountcode = (select Name from Groups where CoId=#comp and Code = #AccountCode)
FETCH NEXT FROM postings_cursor INTO #Id, #AccountCode, #TrasactionNumber, #LedgerNumber, #RefCode, #IsDebit, #Amount, #pcomp, #CreateDate, #status
END;
CLOSE postings_cursor;
DEALLOCATE postings_cursor;
END
C#:
var posting = db.sp_get_AllofPostings(comp, item.Number);

What is the best approach to inserting or updating an integer using stored procedure?

I have a table called Employees.
This table is updated daily with a scheduled job from Active Directory.
We currently have the following stored procedure that checks if a particular employee exists in the Employee table.
If yes, update the rest of the employee records in that table.
If no, then insert the employee record into that Employee table.
In order to determine whether an employee exists in Employee table or not, employees are required to FIRST enter their employeeID. This is not an auto-generated ID. It is imported into the Employee table along with rest of employee records from Active Directory if that employee record exists in Active Directory.
The issue we are having is that we are not able insert a new employee record into Employee table. Neither are we able to update the record.
We kept getting the message that:
Cannot insert the value NULL into column 'employeeID', table 'Employees'; column does not allow nulls. INSERT fails.The statement has been terminated.
I suspect the issue is with my stored procedure but not sure what the issue is.
Any assistance is greatly appreciated.
Here is my stored proc and the code I am using to try to invoke it.
ALTER PROCEDURE [dbo].[usp_Employees]
#FullName varchar(75),
#address varchar(100),
#city varchar(50),
#state varchar(50),
#zip varchar(50),
#eid int = 0 OUTPUT
AS
BEGIN
SET NOCOUNT ON;
begin tran
if exists (select * from Employees where employeeID = #eid)
begin
UPDATE Employees SET [empFullName] = #FullName
,[Address] = #address
,[City] = #city
,[State] = #state
,[Zip] = #zip where employeeID = #eid
end
else
begin
INSERT INTO [dbo].[Employees]
([empFullName]
,[Address]
,[City]
,[State]
,[Zip]
,[employeeID])
VALUES
(#FullName
,#address
,#city
,#state
,#zip
,#eid)
SET #eid = SCOPE_IDENTITY()
end
commit tran
END
int eid = 0;
SqlCommand cmd = new SqlCommand("usp_Employees", conn);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("#FullName", txtfname.Text);
cmd.Parameters.AddWithValue("#address", txtfaddress.Text);
cmd.Parameters.AddWithValue("#city", txtcity.Text);
cmd.Parameters.AddWithValue("#state", ddlstates.SelectedValue);
cmd.Parameters.AddWithValue("#zip", txtfzip.Text);
SqlParameter employeeID = cmd.Parameters.Add("#eid", SqlDbType.Int);
employeeID.Direction = ParameterDirection.Output;
cmd.ExecuteNonQuery();
eid = Convert.ToInt32(employeeID.Value);
I need to grab this employeeID after insert or update and insert it in other tables.
I think your issue is simply you are not passing the employee id in as it should be. Pass it in with the rest of the code, and discard the output and SCOPE_IDENTITY. Amend you C# to add it to the stored proc along with the rest and it should be fine. Also, not sure of the point of using BEGIN TRAN and COMMIT TRAN without a try/catch, to either commit, or rollback. Otherwise it is just getting committed with or without:
ALTER PROCEDURE [DBO].[USP_EMPLOYEES]
#FULLNAME VARCHAR(75),
#ADDRESS VARCHAR(100),
#CITY VARCHAR(50),
#STATE VARCHAR(50),
#ZIP VARCHAR(50),
#EMPLOYEEID INT ,
#EID INT
AS
BEGIN
SET NOCOUNT ON;
BEGIN TRAN
IF EXISTS (SELECT * FROM EMPLOYEES WHERE EMPLOYEEID = #EID)
BEGIN
UPDATE EMPLOYEES
SET [EMPFULLNAME] = #FULLNAME
,[ADDRESS] = #ADDRESS
,[CITY] = #CITY
,[STATE] = #STATE
,[ZIP] = #ZIP
WHERE EMPLOYEEID = #EID
END
ELSE
BEGIN
INSERT INTO [DBO].[EMPLOYEES]
([EMPFULLNAME]
,[ADDRESS]
,[CITY]
,[STATE]
,[ZIP]
,[EMPLOYEEID])
VALUES
(#FULLNAME
,#ADDRESS
,#CITY
,#STATE
,#ZIP
,#EID)
END
COMMIT TRAN
END
You can use MERGE (starting with Sql Server 2008)
MERGE Employees AS target
USING (SELECT #eid,
#fullName,
#address,
#city,
#state,
#zip) AS source (eid, fullName, address, city, state, zip)
ON (target.employeeID = source.eid)
WHEN MATCHED THEN
UPDATE SET
empFullName = source.fullName,
Address = source.address,
City = source.city,
State = source.state,
Zip = source.zip
WHEN NOT MATCHED THEN
INSERT (employeeID, empFullName, Address, City, State, Zip)
VALUES (source.eid,
source.fullName,
source.address,
source.city,
source.state,
source.zip)
OUTPUT inserted.employeeID; -- return updated or inserted Id
...
#eid int
as
begin
...
SET #eid = SCOPE_IDENTITY()
INSERT INTO [dbo].[Employees]
([empFullName]
,[Address]
,[City]
,[State]
,[Zip]
,[employeeID])
VALUES
(#FullName
,#address
,#city
,#state
,#zip
,#eid)

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

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

dynamic cursor in stored procedure

hi i am dojng a stored procedure which conatains a cursor...cursor has a dynamic sql query ..this query has dynamic value..which is #industry..then i put the results in a temporary table..but the problem is when i execute the procedure results are not coming...
this is my stroedproc in sqlserver
ALTER PROCEDURE GETARTISTDETAIL AS
BEGIN
DECLARE #INDUSTRY VARCHAR(40)
DECLARE #ID INT
DECLARE #SQL1 VARCHAR(1000)
DECLARE #SQL VARCHAR(1000)
SET #INDUSTRY='''BollyWood'',''TollyWood'',''HollyWood'''
CREATE TABLE #TEMPTBL([NAME] VARCHAR(20),[AGE] INT ,[MAILID] VARCHAR(20))
--SET #SQL='SELECT ARTISTID FROM ARTIST WHERE INDUSTRY IN ('+#INDUSTRY+')'
DECLARE TEMPCRS CURSOR LOCAL SCROLL STATIC FOR SELECT ARTISTID FROM ARTIST WHERE INDUSTRY IN (#INDUSTRY)
--PRINT #SQL
--exec (#SQL)
OPEN TEMPCRS
FETCH NEXT FROM TEMPCRS INTO #ID
WHILE ##FETCH_STATUS=0
BEGIN
INSERT INTO #TEMPTBL SELECT [NAME],[AGE],[MAILID] FROM ARTIST WHERE ARTISTID=#ID
FETCH NEXT FROM TEMPCRS INTO #ID
END
CLOSE TEMPCRS
DEALLOCATE TEMPCRS
SELECT * FROM #TEMPTBL
DROP TABLE #TEMPTBL
END
You don't need a cursor to do this, just use a subquery:
DECLARE #INDUSTRY VARCHAR(40)
DECLARE #SQL VARCHAR(1000)
CREATE TABLE #TEMPTBL([NAME] VARCHAR(20),[AGE] INT ,[MAILID] VARCHAR(20))
SET #INDUSTRY='''BollyWood'',''TollyWood'',''HollyWood'''
SET #SQL='INSERT INTO #TEMPTBL SELECT [NAME],[AGE],[MAILID]
FROM ARTIST WHERE ARTISTID IN (
SELECT ARTISTID FROM ARTIST WHERE INDUSTRY IN ('+#INDUSTRY+')
)'
EXEC (#SQL)
SELECT * FROM #TEMPTBL
DROP TABLE #TEMPTBL

Categories