ExecutenonQuery not working - c#

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.

Related

A SqlParameter with parameter name '#name' is not contained by this SqlParameterCollection function

I am trying to return a value from the code below but I am getting an error that says:
A SqlParameter with parameter name '#vRESULT' is not contained by this SqlParameterCollection
c# Code:
public int userLogin()
{
string connStr = ConfigurationManager.ConnectionStrings["conn"].ToString();
string cmdStr = #"fucn_LOg";
using (SqlConnection conn = new SqlConnection(connStr))
using (SqlCommand cmd = new SqlCommand(cmdStr, conn))
{
try
{
conn.Open();
cmd.CommandText = cmdStr;
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Clear();
cmd.Parameters[":vResult"].Direction = ParameterDirection.Output;
cmd.Parameters.Add(new SqlParameter("param1", SqlDbType.VarChar)).Value = TB_1.Text;
cmd.Parameters.Add(new SqlParameter("param2", SqlDbType.VarChar)).Value = TB_2.Text;
cmd.ExecuteScalar();
return Int32.Parse(cmd.Parameters[":vResult"].Value.ToString());
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
return -1;
}
}
}
the sql server function code below with returning parameter DECLARE #vResult int
CREATE FUNCTION USER_LOGIN(#USER_NAME VARCHAR(60),
#PWD VARCHAR(60))
RETURNS INT
AS BEGIN
DECLARE #vResult int
SELECT #vRESULT=COUNT(*)
FROM OPER
WHERE UPPER(UNAM)=UPPER(#USER_NAME)
AND PSW=#PWD
IF #vResult=1
SET #vResult=1
ELSE
SET #vResult= -1
RETURN #vResult
END
Just Get result from Stroed Procedure like this:
var result = cmd.ExecuteScalar();
return Int32.Parse(result.ToString());
This gets first and Only result from Stored Procedure.
Also recommend simplify your code Like this:
public int userLogin() {
string connStr = ConfigurationManager.ConnectionStrings["conn"].ToString();
using (SqlConnection conn = new SqlConnection(connStr))
using (SqlCommand cmd = new SqlCommand("fucn_LOg", conn)) {
try {
cmd.Connection.Open();
cmd.CommandType = System.Data.CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("#param1", TB_1.Text);
cmd.Parameters.AddWithValue("#param2", TB_2.Text);
var result = cmd.ExecuteScalar();
return Int32.Parse(result.ToString());
}
catch (Exception ex) {
MessageBox.Show(ex.ToString());
return -1;
}
finally {
if (cmd.Connection.State != ConnectionState.Closed) cmd.Connection.Close();
}
}
}
And your Stored procedure should looks Like this:
CREATE PROCEDURE fucn_LOg
(
#param1 nvarchar(max),
#param2 nvarchar(max)
)
AS
BEGIN
SET NOCOUNT ON;
if (exists(select * from tbUsers where flLogin = #param1 and flPassword = #param2))
begin
return 1;
end
else
begin
return 0;
end
END
GO
OR
CREATE PROCEDURE fucn_LOg
(
#param1 nvarchar(max),
#param2 nvarchar(max)
)
AS
BEGIN
SET NOCOUNT ON;
select COUNT(*) from tbUsers where flLogin = #param1 and flPassword = #param2
END
GO
Several problems.
First, you don't need the cmd.Parameters.Clear();, as you just establish a new cmd.
Second, use # for SQL Server parameters.
Third, a parameter named vResult is not set, so cmd.Parameters[":vResult"].Direction is invalid. You need to assign its type and value. Make sure your stored procedure has this parameter set with correct SQL data type.
Lastly, I guess you return the vResult in your stored procedure like select #vResult; so make it a new vResult = function(vResult). But no, it is not how SQL Server work. It won't change your input parameter even though you return your #vResult. While, ExecuteScaler does. So, simply get your result back by var result = cmd.ExecuteScalar();.
You are getting data from a stored procedure, not getting back the parameter you sent. That's the supposed correct way.
conn.Open();
cmd.CommandText = cmdStr;
cmd.CommandType = CommandType.StoredProcedure;
//Base on sql you provided, it is no need for this part.
/*
SqlParameter vResult = new SqlParameter();
vResult.ParameterName = "#vResult";
vResult.Direction = ParameterDirection.Output;
vResult.SqlDbType = System.Data.SqlDbType.???;
vResult.Value = ???;
cmd.Parameters.Add(vResult);
*/
cmd.Parameters.Add("#param1", SqlDbType.VarChar).Value = TB_1.Text;
cmd.Parameters.Add("#param2", SqlDbType.VarChar).Value = TB_2.Text;
var result = cmd.ExecuteScalar();
return Int32.Parse(result.ToString());
This is hard to debug without the SP, but a couple of things jump out.
First, you need to use the '#' character as a prefix for your parameter names, not a colon.
Second, you should define your output parameter like this:
SqlParameter outputParam = new SqlParameter("#vResult", SqlDbType.Int);
outputParam.Direction = ParameterDirection.Output;
cmd.Parameters.Add(outputParam);

How To Get Set Value From Stored procedure in C#

I have a stored procedure that client provided me
Like:
ALTER Proc [dbo].[XYZ]
#Parameter varchar(100),
#Parameter1 nvarchar(4000) out
SET #APIString = "Test Test"
I have no rights to change this procedure.
When I execute procedure through C# I get a blank string from procedure
How to get the #Parameter1 value in my project?
C# Code:
SqlCommand cmd = new SqlCommand("dbo.XYZ", conn);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("#Parameter", Parameter);
cmd.Parameters.Add("#Parameter1", SqlDbType.VarChar,4000);
cmd.Parameters["#Parameter1"].Direction = ParameterDirection.Output;
conn.Open();
SqlDataReader reader = cmd.ExecuteReader();
while (reader.Read())
{
String = reader["#Parameter1"] != null ? reader["#Parameter1"].ToString() : "";
}
conn.Close();
#Parameter1 is an output parameter. You can get its value the same way you set the values for input parameters, e.g.
var cmd = new SqlCommand("dbo.XYZ", con);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("#Parameter", inputValue);
// add the output parameter
cmd.Parameters.Add("#Parameter1", SqlDbType.NVarChar).Direction =
ParameterDirection.Output;
cmd.ExecuteNonQuery();
string parameter1 = (string)cmd.Parameters["#Parameter1"].Value;
You should also use ExecuteNonQuery unless the store procedure returns values with a select statement.

SqlCommand.ExecuteReader returns no rows using Stored Proc with output parameters

I have a stored procedure that accepts an input and returns multiple columns. The stored procedure works when I execute it from SSMS and also inside of VS 2013. However when I try and execute it using SqlCommand.ExecuteReader the reader doesn't have any rows in it. If I remove the output parameters from the proc and from the SqlCommand, while still keeping the one input parameter, I am able to return the row that I am looking for.
Here is the stored proc
create Proc sp_ReturnSingleGame
#GameName varchar(100) output,
#PlatformName varchar(50) output,
#ConditionShortDescription varchar(30) output,
#RetailCost decimal(6,2) output,
#InStock bit output,
#GameID int
AS
select #GameName = GameName, #PlatformName = PlatformName,
#ConditionShortDescription = ConditionShortDescription, #RetailCost = RetailCost
from Games inner join Condition
on Games.ConditionID = Condition.ConditionID
inner join ConsolePlatform
on Games.PlatformID = ConsolePlatform.PlatformID
Where Games.GameID = #GameID
if exists (select GameID
From SaleItemized
Where GameID = #GameID)
Begin
set #InStock = 1;
end
else
Begin
set #InStock = 0;
end
Here is my C# code
public Game ReturnSingleGame(int gameId)
{
SqlConnection connection = new SqlConnection(#"server=mylaptop; integrated security=true; database=GameStoreDB;");
SqlCommand command = this.ReturnCommandForSp_ReturnSingleGame(connection, gameId);
try
{
connection.Open();
SqlDataReader reader = command.ExecuteReader();
if (reader.HasRows == true)
{
reader.Read();
game.GameId = gameId;
game.GameName = reader["GameName"].ToString();
game.PlatformName = reader["PlatformName"].ToString();
game.RetailCost = (decimal) reader["RetailCost"];
}
else
{
var exception = new ApplicationException("Game was not found");
throw exception;
}
}
catch (Exception)
{
throw;
}
finally
{
connection.Close();
}
return game;
}
private SqlCommand CommandForSp_ReturnSingleGame(SqlConnection connection, int gameId)
{
string storedProc = #"dbo.sp_ReturnSingleGame";
SqlCommand command = new SqlCommand(storedProc, connection);
command.CommandType = CommandType.StoredProcedure;
command.Parameters.Add("#GameName", SqlDbType.VarChar, 100, "GameName");
command.Parameters["#GameName"].Direction = ParameterDirection.Output;
command.Parameters.Add("#PlatformName", SqlDbType.VarChar, 50, "PlatformName");
command.Parameters["#PlatformName"].Direction = ParameterDirection.Output;
command.Parameters.Add("#ConditionShortDescription", SqlDbType.VarChar, 30, "ConditionShortDescription");
command.Parameters["#ConditionShortDescription"].Direction = ParameterDirection.Output;
command.Parameters.Add("#RetailCost", SqlDbType.Decimal);
command.Parameters["#RetailCost"].SourceColumn = "RetailCost";
command.Parameters["#RetailCost"].Precision = 6;
command.Parameters["#RetailCost"].Scale = 2;
command.Parameters["#RetailCost"].Direction = ParameterDirection.Output;
command.Parameters.Add("#InStock", SqlDbType.Bit);
command.Parameters["#InStock"].SourceColumn = "InStock";
command.Parameters["#InStock"].Direction = ParameterDirection.Output;
command.Parameters.Add("#GameID", SqlDbType.Int).Value = gameId;
command.Parameters["#GameID"].SourceColumn = "GameID";
command.Parameters["#GameID"].Direction = ParameterDirection.Input;
command.Prepare();
return command;
}
Stored procedure provided by you actually doesn't return any rows of data.
All it does - is just set output parameters.
So you don't need any SqlDataReader to retrieve there parameters.
Just call command.ExecuteNonQuery() and then get your parameters values from command.Parameters["#GameName"].Value and so on.
Agree with Andy.
For you snippet from one of my project is:`
DbCommand Cmd = null;
using (DataClient client = new DataClient())
{
SqlParameter[] parameters = new SqlParameter[2];
parameters[0] = new SqlParameter("#ID", SqlDbType.VarChar);
parameters[0].Size = 10;
parameters[0].Direction = ParameterDirection.Output;
parameters[1] = new SqlParameter("#YourParameterName", SqlDbType.VarChar);
parameters[1].Value = Class.PropertyName;
parameters[2] = new SqlParameter("#Year", SqlDbType.Int);
client.ExecuteNonQuery("ReturnCommandForSp_ReturnSingleGame", CommandType.StoredProcedure, parameters, ref Cmd);
Then retrieve it like this
int yourReturnValue= Convert.ToInt32(Cmd.Parameters["#ID"].Value);
}
Hope it helps.

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

Categories

Resources