C# DataSet, Data Source and Stored Procedure - c#

So I have this code inside a stored procedure:
select * from myTable where email = #email
assume that #email is nvarchar(50) and email is a column in the table
I have a DataSet that has the above stored procedure.
I have a DataGridView that has it's data source as the dataset which uses the stored procedure.
I want to pass a value to the #email in the stored procedure. Is this possible?

Yes. Assuming SqlCommand object 'command', just add the Parameters to it. See here
string Email="Email";
string email="somebody#hotmail.com";
command.Parameters.Add(new SqlParameter(Email, email));
Of course, your stored Procedure needs to be expecting the parameter also.
CREATE PROCEDURE [dbo].[usp_YourStoredProc]
(
#Email [nvarchar(50)] = NULL,
.
.
.

You can use this one
// Create the command and set its properties.
SqlCommand command = new SqlCommand();
command.Connection = connection;
command.CommandText = "ProcedureName";
command.CommandType = CommandType.StoredProcedure;
// Add the input parameter and set its properties.
SqlParameter parameter = new SqlParameter();
parameter.ParameterName = "#email";
parameter.SqlDbType = SqlDbType.NVarChar;
parameter.Direction = ParameterDirection.Input;
parameter.Value = textEmail.Text;
// Add the parameter to the Parameters collection. command.Parameters.Add(parameter);

Related

Why i can not handle the store procedure return value is c#?

I'm new in c#,and want to write simple application work with sql server store procedure,in the sql server write this store procedure:
USE [mammutRecruitment]
ALTER PROCEDURE [dbo].[FirstStep]
#Name nvarchar(max),#Family nvarchar(max),#FatherName nvarchar(max),#BirthCertificate bigint,#PlaceOfBirth nvarchar(max),#BirthDate datetime,
#NationalCode bigint,#Religion nvarchar(max),#faith nvarchar(max),#Nationality nvarchar(max),#BloodGroup nvarchar(max)
AS
BEGIN
DECLARE #MYID bigint
insert into [dbo].[UserMainSpecifications] values(#Name,#Family,#FatherName,#BirthCertificate,#PlaceOfBirth,1,#BirthDate,#NationalCode,
#Religion,#faith,#Nationality,#BloodGroup,12,'123','123',1,2015-1-1,'12','123','1234',1)
select #MYID=[UserID] from [mammutRecruitment].[dbo].[UserMainSpecifications]
where [NationalCode]=#NationalCode
select #MYID as myID
END
and in c# write this code for call that:
using (SqlConnection con = new SqlConnection("Data Source=.;Initial Catalog=mammutRecruitment;Integrated Security=True"))
{
using (SqlCommand cmd = new SqlCommand("FirstStep", con))
{
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add("#Name", SqlDbType.NVarChar).Value = m.Name;
cmd.Parameters.Add("#Family", SqlDbType.NVarChar).Value = m.Family;
cmd.Parameters.Add("#FatherName", SqlDbType.NVarChar).Value = m.FatherName;
cmd.Parameters.Add("#BirthCertificate", SqlDbType.BigInt).Value =Convert.ToInt64(m.BirthCertificate);
cmd.Parameters.Add("#PlaceOfBirth", SqlDbType.NVarChar).Value = m.PlaceOfBirth;
cmd.Parameters.Add("#BirthDate", SqlDbType.DateTime).Value =Convert.ToDateTime(dt.ToString());
cmd.Parameters.Add("#NationalCode", SqlDbType.BigInt).Value =Convert.ToInt64(m.NationalCode);
cmd.Parameters.Add("#Religion", SqlDbType.NVarChar).Value = m.Religion;
cmd.Parameters.Add("#faith", SqlDbType.NVarChar).Value = m.faith;
cmd.Parameters.Add("#Nationality", SqlDbType.NVarChar).Value = m.Nationality;
cmd.Parameters.Add("#BloodGroup", SqlDbType.NVarChar).Value = m.BloodGroup;
SqlParameter retval = cmd.Parameters.Add("#myID", SqlDbType.BigInt);
retval.Direction = ParameterDirection.ReturnValue;
con.Open();
cmd.ExecuteNonQuery();
var retunvalue = cmd.Parameters["#myID"].Value;
but in the this line i get zero value always:
var retunvalue = cmd.Parameters["#myID"].Value;
What happen?How can i solve that problem?thanks.
This line:
cmd.ExecuteNonQuery();
Is executing your query and not returning a value.
You could start by looking into using this instead:
cmd.ExecuteReader();
Or if you want the value of the first field of the first row, you could use this:
var returnValue = cmd.ExecuteScalar();
Which will give you an object that you can then convert or cast into the appropriate type for your method.
SqlCommand.ExecuteNonQuery Method ()
Executes a Transact-SQL statement against the connection and returns
the number of rows affected.
SqlCommand.ExecuteScalar Method ()
Executes the query, and returns the first column of the first row in
the result set returned by the query. Additional columns or rows are
ignored.
I believe you want the second method
You need to include #myID as an output parameter in your stored procedure definition:
ALTER PROCEDURE [dbo].[FirstStep]
#Name nvarchar(max),#Family nvarchar(max),#FatherName nvarchar(max),#BirthCertificate bigint,#PlaceOfBirth nvarchar(max),#BirthDate datetime,
#NationalCode bigint,#Religion nvarchar(max),#faith nvarchar(max),#Nationality nvarchar(max),#BloodGroup nvarchar(max)
, #myID bigint output
AS
And then remove the line
DECLARE #MYID bigint
You also need to add the parameter to cmd in your c# code:
cmd.Parameters.Add(retval);
you need define #MYID as output parameter.
USE [mammutRecruitment]
ALTER PROCEDURE [dbo].[FirstStep]
#MYID bigint output,#Name nvarchar(max),#Family nvarchar(max),#FatherName nvarchar(max),#BirthCertificate bigint,#PlaceOfBirth nvarchar(max),#BirthDate datetime,
#NationalCode bigint,#Religion nvarchar(max),#faith nvarchar(max),#Nationality nvarchar(max),#BloodGroup nvarchar(max)
AS
BEGIN
insert into [dbo].[UserMainSpecifications] values(#Name,#Family,#FatherName,#BirthCertificate,#PlaceOfBirth,1,#BirthDate,#NationalCode,
#Religion,#faith,#Nationality,#BloodGroup,12,'123','123',1,2015-1-1,'12','123','1234',1)
select #MYID = SCOPE_IDENTITY()
END
and add your command
SqlParameter pOut = new SqlParameter("#MYID", SqlDbType.BigInt);
pOut.Direction = ParameterDirection.Output;
cmd.Parameters.Add(pOut);
You can read the value now
cmd.ExecuteNonQuery();
long newId = (long)pOut.Value;
Actually, you need change that statement:
retval.Direction = ParameterDirection.ReturnValue;
to
retval.Direction = ParameterDirection.Output
because ExecuteNonQuery return:
Executes a Transact-SQL statement against the connection and returns the number of rows affected.
Although the ExecuteNonQuery returns no rows, any output parameters or return values mapped to parameters are populated with data.
End include your parameter to procedure definition:
#myID BIGINT OUTPUT
USE [mammutRecruitment]
ALTER PROCEDURE [dbo].[Firststep] #Name NVARCHAR(max),
#Family NVARCHAR(max),
#FatherName NVARCHAR(max),
#BirthCertificate BIGINT,
#PlaceOfBirth NVARCHAR(max),
#BirthDate DATETIME,
#NationalCode BIGINT,
#Religion NVARCHAR(max),
#faith NVARCHAR(max),
#Nationality NVARCHAR(max),
#BloodGroup NVARCHAR(max),
#myID BIGINT output
AS
BEGIN
INSERT INTO [dbo].[usermainspecifications]
VALUES (#Name,
#Family,
#FatherName,
#BirthCertificate,
#PlaceOfBirth,
1,
#BirthDate,
#NationalCode,
#Religion,
#faith,
#Nationality,
#BloodGroup,
12,
'123',
'123',
1,
2015 - 1 - 1,
'12',
'123',
'1234',
1)
SELECT #myID = [userid]
FROM [mammutRecruitment].[dbo].[usermainspecifications]
WHERE [nationalcode] = #NationalCode
END

How do I get the return value from a scalar stored procedure in ASP C#?

I have a stored procedure and I want it to return a sum of a column of values. When I use the SqlCommand, I add the parameter enrollmentId. When I try to run my code in Visual Studio, it says I have to provide the parameter #totalEarned... my problem is that is what I am using the SP to determine... it is supposed to output #totalEarned. How do I use this SP without providing #totalEarned?
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[totalEarned]
#enrollmentId Int,
#totalEarned int OUTPUT
AS
BEGIN
SELECT #totalEarned = SUM(pointsEarned)
FROM Assignments
WHERE enrollmentId = #enrollmentId
RETURN
END
Here's the C# code:
string connstring;
connstring = ConfigurationManager.ConnectionStrings["dbConn"].ConnectionString;
SqlConnection conn = new SqlConnection(connstring);
SqlCommand cmd = new SqlCommand("dbo.totalEarned", conn);
cmd.Parameters.Add(new SqlParameter("#enrollmentId", enrollmentId));
cmd.Parameters.Add(new SqlParameter("#totalEarned", null));
cmd.CommandType = System.Data.CommandType.StoredProcedure;
using (conn)
{
conn.Open();
double totalEarned = (double)cmd.ExecuteScalar();
}
You'd have to specify Direction. Replace cmd.Parameters.Add(new SqlParameter("#totalEarned", null)); with:
SqlParameter totalEarned= new SqlParameter("#totalEarned", SqlDbType.Int);
totalEarned.Direction = ParameterDirection.Output;
cmd.Parameters.Add(totalEarned);
Then after executing command, cast it to int to get the value:
int value = (int)totalEarned.Value;
When you construct the SqlParameter set its Direction property to Output.
Alternatively, simply SELECT SUM(pointsEarned) directly.

INSERT EXEC from DbCommand

I'm trying to execute the results of a stored procedure that takes parameters into a temporary table.
// Create #temptable
// ..
using (DbCommand command = connection.CreateCommand())
{
command.CommandText = "INSERT #temptable EXEC [MystoredProcThatHasParams]";
command.CommandType = CommandType.StoredProcedure;
command.Parameters.Add(someObject)
command.ExecuteNonQuery();
}
Output:
Could not find stored procedure ''.
If I remove command.CommandType = CommandType.StoredProcedure, I get:
Procedure or function 'MystoredProcThatHasParams' expects parameter '#p1' which was not supplied
Is it possible to save the output of a stored procedure that takes parameters from a query in C#?
The command type StoredProcedure uses a special, higher-performance method for connecting to SQL Server (an RPC call), which requires that the command text be exactly the name of a stored procedure. You cannot include Transact-SQL in the command text if you want to use CommandType.StoredProcedure.
Instead, you need to use CommandType.Text and embed the parameters into the SQL string yourself:
cmd.CommandType = CommandType.Text;
cmd.CommandText = "INSERT #temptable EXEC [MystoredProcThatHasParams] #Param1, #Param2";
cmd.Parameters.Add("#Param1", SqlDbType.Int).Value = 1;
cmd.Parameters.Add("#Param2", SqlDbType.VarChar, 100).Value = "Test";

Procedure or function expects parameter which was not supplied, when parameter is auto-generated

I'm trying to insert data in my db. this is the code im using
SqlCommand cmd = new SqlCommand("dbo.UsersInsert", cnn);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add("#UserID", SqlDbType.Int);
cmd.Parameters.AddWithValue("#UserFirstName", FirstName.Text);
cmd.Parameters.AddWithValue("#UserMiddleName", MiddleName.Text);
cmd.Parameters.AddWithValue("#UserLastName", LastName.Text);
etc...
It is giving me error
Procedure or function 'UsersInsert' expects parameter '#UserID', which
was not supplied.
on cmd.ExecuteNonQuery(); line.
Here, My UserID is auto-generated in my Database. How do I resolve this?
Stored Procedure
#UserID INT OUTPUT,
#UserFirstName VARCHAR (50),
#UserMiddleName VARCHAR (50),
#UserLastName VARCHAR (50), etc...
AS
SET NOCOUNT ON
DECLARE #ReturnValue int
BEGIN
SELECT #ReturnValue = 0
INSERT [Users]
(
[UserFirstName]
,[UserMiddleName]
,[UserLastName] etc...
values (
#UserFirstName,
#UserMiddleName,
#UserLastName, etc.. )
IF (##Error <> 0) GOTO ERROR_HANDLER
GOTO OnExit
END
You should make it an ParameterDirection.Output
SqlParameter userIdParam = new SqlParameter("#UserID", SqlDbType.Int);
userIdParam.Direction = ParameterDirection.Output;
cmd.Parameters.Add(userIdParam);
This way you don't have to supply a value
The following code should work, change the sql to accept the parameters
SqlCommand cmd = new SqlCommand("dbo.UsersInsert #UserID out, #UserFirstName, #UserMiddleName, #UserLastName", cnn);
Then change the parameters as follows
var id = new SqlParameter("UserID", System.Data.SqlDbType.Int);
id.Direction = System.Data.ParameterDirection.Output;
cmd.Parameters.Add(id);
cmd.Parameters.AddWithValue("UserFirstName", FirstName.Text);
cmd.Parameters.AddWithValue("UserMiddleName", MiddleName.Text);
cmd.Parameters.AddWithValue("UserLastName", LastName.Text);

Stored procedure with return value

I have a stored procedure that goes like this:
ALTER PROCEDURE [dbo].[AuthenticateUser]
#AzUserName varchar(20),
#Hash varchar(32),
#UserId bigint output,
#Authorized bit output
...
and runs just fine fine in Management Studio.
Here's my C# code:
SqlConnection scon = new SqlConnection(connectionString);
SqlCommand authCmd = new SqlCommand("AuthenticateUser", scon);
authCmd.CommandType = System.Data.CommandType.StoredProcedure;
SqlParameter userNameParam = authCmd.Parameters.Add("#AzUserName", System.Data.SqlDbType.VarChar, 20);
userNameParam.Value = username;
string hashed = Md5Hash.ComputeHash(username);
SqlParameter hashedParam = authCmd.Parameters.Add("#Hash", System.Data.SqlDbType.VarChar, 32);
hashedParam.Value = hashed;
SqlParameter userIdParam = authCmd.Parameters.Add("#UserId", System.Data.SqlDbType.Int);
userIdParam.Direction = System.Data.ParameterDirection.ReturnValue;
SqlParameter authorizedParam = authCmd.Parameters.Add("#Authorized", System.Data.SqlDbType.Bit);
authorizedParam.Direction = System.Data.ParameterDirection.ReturnValue;
scon.Open();
authCmd.ExecuteNonQuery();
scon.Close();
When I run it I am getting the following error:
{"Procedure or function 'AuthenticateUser' expects parameter '#UserId', which was not supplied."} System.Exception {System.Data.SqlClient.SqlException}
When I replace ParameterDirection.ReturnValue with ParameterDirection.Output I am not getting the error but never get the value of the procedure.
UPDATE:
Thank you All for your help. The error was more trivial than you would have thought and I described in the question. I have been changing back and forth ReturnValue to Output for quite a while today with no result. Then I had to post my question on SO just to realize that I am taking the hash value of ... username..Going outdoor to get some oxygen now.
You will have to use ParameterDirection.Output on every parameter, that has been marked with output in T-SQL. You can access the values, after the call to
authCmd.ExecuteNonQuery();
by getting the values of the parametes like this:
authCmd.Parametes["#UserId"].Value
You're confusing the concepts of OUTPUT and RETURN values.
A RETURN value from a stored procedure is a single integer value per stored procedure that is defined within your proc by using the RETURN statement eg
RETURN 1
A stored procedure can have zero to many parameters of which zero to many can be defined as OUTPUT.
In your case you're not showing any use of the RETURN statement but you are using OUTPUT parameters. In SQL Server these are more like input/output parameters and you need to provide a value.
You can access the resulting value of an OUTPUT parameter by looking at the parameters collection after calling the stored procedure and look at the value eg
authCmd.Parameters[2].Value
Or
userIdParam.Value
As per other answers, you need to use the output parameter direction to achieve this
You can access the values of authorizedParam.Value and userIdParam.Value after executing the command.
SqlConnection scon = new SqlConnection(connectionString);
SqlCommand authCmd = new SqlCommand("AuthenticateUser", scon);
authCmd.CommandType = System.Data.CommandType.StoredProcedure;
SqlParameter userNameParam = authCmd.Parameters.Add("#AzUserName", System.Data.SqlDbType.VarChar, 20);
userNameParam.Value = username;
string hashed = Zonal.Pie.Core.Common.Utils.Md5Hash.ComputeHash(username);
SqlParameter hashedParam = authCmd.Parameters.Add("#Hash", System.Data.SqlDbType.VarChar, 32);
hashedParam.Value = hashed;
SqlParameter userIdParam = authCmd.Parameters.Add("#UserId", System.Data.SqlDbType.Int);
userIdParam.Direction = System.Data.ParameterDirection.Output;
SqlParameter authorizedParam = authCmd.Parameters.Add("#Authorized", System.Data.SqlDbType.Bit);
authorizedParam.Direction = System.Data.ParameterDirection.Output;
scon.Open();
authCmd.ExecuteNonQuery();
//Access authorizedParam.Value and userIdParam.Value here
scon.Close();

Categories