C# update stored procedure not making changes to database - c#

I have looked at similar topics with no luck, it looks (to me) like im doing things correctly but the database is just not being updated.
My function, as below, has the parameter values of 1, "Connor Smith", 5, "New" respectively
[HttpPost, ValidateAntiForgeryToken]
public ActionResult UpdateDevelopmentRequest(int changeID, string evaluator, int priority, string status)
{
SqlCommand cmd = new SqlCommand(StoredProcedures.DevRequests.UpdateDevRequest, Conn);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add("#changeID", SqlDbType.Int).Value = changeID;
cmd.Parameters.Add("#evaluator", SqlDbType.NVarChar, 30).Value = evaluator;
cmd.Parameters.Add("#priority", SqlDbType.Int).Value = priority;
cmd.Parameters.Add("#status", SqlDbType.NVarChar, 15).Value = status;
//cmd.Parameters.AddWithValue("#changeID", changeID);
//cmd.Parameters.AddWithValue("#evaluator", evaluator);
//cmd.Parameters.AddWithValue("#priority", priority);
//cmd.Parameters.AddWithValue("#status", status);
Conn.Open();
cmd.ExecuteNonQuery();
Conn.Close();
return RedirectToAction("DevelopmentRequests");
}
My stored procedure is as below
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[sp_UpdateDevRequests]
#changeID INT,
#evaluator NVARCHAR(30),
#priority INT,
#status NVARCHAR(15)
AS
UPDATE it_ChangeRequest
SET it_ChangeRequest.Evaluator = #evaluator,
it_ChangeRequest.Status = #status,
it_ChangeRequest.Priority = #priority
WHERE ChangeID = #changeID
Aside from the code and stored procedure as shown, I have tried to add
int result = cmd.ExecuteNonQuery();
which returned a 1 when values were correct and a 0 when they were incorrect (I am only expecting 1 row to be changed). I have also ran the query separately, hardcoding the values in e.g Declare #changeID int = 1 and the query worked fine with this method too.
I have been stumped on this all morning and would appreciate some help
e: I also tried setting the stored procedure to just priority = 2 instead of priority = #priority to ensure it was pointed and updating the expected DB and all worked as expected when doing that

Please try changing your POST action as below by specifying ParameterDirection:
[HttpPost, ValidateAntiForgeryToken]
public ActionResult UpdateDevelopmentRequest(int changeID, string evaluator, int priority, string status)
{
using (var conn = new SqlConnection(<your_connection_string_goes_here>))
using (SqlCommand cmd = new SqlCommand(StoredProcedures.DevRequests.UpdateDevRequest, Conn))
{
cmd.CommandType = CommandType.StoredProcedure;
/*
cmd.Parameters.Add("#changeID", SqlDbType.Int).Value = changeID;
cmd.Parameters.Add("#evaluator", SqlDbType.NVarChar, 30).Value = evaluator;
cmd.Parameters.Add("#priority", SqlDbType.Int).Value = priority;
cmd.Parameters.Add("#status", SqlDbType.NVarChar, 15).Value = status;
*/
var param1 = cmd.Parameters.AddWithValue("#changeID", changeID);
cmd.Parameters["#changeID"].Direction = ParameterDirection.Input
param1.SqlDbType = SqlDbType.Int
var param2 = cmd.Parameters.AddWithValue("#evaluator", evaluator);
cmd.Parameters["#evaluator"].Direction = ParameterDirection.Input
param2.SqlDbType = SqlDbType.NVarChar
var param3 = cmd.Parameters.AddWithValue("#priority", priority);
cmd.Parameters["#priority"].Direction = ParameterDirection.Input
param3.SqlDbType = SqlDbType.Int
var param4 = cmd.Parameters.AddWithValue("#status", status);
cmd.Parameters["#status"].Direction = ParameterDirection.Input
param4.SqlDbType = SqlDbType.NVarChar
Conn.Open();
// If you want you can specify the Timeout as below
// cmd.CommandTimeout = 300;
cmd.ExecuteNonQuery();
Conn.Close();
}
return RedirectToAction("DevelopmentRequests");
}

Related

SQL Server stored procedure return value, and using it in C#

My application allows the user to add a new player to the database. Before adding a new player, I'd like for a stored procedure to check whether or not a player with the first name and last name exists. I want the stored procedure to return a bit value, 0 or 1. My C# method will then return this value and the program can decide whether or not to proceed with the creation.
Note that I've cut some of the general validation out of the code below, i.e. if the fields are empty, or the balance TextBox is invalid etc..
I'm also aware that I may be using the wrong datatype when handling the returned value. i.e. int instead of bool.
When I run this, I get an error saying that my SP requires an input parameter #ReturnedValue.
Cheers
Player newPlayer = new Player();
newPlayer.PlayerID = Guid.NewGuid();
newPlayer.FirstName = TextBoxFirstName.Text;
newPlayer.LastName = TextBoxLastName.Text;
newPlayer.Balance = Convert.ToDouble(TextBoxInitialCredit.Text);
var exists = newPlayer.CheckExists();
if (exists == 1)
{
newPlayer.AddPlayer();
}
and here's the method:
public int CheckExists()
{
SqlConnection myConnection = new SqlConnection(ConfigurationManager.ConnectionStrings["Badminton"].ConnectionString);
myConnection.Open();
SqlCommand SqlCmd = new SqlCommand("CheckPlayerExists", myConnection);
SqlCmd.CommandType = CommandType.StoredProcedure;
SqlCmd.Parameters.Add("#FirstName", SqlDbType.NVarChar, 50).Value = FirstName;
SqlCmd.Parameters.Add("#LastName", SqlDbType.NVarChar, 50).Value = LastName;
SqlCmd.Parameters.Add("#ReturnValue", SqlDbType.Int, 2).Direction = ParameterDirection.Output;
SqlDataAdapter myDataAdapter = new SqlDataAdapter(SqlCmd);
DataSet myDataSet = new DataSet();
myDataAdapter.Fill(myDataSet);
int exists = Convert.ToInt32(SqlCmd.Parameters["#ReturnValue"].Value);
myConnection.Close();
return exists;
}
and now my stored procedure:
CREATE PROCEDURE dbo.CheckPlayerExists
#firstName nvarchar(50),
#lastName nvarchar(50),
#ReturnValue bit output
AS
BEGIN
IF EXISTS (SELECT * FROM Players WHERE FirstName = #firstName AND LastName = #lastName)
SET #ReturnValue = 1
ELSE
SET #ReturnValue = 0
RETURN #ReturnValue
END
First, there's some inconsistency in your posted information. Is the parameter #ReturnValue or #ReturnedValue? That alone could be the problem.
Second, either change your stored procedures declaration of the #ReturnedValue parameter to
#ReturnValue bit = 0 output
or change the C# code that adds the output parameter:
SqlParameter p = new SqlParameter();
p.ParameterName = "#ReturnedValue";
p.SqlDbType = SqlDbType.Int;
p.Value = 0;
p.Direction = ParameterDirection.InputOutput;
SqlCmd.Parameters.Add(p);
Problem : You are assigning the ParameterDirection Enum value as Output.
Solution : Change your ParameterDirection Enum value from Output to ReturnValue
ReturnValue: ParameterDirection.ReturnValue
The parameter represents a return value from an operation such as a
stored procedure, built-in function, or user-defined function.
Replace This:
SqlCmd.Parameters.Add("#ReturnValue", SqlDbType.Int, 2).Direction
= ParameterDirection.Output;
With This:
SqlCmd.Parameters.Add("#ReturnValue", SqlDbType.Int, 2).Direction
= ParameterDirection.ReturnValue;
I think I see your issues. In the line:
SqlCmd.Parameters.Add("#ReturnValue", SqlDbType.Int, 2).Direction = ParameterDirection.Output;
change name and direction type to:
SqlCmd.Parameters.Add("#ReturnedValue", SqlDbType.Int, 2).Direction = ParameterDirection.ReturnValue;

How to get return value from stored procedure

I have the following stored procedure:
ALTER PROCEDURE spLogin
#CAD_WEB_LOGIN_USERNAME varchar(60),
#CAD_WEB_LOGIN_PASSWORD varchar(60),
#Result int output
AS
BEGIN
SELECT
CAD_NUMBER
FROM
CMACADDR
WHERE
CAD_WEB_LOGIN_USERNAME = #CAD_WEB_LOGIN_USERNAME
AND CAD_WEB_LOGIN_PASSWORD = #CAD_WEB_LOGIN_PASSWORD
END
In C#, I want to execute this query and get the return value.
This is my code:
int flag = 0;
con.Open();
SqlCommand cmd3 = new SqlCommand("spLogin", con);
cmd3.Connection = con;
cmd3.CommandType = CommandType.StoredProcedure;
cmd3.Parameters.Add("#CAD_WEB_LOGIN_USERNAME", SqlDbType.VarChar).Value = txtUserName.Text;
cmd3.Parameters.Add("#CAD_WEB_LOGIN_PASSWORD", SqlDbType.VarChar).Value = txtPassword.Text;
SqlParameter parm = new SqlParameter("#Return", SqlDbType.Int);
parm.Direction = ParameterDirection.ReturnValue;
cmd3.Parameters.Add(parm);
flag = cmd3.ExecuteNonQuery();
con.Close();
int id = Convert.ToInt32(parm.Value);
I get an error:
Procedure or function 'spLogin' expects parameter '#Result', which was not supplied.
What's the logic error with this code?
Thanks
Change the ParameterDirection to Output , and change the parameter name to #Result .
SqlParameter parm = new SqlParameter("#Result", SqlDbType.Int);
parm.Direction = ParameterDirection.Output;
cmd3.Parameters.Add(parm);
As error suggest 'spLogin' expects parameter '#Result'
Change
SqlParameter parm = new SqlParameter("#Return", SqlDbType.Int);
to
SqlParameter parm = new SqlParameter("#Result", SqlDbType.Int);
EDIT
Also updated your procedure, return some value. Currently you are not returning anything. Also you don't need to add an extra parameter in SP.
ALTER PROCEDURE Splogin #CAD_WEB_LOGIN_USERNAME VARCHAR(60),
#CAD_WEB_LOGIN_PASSWORD VARCHAR(60)
AS
BEGIN
Declare #MyResult as INT
SELECT #MyResult = cad_number
FROM cmacaddr
WHERE cad_web_login_username = #CAD_WEB_LOGIN_USERNAME
AND cad_web_login_password = #CAD_WEB_LOGIN_PASSWORD
RETURN #MyResult -- return value
END

Changing the ParameterDirection.Input to ParameterDirection.InputOutput

MemberChecker.CommandType = CommandType.StoredProcedure;
added
and Problem Solved!
---- Here was the funny question!
Why does my SqlCommand accessing a Stored Procedure work only when I use
ParameterDirection.InputOutput
and not
ParameterDirection.Output
An SqlParameter with ParameterName '#Customer' is not contained by this SqlParameterCollection
Here is some of my code:
using (SqlConnection H20_Connection = new SqlConnection(ConfigurationManager.ConnectionStrings["H20"].ConnectionString))
{
SqlCommand MemberChecker = new SqlCommand("execute custom_x_Check", H20_Connection);
MemberChecker.Parameters.Add("#TN", SqlDbType.VarChar,50).Value = TNH20.Text.Trim();
MemberChecker.Parameters.Add("#Customer_ID", SqlDbType.VarChar, 50).Value = TNH20.Text.Trim();
MemberChecker.Parameters.Add("#Customer", SqlDbType.VarChar, 100).Direction = ParameterDirection.Output;
MemberChecker.Parameters.Add("#Out_TN", SqlDbType.VarChar, 50).Direction = ParameterDirection.Output;
MemberChecker.Parameters.Add("#Out_Customer_ID", SqlDbType.VarChar, 50).Direction = ParameterDirection.Output;
H20_Connection.Open();
if (MemberChecker.ExecuteNonQuery() > 1)
{
Top.Visible = false;
Bottom.Visible = true;
}
else
{
Top.Visible = true;
Bottom.Visible = false;
}
}
and my SQL
alter proc custom_Check
#TN varchar(50) ='',
#Customer_ID varchar(50)='',
#Customer varchar(100) out,
#Out_TN varchar(50) out,
#Out_Customer_ID varchar(50) out
as
select #Out_Customer_ID=Customer_ID,
#Out_TN = MainTN,#Customer = Customer
from [vCustomerName]
where Customer_ID = #Customer_ID or #TN = MainTN
Thanks!
#Customer, #Out_TN, and #Out_Customer_ID should all use ParameterDirection.Output since they are out parameters in your SQL.
something like this:
MemberChecker.Parameters.Add("#Customer").Direction = ParameterDirection.Output;
MemberChecker.Parameters.Add("#Out_TN").Direction = ParameterDirection.Output;
MemberChecker.Parameters.Add("#Out_Customer_ID").Direction = ParameterDirection.Output;
Also be aware that your SQL will fail if more than one record meets your criteria:
where Customer_ID = #Customer_ID or #TN = MainTN
As you astutely noticed, you are calling the stored procedure with an execute statement which is incorrect in this case. Change the command to:
SqlCommand MemberChecker = new SqlCommand("custom_Check", H20_Connection);
MemberChecker.CommandType = CommandType.StoredProcedure;
MemberChecker.CommandType = CommandType.StoredProcedure

ExecutenonQuery not working

I have stored proc as below:
ALTER PROC pr_Update_Users_Nomination
(
#UserID AS VARCHAR(100),
#Nominated AS BIT
)
AS
UPDATE User
SET isNominated = #Nominated
WHERE
EMPID = #UserID;
I want to call this procedure from c# code: Below is the code I am trying:
void OpenConnection()
{
string Nominated = "False";
//Connection String
string sConnString = System.Configuration.ConfigurationManager.ConnectionStrings["ConString1"].ConnectionString;
SqlConnection mySqlCon = new SqlConnection(sConnString);
SqlCommand mySqlCom = mySqlCon.CreateCommand();
//Call the stored proc and provide in parameters
mySqlCom.CommandText = "EXECUTE pr_Update #UserID #Nominated";
mySqlCom.Parameters.Add("#UserID", SqlDbType.VarChar, 20).Value = UserID;
mySqlCom.Parameters.Add("#Nominated", SqlDbType.Bit).Value = Nominated;
mySqlCon.Open();
mySqlCom.ExecuteNonQuery();
mySqlCon.Close();
}
I get an error saying
Incorrect Syntax near #Nominated
first, when executing a procedure with parameter(s), separate the parameters with a comma
EXECUTE pr_Update #UserID, #Nominated
second, modify your code into this,
string sConnString = System.Configuration.ConfigurationManager.ConnectionStrings["ConString1"].ConnectionString;
using(SqlConnection mySqlCon = new SqlConnection(sConnString))
{
using(SqlCommand mySqlCom = new SqlCommand())
{
mySqlCom.Connection = mySqlCon;
mySqlCom.CommandText = "pr_Update";
mySqlCom.CommandType = CommandType.StoredProcedure;
mySqlCom.Parameters.Add("#UserID", SqlDbType.VarChar, 20).Value = UserID;
mySqlCom.Parameters.Add("#Nominated", SqlDbType.Bit).Value = Nominated;
try
{
mySqlCon.Open();
mySqlCom.ExecuteNonQuery();
}
catch(SqlException ex)
{
// do something with the exception
// don't hide it
}
}
}
You are missing a comma (,) between the parameters.
It should be
mySqlCom.CommandText = "EXECUTE pr_Update #UserID, #Nominated";
mySqlCom.Parameters.Add("#UserID", SqlDbType.VarChar, 20).Value = UserID;
mySqlCom.Parameters.Add("#Nominated", SqlDbType.Bit).Value = Nominated;
Alternatively, since all you are doing is calling a stored proc, you could do:
mySqlCom.CommandType = CommandType.StoredProcedure ;
mySqlCom.CommandText = "pr_Update"; //no need to specify parameter names
mySqlCom.Parameters.Add("#UserID", SqlDbType.VarChar, 20).Value = UserID;
mySqlCom.Parameters.Add("#Nominated", SqlDbType.Bit).Value = Nominated;
Give only name of stored procedure, as you are adding parameter in statements after this. Also set CommandType.
mySqlCom.CommandText = "pr_Update";
mySqlCom.CommandType = CommandType.StoredProcedure;
You are invoking wrong SQL. You should set the command text of command to pr_Update only:
mySqlCom.CommandText = "pr_Update";
And set type command type to stored procedure:
mySqlCom.CommandType = CommandType.StoredProcedure;
See MSDN page for more.

Adding more number of parameters to sqlparameter class

I have to call a stored procedure but i am having more number of parameters is there any simple way to do this? or simply adding every parameter to sqlparameter class?? like below
SqlCommand command = new SqlCommand("inserting", con);
command.CommandType = CommandType.StoredProcedure;
command.Parameters.Add(new SqlParameter("#Firstname", SqlDbType.NVarChar).Value = TextBox1.Text;
Be aware that Paramters.Add has an overload that takes in a string and a DbType, so you don't have to call the Parameter constructor. You could replace the line you are currently using to add a new parameter:
command.Parameters.Add(new SqlParameter("#Firstname", SqlDbType.NVarChar)).Value = TextBox1.Text;
with the following shorter (but functionally equivalent) line:
command.Parameters.Add("#Firstname", SqlDbType.NVarChar).Value = TextBox1.Text;
If you want to add more parameters, you would simply add them to the Parameters property of your command, like so:
SqlCommand command = new SqlCommand("inserting", con);
command.CommandType = CommandType.StoredProcedure;
command.Parameters.Add("#Firstname", SqlDbType.NVarChar).Value = TextBox1.Text;
command.Parameters.Add("#Lastname", SqlDbType.NVarChar).Value = TextBox2.Text;
Aside from that, have you tried using Parameters.AddWithValue? You can use this if the data type of your column maps to the type of your value in C#. You can find a mapping of C# to SQL Server data typse here.
You would use it like so:
// Assume your sproc has a parameter named #Age that is a SqlInt32 type
int age = 5;
// Since age is a C# int (Int32), AddWithValue will automatically set
// the DbType of our new paramter to SqlInt32.
command.Parameters.AddWithValue("#Age", 5);
If you need to specify the SqlDbType, AddWithValue returns the parameter you just added, so it's as simple as adding an extra statement to set the DbType property at the end, although at this point, you're better off just using the original .Add function and setting the value.
command.Parameters.AddWithValue("#Firstname", TextBox1.Text).DbType = SqlDbType.NVarChar;
Use Array of type SqlParameter and insert that into SqlCommand
SqlCommand Comm = new SqlCommand("Command text", new SqlConnection("Connection String");
SqlParameter[] param = {new SqlParameter("#Name","Value"),
new SqlParameter("#Name","Value"),
........
};
Comm.Parameters.AddRange(param);
Just call the command.Parameters.Add method multiple times:
SqlCommand command = new SqlCommand("inserting", con);
command.CommandType = CommandType.StoredProcedure;
command.Parameters.Add("#Firstname", SqlDbType.NVarChar, 100).Value = TextBox1.Text;
command.Parameters.Add("#Lastname", SqlDbType.NVarChar, 100).Value = TextBox2.Text;
command.Parameters.Add("#City", SqlDbType.NVarChar, 100).Value = TextBox3.Text;
command.Parameters.Add("#ID", SqlDbType.Int).Value = Convert.ToInt32(TextBox4.Text);
....... and so on .....
You may use like it
return new SqlParameter[]
{
new SqlParameter("#Firstname", SqlDbType.VarChar)
{
Value = Firstname.Text
},
new SqlParameter("#Lastname", SqlDbType.VarChar)
{
Value = Lastname.Text
},
};
You can use dapper-dot-net
sample code:
var dog = connection.Query<Dog>("select Age = #Age, Id = #Id", new { Age = (int?)null, Id = guid });
Insert example:
connection.Execute(#"insert MyTable(colA, colB) values (#a, #b)",
new[] { new { a=1, b=1 }, new { a=2, b=2 }, new { a=3, b=3 } }
).IsEqualTo(3); // 3 rows inserted: "1,1", "2,2" and "3,3"
The command.Parameters.Add is deprecated. Rather use command.Parameters.AddWithValue .
For this, you would call it many times for each parameter.
// Mention size of the nvarchar column , here i give 500 , you can use its length for #Firstname as you mention in database according to your database
SqlCommand command = new SqlCommand("inserting", con);
command.CommandType = CommandType.StoredProcedure;
command.Parameters.Add(new SqlParameter("#Firstname", SqlDbType.NVarChar,500).Value = TextBox1.Text;

Categories

Resources