How to read Scope Identity in C# from executed Stored Procedure - c#

I want to read Scope_Identity via output variable '#RoleID' from where I am assigning value of scope identity.
C#:
private static long createNewRoleInsert(ADB.Model.RolesModel roleModelObj, MSSQL sql)
{
bool killConnection = Utils.getConnection(ref sql);
long returnValue = 0;
try
{
sql.SetSProc("[dbo].[p_Role_dfn_createNew]");
sql.AddParam("#Title", roleModelObj.Title);
sql.AddParam("#Description", roleModelObj.Description);
sql.AddParam("#CreatedDate", roleModelObj.CreatedDate);
var RoleID = sql.ExecuteNonQuery();
if(RoleID!=0 && RoleID>0)
{
returnValue = RoleID;
}
}
finally
{
if (killConnection)
sql.Dispose();
}
return returnValue;
}
Stored procedure:
SET ANSI_NULLS ON
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[p_Role_dfn_createNew]
#Title nvarchar(250),
#Description nvarchar(MAX) = NULL,
#CreatedDate DateTime,
#RoleID bigInt OUTPUT
AS
SET NOCOUNT ON;
SET XACT_ABORT ON
DECLARE #l_object AS SYSNAME = OBJECT_NAME(##PROCID),
#l_error_msg AS NVARCHAR(2000)
BEGIN TRY
BEGIN TRAN
INSERT INTO [adb_TestDb].[dbo].[Role] ([Title], [Description], [CreatedDate])
VALUES (#Title, #Description, #CreatedDate)
COMMIT TRAN
SET #RoleID = SCOPE_IDENTITY();
RETURN #RoleID
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

The ExecuteNonQuery method doesn't return the return value from the procedure, it returns the number of rows affected.
To get the return value you would add a parameter with ParameterDirection.ReturnValue, however that won't safely get you the value in #RoleID as the return value from a procedure can't be a bigint, it's always an int.
As you already have #RoleID as an output parameter you should add parameter to the command to get the value. Example:
SqlParameter roleIdParam = new SqlParameter("#RoleID", SqlDbType.BigInt);
roleIdParam.Direction = ParameterDirection.Output;
cmd.Parameters.Add(roleIdParam);
// execute command
long roleId = (long)roleIdParam.Value;

You need to add an output parameter in C# to get the value of #RoleID from the stored procedure. Here's an example of that:
using System.Data.SqlClient;
using (SqlConnection conn = new SqlConnection("connectionString"))
{
SqlCommand cmd = conn.CreateCommand();
cmd.CommandType = System.Data.CommandType.StoredProcedure;
cmd.CommandText = "dbo.p_Role_dfn_createNew";
// add other parameters...
cmd.Parameters.Add(new SqlParameter("#RoleID", SqlDbType.BigInt))
.Direction = ParameterDirection.Output;
cmd.ExecuteNonQuery();
returnValue = (long)cmd.Parameters["#RoleID"].Value;
}

Change the
RETURN #RoleID
to
SELECT #RoleID
or add the output parameter as explained in other answers

Related

Conversion error when i call a stored procedure from SQL Server in C#

I have a stored procedure called lastID like this:
CREATE PROCEDURE lastID(#id varchar(64) OUTPUT)
AS
BEGIN
SET NOCOUNT ON;
DECLARE #f VARCHAR(64);
SELECT TOP 1 #f = work_id
FROM workorder
WHERE (RIGHT(work_id,2)) = (RIGHT(Year(getDate()),2))
ORDER BY work_id DESC;
IF(#f IS NULL)
BEGIN
SET #f = 'No work orders';
SET #id = #f;
RETURN #id;
END
ELSE
BEGIN
SET #id = #f;
RETURN #id;
END
END
This stored procedure returns the last id from the table workorder, now I'm trying to execute this procedure in C#, this is the code:
private void lastWorkId()
{
String strConnString = "Server=.\\SQLEXPRESS;Database=recalls;Integrated Security=true";
SqlConnection con = new SqlConnection(strConnString);
SqlCommand cmd = new SqlCommand();
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText = "lastID";
cmd.Parameters.Add("#id", SqlDbType.VarChar, 64).Direction = ParameterDirection.Output;
cmd.Connection = con;
try
{
con.Open();
cmd.ExecuteNonQuery();
String id = cmd.Parameters["#id"].Value.ToString();
lastid.Text = id.ToString(); //Putting the return value into a label
}
catch (Exception ex)
{
throw ex;
}
finally
{
con.Close();
con.Dispose();
}
}
I don't know what are wrong with my code, because an exception is displayed, and this says
Conversion failed when converting the varchar value ' OT- 003-16 ' to data type int
I was wrong about my first answer, here is the updated answer:
Your stored procedure is setup with an OUTPUT parameter of type VARCHAR(64).
Within your proc you have a couple of RETURN #id; statements, which is actually returning a VARCHAR(64). You only need to set your OUTPUT variable within the stored procedure. The RETURN statement expects an integer expression. Here's the updated fixed sproc using OUTPUT appropriately:
ALTER PROCEDURE [dbo].[lastID](#id varchar(64) OUTPUT)
AS
BEGIN
SET NOCOUNT ON;
DECLARE #f VARCHAR(64);
SELECT TOP 1 #f = work_id FROM workorder WHERE (RIGHT(work_id,2)) = (RIGHT(Year(getDate()),2)) ORDER BY work_id DESC;
IF(#f IS NULL)
BEGIN
SET #f = 'No work orders';
SET #id = #f;
END
ELSE
BEGIN
SET #id = #f;
END
END
Error is basically should get fixed by cast
((RIGHT(work_id,2)) as int)
But code can be further condensed and improved.
CREATE PROCEDURE lastID(#id varchar(64) OUTPUT)
AS
BEGIN
SET NOCOUNT ON;
SELECT TOP 1 #id = isnull(work_id , 'No work orders') FROM workorder WHERE cast ((RIGHT(work_id,2)) as int)= (RIGHT(Year(getDate()),2)) ORDER BY work_id DESC;
RETURN #id;
END

How to create sql server stored procedure with output parameter and call from C#

Still i get an error "The formal parameter "#result" was not declared as an OUTPUT parameter, but the actual parameter passed in requested output".
here is my code in c#
SqlCommand cmd = new SqlCommand("AddRoomType", con);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("#TypeName", TxtType.Text);
cmd.Parameters.Add("#result", SqlDbType.Int);
cmd.Parameters["#result"].Direction = ParameterDirection.Output;
con.Open();
cmd.ExecuteNonQuery();
con.Close();
my stored procedure in SQL server
Create proce AddRoomType
#TypeName nvarchar(50),
#result int
as
if(exists(select * from TblRoomTypes where RoomType = #TypeName))
set #result = 0
else
begin
set #result = 1
insert into TblRoomTypes (RoomType) values (#TypeName)
end
please Help
Set Your Parameter as OUTPUT when creating the Stored Procedure
create proc AddRoomType
#TypeName nvarchar(50),
#result int out -- ** NOTE it's declared as 'OUT' **
as
if(exists(select * from TblRoomTypes where RoomType = #TypeName))
set #result = 0
else
begin
set #result = 1
insert into TblRoomTypes (RoomType) values (#TypeName)
end

Error converting data type varchar to int

This is my stored procedure code
ALTER procedure [Proc_Add_User]
(#UserId varchar(20),
#UserName varchar(100),
#Page_Name varchar(20),
#AccessIndicator int,
#CreatedBy varchar(50),
#returnStatus varchar(50) output)
as
DECLARE #intErrorCode INT
DECLARE #Page_Indicator INT
begin
BEGIN TRAN
Set #Page_Indicator = (select Page_Indicator from Pages where Page_Name=#Page_Name);
if (select count(*) from Users where UserId=#UserId and UserName=#UserName) > 0 begin
if (select count(*) from User_Credentials where Page_Indicator=#Page_Indicator and
UserId=#UserId ) > 0
set #returnStatus='User already has access'
else
insert into User_Credentials(UserId,Page_Indicator,Access_Indicator,CreatedBy)
values (#UserId,#Page_Indicator,#AccessIndicator,#CreatedBy)
SELECT #intErrorCode = ##ERROR
IF (#intErrorCode <> 0) GOTO PROBLEM
end
else begin
insert into Users(UserId,UserName,CreatedBy)
values(#UserId,#UserName,#CreatedBy)
SELECT #intErrorCode = ##ERROR
IF (#intErrorCode <> 0) GOTO PROBLEM
insert into User_Credentials(UserId,Page_Indicator,Access_Indicator,CreatedBy)
values (#UserId,#Page_Indicator,#AccessIndicator,#CreatedBy)
SELECT #intErrorCode = ##ERROR
IF (#intErrorCode <> 0) GOTO PROBLEM
end
COMMIT TRAN
if(#returnStatus is null)
set #returnStatus='Success';
PROBLEM:
IF (#intErrorCode <> 0) BEGIN
set #returnStatus= 'Unexpected error occurred!'
ROLLBACK TRAN
end
end
And I am calling this from the code pasted below:
Con.Open();
cmd = new OleDbCommand();
cmd.Connection = Con;
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText = "Proc_Add_User";
cmd.Parameters.Clear();
cmd.Parameters.Add("#UserId", SqlDbType.VarChar).Value = userLanId;
cmd.Parameters.Add("#UserName", SqlDbType.VarChar).Value = userName;
cmd.Parameters.Add("#Page_Name", SqlDbType.VarChar).Value = pageName;
cmd.Parameters.Add("#AccessIndicator", SqlDbType.Int).Value = accessIndicator;
cmd.Parameters.Add("#CreatedBy", SqlDbType.VarChar).Value = createdBy;
OleDbParameter output = new OleDbParameter("#returnStatus", SqlDbType.VarChar);
output.Direction = ParameterDirection.Output;
cmd.Parameters.Add(output);
int result = cmd.ExecuteNonQuery();
I am getting the error mentioned at the ExecuteNonQuery statement. What's confusing to me is I am able to execute the stored procedure in SSMS but not from my application (front-end). I provided the same values too yet it fails from my app.
I double checked to make sure the order of parameters passed match and are of same data type but still it throws this error. I can paste my stored proc code here if wanted so let me know..Thanks in advance!
EDIT
OOPS! I just realized that all the inserts are all happening and getting committed fine in the database. It's just this error is getting caught inside catch block in my app. Any ideas?
I can not ignore it because based on the return value of ExecuteNonQuery(), I have some statements and also it's not going through the code present after ExecuteNonQuery().
This is most likely because you are using SqlDbType with OleDbParameters:
OleDbParameter output = new OleDbParameter("#returnStatus", SqlDbType.VarChar);
This causes .NET to use the OleDbParameter(String, Object) constructor, setting the value of the parameter to SqlDbType.VarChar which it assumes is an int.
You should use this instead:
OleDbParameter output = new OleDbParameter("#returnStatus", OleDbType.VarChar);
And change your calls to cmd.Parameters.Add to use OleDbType as well.
Alternatively, you could use System.Data.SqlClient instead of OleDb

returning int value from stored procedure and check it in asp.net code to validate login form

What is the true sequence to make this code run as I tried many time but I don't get a valid result
// the code of SQL stored procedure
set ANSI_NULLS ON
set QUOTED_IDENTIFIER ON
GO
ALTER PROC [dbo].[login_proc] #username Varchar =50, #password varchar=50
as
Declare #user_name varchar , #pass_word varchar, #result varchar
Set #user_name = #username
Set #pass_word = #password
if EXISTS (select username , password from data where username= #user_name)
set #result= 1
else
set #result=0
return #result
and asp.net code is
SqlConnection conn = new SqlConnection ("Data Source=ANAGUIB-LAPNEW\\SQLEXPRESS;Initial Catalog=account;Integrated Security=True");
SqlCommand cmd = new SqlCommand("login_proc",conn);
cmd.CommandType = CommandType.StoredProcedure;
SqlParameter paramReturnValue = new SqlParameter();
paramReturnValue.ParameterName = "#result";
paramReturnValue.SqlDbType = SqlDbType.Int;
cmd.Parameters.Add(paramReturnValue);
cmd.Parameters["#result"].Direction = ParameterDirection.Output;
conn.Open();
cmd.Parameters.AddWithValue("#username", TextBox1.Text);
cmd.Parameters.AddWithValue("#password", TextBox2.Text);
cmd.ExecuteScalar();
string retunvalue = (string)cmd.Parameters["#result"].Value;
if (retunvalue == "1")
{
Response.Redirect("hello.aspx");
}
else
{
Response.Write("error");
}
conn.Close();
You're executing .ExecuteScalar() so you're expecting back a result set with a single row, single column from the stored procedure - but you're not selecting anything at the end of your stored proc!
You need to change your last line in the stored proc from
return #result
to
SELECT #result
and then it should work.
Add another parameter for the return value
ALTER PROC [dbo].[login_proc]
#username Varchar = 50,
#password Varchar = 50,
#result int OUTPUT
Examples can be viewd here.
Did you try this one;
Use the
return #result
and in c#
int resultID = Convert.ToInt32(cmd.ExecuteScalar());
Also remove next line
cmd.Parameters[""].value;
I'm unable to login any suggestions, both in case of stored procedure and codebehind can anyone provide solution to this,,,plz,,,

Ado.net ExecuteScalar() returning null

I am executing a stored procedure in c# (through vs2008) using ado.net with an ExecuteScalar command. The stored proc returns the pkey of the new record entered, but ExecuteScalar is returning null. I look in the database and a record has indeed been added. I could use an output parameter to get the value, but then I won't know why this didn't work.
When I execute the sp in ssms, the pkey is returned.
What am I doing wrong?
Here is the C# code:
public int SaveNewPerson(EPerson ePerson)
{
int newPersonPkey;
SqlConnection cn = new SqlConnection(cnn.PersonData);
using (cn)
{
try
{
SqlCommand cmd = new SqlCommand();
cmd.Connection = cn;
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText = "People.dbo.AddNewPerson";
cmd.Parameters.Add("#LastName", SqlDbType.VarChar, 150).Value = ePerson.LastName;
cmd.Parameters.Add("#FirstName", SqlDbType.VarChar, 150).Value = ePerson.FirstName;
cn.Open();
object result = cmd.ExecuteScalar();
newPersonPkey = int.Parse(result.ToString());
cn.Close();
}
catch (Exception e)
{
// call error method
throw new Exception(e.Message + " save new Person error ");
}
}
return newPersonPkey;
}
And this is the sp:
PROCEDURE [dbo].[AddNewPerson]
#FirstName varchar(50)
,#LastName varchar(50)
AS
BEGIN
SET NOCOUNT ON;
INSERT INTO [People].[dbo].[Persons]
(
[FirstName]
,[LastName]
)
VALUES
(
#FirstName
,#LastName
)
declare #persons_PKey int
set #persons_PKey = ##IDENTITY
return #persons_PKey
end
The ExecuteScalar method returns the first field of the first record of the result, but as your query doesn't produce a result, it will return null.
You can either select the value instead of returning it from the stored procedure, or add a parameter with the direction set to ParameterDirection.ReturnValue to catch what the stored procedure returns.
Try changing the Stored Procedure to use a Select Statement to return the identity instead of using a return like this:
SELECT CAST(scope_identity() AS int)
Thus changing your procedure to:
PROCEDURE [dbo].[AddNewPerson]
#FirstName varchar(50)
,#LastName varchar(50)
AS
BEGIN
SET NOCOUNT ON;
INSERT INTO [People].[dbo].[Persons]
(
[FirstName]
,[LastName]
)
VALUES
(
#FirstName
,#LastName
)
SELECT CAST(scope_identity() AS int)
end
From the documentation of the ExecuteScalar() on MSDN it says that it will return the first column of the first row in the result set or null otherwise if the result set is empty.

Categories