2nd Query in SQL Stored Procedure giving me Null error - c#

I need to run three Insert queries in SQL Server 2008 via stored procedure and expected three OUTPUT values to read in C#. In following Stored Procedure, my first query only runs and remain I am getting Null error
Cannot insert the value NULL into column
'AssessmentElectronicSignatureID'
USE [myDB]
GO
/****** Object: StoredProcedure [dbo]. [p_assessment_dfn_statementAnswer_insert] Script Date: 10/05/2015 13:24:22 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[p_assessment_dfn_statementAnswer_insert]
#StatementID AS bigint,
#StaffID AS int,
#AssessmentID As bigint,
#StatementText AS nvarchar(MAX),
#StatementDate AS Date,
#StatementAnswerID AS bigint OUTPUT,
--
#SignatureCheck AS bit,
#SignatureDate AS Date,
#ElectronicSignatureID AS bigint OUTPUT,
--
#AssessmentElectronicSignatureID AS bigint OUTPUT
AS
SET NOCOUNT ON
SET XACT_ABORT ON
-- local variables
DECLARE #l_object AS SYSNAME = OBJECT_NAME(##PROCID)
,#l_error_msg AS NVARCHAR(2000)
BEGIN TRY
BEGIN TRAN
INSERT INTO [adb_TestDb].[dbo].[Assessment_Statement_Answer]
([StatementID],[StaffID],[AssessmentID],[StatementText],[Date])
VALUES (#StatementID, #StaffID, #AssessmentID, #StatementText, #StatementDate)
SELECT #StatementAnswerID = SCOPE_IDENTITY();
IF(#StatementAnswerID>0)
BEGIN
INSERT INTO [adb_TestDb].[dbo].[Assessment_ElectronicSignature]([AssessmentID],[ElectronicSignatureCheck],[SignatureDateAndTime])
VALUES (#AssessmentID, #SignatureCheck,#SignatureDate)
SELECT #ElectronicSignatureID = SCOPE_IDENTITY();
END
IF(#ElectronicSignatureID>0)
BEGIN
INSERT INTO [adb_TestDb].[dbo].[AssessorSignature]([AssessmentElectronicSignatureID],[StatementAnswerID],[AssessorID])
VALUES(#ElectronicSignatureID, #StatementAnswerID, #AssessmentID)
SELECT #AssessmentElectronicSignatureID = SCOPE_IDENTITY();
END
COMMIT TRAN
--RETURN SCOPE_IDENTITY();
END TRY
BEGIN CATCH
-- rollback any open/uncomitted transactions
IF XACT_STATE() IN ( -1, 1) ROLLBACK TRANSACTION
-- return an error containing the object, error number and error description
SELECT #l_error_msg = 'Error number : ' + CAST(ERROR_NUMBER()AS VARCHAR) + '. ' + ERROR_MESSAGE()
RAISERROR (#l_error_msg,16,1)
END CATCH

There is a known bug with SCOPE_IDENTITY(); Occurs occasionally when triggers are used. Google for the occurances if you want to dig deep. Or...
Try changing things like
SELECT #StatementAnswerID = SCOPE_IDENTITY();
to
SELECT #StatementAnswerID = ##IDENTITY;
Or
SET #StatementAnswerID = ##IDENTITY;
and other similar assignments. I think the problem here is causing because of being the #StatementAnswerID as Null.

Related

Why I get exception when I call stored procedure?

I am using Entity Framework 6 and Microsoft SQL Server 2012.
Here is my stored procedure:
ALTER PROCEDURE SPDeleteRegion
#siteId int,
#regionId int
AS
BEGIN
SET NOCOUNT ON;
DECLARE #isDeleted BIT
IF EXISTS (SELECT 1 FROM SiteObjects WHERE SiteRegionId = #regionId)
BEGIN
SET #isDeleted = 0 ; --not deleted
RETURN #isDeleted;
END
ELSE
BEGIN
--do what needs to be done if not
DELETE FROM SiteRegions
WHERE Id = #regionId;
SET #isDeleted = 1; -- deleted
RETURN #isDeleted;
END
END
Here how I call the stored procedure in C#:
var t = _context.Database.SqlQuery<bool>("SPDeleteRegion #siteId, #regionId",
new SqlParameter("#siteId", siteId),
new SqlParameter("#regionId", regionId));
On the line of code above I get this exception:
The data reader has more than one field. Multiple fields are not valid for EDM primitive or enumeration types.
Any idea why I get the excewption and how to fix it?
Your procedure doesn't selecting anything. Change it like this:
ALTER PROCEDURE SPDeleteRegion
-- Add the parameters for the stored procedure here
#siteId int,
#regionId int
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
DECLARE
#isDeleted BIT
IF EXISTS (SELECT 1 FROM SiteObjects WHERE SiteRegionId = #regionId)
BEGIN
SET #isDeleted = 0 ; --not deleted
SELECT #isDeleted [IsDeleted]; --HERE
END
ELSE
BEGIN
--do what needs to be done if not
DELETE FROM SiteRegions WHERE Id = #regionId;
SET #isDeleted = 1;--deleted
SELECT #isDeleted [IsDeleted]; -- AND HERE
END
END

ADO.NET stored procedure for inserting not working

I have a database which stores information about a library (books, authors & categories).
But I can't get my stored procedure to work for inserting data. The stored procedure itself executes fine, but when I perform a test, it simply doesn't add anything to the database. Can anyone see what I'm missing?
This is my stored procedure (for category):
USE MyLibrary
GO
IF EXISTS (SELECT 1 FROM sysobjects WHERE name = 'CategoryInsert' AND TYPE = 'P')
BEGIN
DROP PROC CategoryInsert
END
GO
CREATE PROCEDURE CategoryInsert
(
#Id int out,
#Name nvarchar(255),
#InsertedBy nvarchar(120),
#InsertedOn datetime
)
AS
DECLARE #CurrentId int
SELECT #CurrentId = Id FROM Category WHERE lower(#Name) = lower(#Name)
IF #CurrentId IS NOT NULL
BEGIN
SET #Id = -100
RETURN
END
INSERT INTO Category
(
Name,
InsertedBy,
InsertedOn
)
VALUES
(
#Name,
#InsertedBy,
#InsertedOn
)
SET #Id = SCOPE_IDENTITY()
GO
This is my test:
USE MyLibrary
GO
DECLARE #NewId int
DECLARE #date datetime
SET #date = getdate()
EXEC CategoryInsert #NewId, 'Testing', 'AL', #date
SELECT #NewId
GO
This line:
SELECT #CurrentId = Id FROM Category WHERE lower(#Name) = lower(#Name)
IF #CurrentId IS NOT NULL
The equality check will always return true because you're essentially comparing WHERE 1 = 1, which means that #CurrentID will always have a value and thus your stored procedure will always return before the INSERT happens.

SQl Transactions - query doesnt return value as expected

tblParent
pid(int) name deleted(bit)
1 abc 0
2 def 0
tblChild
cid(int) name pid(ForeignKey)
1 aaa 1
2 bbb 1
When a record from tblParent is being deleted, it should check for any child records. If yes, rollback & return 0. If no, then update the deleted column to '1' and return 1.
Basically, doing a soft delete
The SP works fine. All I need is to know the status as 0 or 1 based upon the action that took place. How should it be done. I would call this store procedure from c#, linq to entities to get the status.
something like:
public int somefuntion() //returning a string is also fine..
{
return MYDB.SoftDelete(parameters.....);
}
EDIT:
ALTER PROCEDURE SoftDelete
(
#TableName nvarchar(50), #ColName nvarchar(50),
#Id nvarchar(50)
)
AS
BEGIN
DECLARE #qry nvarchar(500)
SELECT #qry = 'begin transaction
delete '+#tablename+' where '+#colname+'='+#id+'
if(##Error <> 0)
Begin
--select 0
End
else
Begin
rollback transaction
update '+#tablename+' set deleted = 1 where '+#colname+' = '+#id+'
--select = 1
end'
EXECUTE sp_executesql #qry
END
Try this:
Declare #status nvarchar(50),#tablename nvarchar(50), #colname nvarchar(50),
#id nvarchar(50), #qry nvarchar(500)
set #tablename = 'person'
set #colname = 'id'
set #id = '15'
begin try
begin transaction
set #qry='delete '+#tablename+' where '+#colname+'=#id'
execute sp_executesql #qry,N'#id nvarchar(50)',#id=#id
rollback
--NO FK violation.So begin another transaction and soft delete
begin transaction
set #qry='update '+#tablename +' set deleted=1 where '+#colname+'=#id'
execute sp_executesql #qry,N'#id nvarchar(50)',#id=#id
commit
select 1
end try
begin catch
print(Error_Message())
--FK violation.Do nothing.Return 0
select 0
end catch
In your script the #status variable is not accessible inside your sql statement you build because "execute sp_executesql #qry" will be executing in different space. Instead use select n" in replace to "set #status = 0" and "set #status = 1"
Try this
Declare #tablename nvarchar(50), #colname nvarchar(50),
#id nvarchar(50), #qry nvarchar(500)
set #tablename = 'tblParent'
set #colname = 'pid'
set #id = '1'
select #qry = 'begin transaction
delete '+#tablename+' where '+#colname+'='+#id+'
if(##Error <> 0)
Begin
select 0
End
else
Begin
rollback transaction
update '+#tablename+' set deleted = 1 where '+#colname+' = '+#id+'
select 1
end
execute sp_executesql #qry

update query returns -1 value eventhough the data is updated in database

update query returns -1 value eventhough the data is updated in database . I am using sql server 2005 stored procedure with c#.
My stored procedure is as follows...
ALTER procedure [dbo].[sp_changepwd]
(
#Cust_Id varchar(50),
#Password varchar(50),
#OldPassword varchar(50),
#Username varchar(50)
)
as
Begin
SET NOCOUNT ON
Begin Tran
update
Customer_Utility_Reg_M_Tbl
set
Password=Convert(varbinary(50),#Password)
where
Cust_Id=#Cust_Id and Password=#OldPassword and Username=#Username
IF ##ERROR = 0
COMMIT TRAN
ELSE
ROLLBACK TRAN
RETURN (##ERROR)
END
SET NOCOUNT OFF when you SET NOCOUNT ON it doesnt report the number of record affected

How to check that a delete / update operation completed successfully when using a stored procedure?

Say we have stored procedure(s) performing simple operations like this:
CREATE PROCEDURE [dbo].[AddNewAuthorReturnID]
(
#Author_Name VARCHAR(MAX),
#Author_ID int OUTPUT
)
AS
SET NOCOUNT OFF;
BEGIN
INSERT INTO AUTHORS (#Author_Name)
VALUES (#Author_Name)
SET #Author_ID = SCOPE_IDENTITY()
SELECT #Author_ID
END
In the above procedure, the returned id is an indication of successful operation.
Consider the equivalent with DELETE.
CREATE PROCEDURE [dbo].[DeleteAuthor]
(
#Author_ID int
)
AS
SET NOCOUNT OFF;
BEGIN
DELETE FROM AUTHORS
WHERE
(Author_ID = #Author_ID)
END
How can we know the operation was
successful and the AUTHORS record was
succesfully removed if we use the above
procedure ?
With an update operation?
You could select ##rowcount
It will show you the rows affected.
e.g
CREATE PROCEDURE [dbo].[DeleteAuthor]
(
#Author_ID int
)
AS
SET NOCOUNT OFF;
BEGIN
DELETE FROM AUTHORS
WHERE
(Author_ID = #Author_ID)
SELECT ##ROWCOUNT
END
This can be applied to update too.
CREATE PROCEDURE [dbo].[UpdateAuthor]
(
#Author_ID int
)
AS
SET NOCOUNT OFF;
BEGIN
UPDATE AUTHORS
SET AuthorName = 'John'
WHERE
(Author_ID = #Author_ID)
SELECT ##ROWCOUNT
END
Alternatively you could use ##Error and raise an error id ##rowcount > 1 (if you only wanted to update one row).
e.g
CREATE PROCEDURE [dbo].[DeleteAuthor]
(
#Author_ID int
)
AS
SET NOCOUNT OFF;
BEGIN
DELETE FROM AUTHORS
WHERE
(Author_ID = #Author_ID)
IF ##ROWCOUNT <>1
BEGIN
RAISERROR ('An error occured',10,1)
RETURN -1
END
END
As Giorgi says this will be returned as a returncode.
You can to return ##ROWCOUNT to determine if your last statement affected any record.
You can return value from stored procedure using return statement. The ##ERROR variable is equal to zero if there was no error.
##ERROR
CREATE PROCEDURE [dbo].[DeleteAuthor]
(
#Author_ID int
)
AS
SET NOCOUNT OFF;
BEGIN
DELETE FROM AUTHORS
WHERE
(Author_ID = #Author_ID)
Return ##ERROR
END

Categories

Resources