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
Related
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");
}
I have a stored procedure named 'sp_AddDevice' which accepts the following variables:
#DeviceID AS NVARCHAR(8),
#Device_location AS NVARCHAR(40),
#Device_asset AS NVARCHAR(7),
#Device_name AS NVARCHAR(50),
#Device_manuf AS NVARCHAR(25),
#Device_model AS NVARCHAR(20),
#Device_serial AS NVARCHAR(40),
#Device_other AS NVARCHAR(20),
#Device_status AS SMALLINT,
#Device_type AS SMALLINT,
#EnteredBy AS VARCHAR(50),
#ChangedBy AS VARCHAR(50),
#errStatusOK INT OUTPUT
What bothers me is the Variable '#errStatusOK INT OUTPUT'
I am calling the stored procedure like this but I receive the error that the variable '#errStatusOK' is not supplied:
SqlCommand command = new SqlCommand(#"BCS_Verify.dbo.sp_AddDevice", con);
command.CommandType = CommandType.StoredProcedure;
command.Parameters.Add("#DeviceID", SqlDbType.NVarChar, 8).Value = deviceID;
command.Parameters.Add("#Device_location", SqlDbType.NVarChar, 40).Value = location;
command.Parameters.Add("#Device_asset", SqlDbType.NVarChar, 7).Value = deviceID.ToLower().TrimStart('b','c','s');
command.Parameters.Add("#Device_name", SqlDbType.NVarChar, 50).Value = type;
command.Parameters.Add("#Device_manuf", SqlDbType.NVarChar, 25).Value = brand;
command.Parameters.Add("#Device_model", SqlDbType.NVarChar, 20).Value = model;
command.Parameters.Add("#Device_serial", SqlDbType.NVarChar, 40).Value = serial;
command.Parameters.Add("#Device_other", SqlDbType.NVarChar, 20).Value = "N/A";
command.Parameters.Add("#Device_status", SqlDbType.SmallInt).Value = status;
command.Parameters.Add("#Device_type", SqlDbType.SmallInt).Value = 0;
command.Parameters.Add("#EnteredBy", SqlDbType.NVarChar, 50).Value = GlobalVar.Default.Username;
command.Parameters.Add("#ChangedBy", SqlDbType.NVarChar, 50).Value = GlobalVar.Default.Username;
var returnParameter = command.Parameters.Add("#errStatusOK", SqlDbType.Int);
returnParameter.Direction = ParameterDirection.ReturnValue;
command.ExecuteNonQuery();
if (returnParameter.SqlValue.ToString() == "1") return true;
else return false;
do I have to define the return variable differently or what might be the issue?
I use something like this:
command.Parameters.Add("#errStatusOK", SqlDbType.Int).Direction =
ParameterDirection.Output;
Then after execution of the query...
command.ExecuteNonQuery();
int iRetVal = Convert.ToInt32(commad.Parameters["#errStatusOK"].Value);
Try this, maybe it's enough to change parameter direction from result to output:
SqlParameter errStatusOK = new SqlParameter
{
ParameterName = "#errStatusOK",
IsNullable = false,
Direction = ParameterDirection.Output,
SqlDbType = SqlDbType.Int,
Value = 0,
};
command.Parameters.Add(errStatusOK);
command.ExecuteNonQuery();
int returnValue = (int)commad.Parameters["#errStatusOK"].Value;
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
I have been trying to make the build in stored procedure to work with Register.aspx. I'm not using the wizard part. Hence writing my own code. I don't understand where the error is. If I use exec stored procedure and send the same value it will execute in Management Studio. But in code it fails.
Here is the code that does the execution of the stored procedure:
using (SqlConnection myConnection = new SqlConnection (ConfigurationManager.ConnectionStrings["connection"].ToString()))
{
using (SqlCommand insertNewUsers = new SqlCommand("aspnet_Membership_CreateUser", myConnection))
{
insertNewUsers.CommandType = CommandType.StoredProcedure;
insertNewUsers.Parameters.Add("#ApplicationName", SqlDbType.NVarChar, 256).Value = AppName;
insertNewUsers.Parameters.Add("#UserName", SqlDbType.NVarChar, 256).Value = UserName.Text;
insertNewUsers.Parameters.Add("#Password ", SqlDbType.NVarChar, 128).Value = goHashPassword;
insertNewUsers.Parameters.Add("#PasswordSalt", SqlDbType.NVarChar, 128).Value = newSalt;
insertNewUsers.Parameters.Add("#Email", SqlDbType.NVarChar, 256).Value = Email.Text;
// insertNewUsers.Parameters.Add(("#LoweredEmail"), SqlDbType.NVarChar, 256).Value = (Email.Text).ToLower();
insertNewUsers.Parameters.Add("#PasswordQuestion", SqlDbType.NVarChar, 256).Value = DBNull.Value ;
insertNewUsers.Parameters.Add("#PasswordAnswer", SqlDbType.NVarChar, 128).Value = DBNull.Value;
insertNewUsers.Parameters.Add("#IsApproved", SqlDbType.Bit).Value = 1;
// insertNewUsers.Parameters.Add("#IsLockedOut", SqlDbType.NVarChar, 1).Value = 0;
insertNewUsers.Parameters.Add("#CurrentTimeUtc", SqlDbType.DateTime).Value = DateTime.UtcNow.Date;
insertNewUsers.Parameters.Add("#CreateDate", SqlDbType.DateTime).Value = DateTime.Today.ToLocalTime();
insertNewUsers.Parameters.Add("#UniqueEmail", SqlDbType.Int).Value = 0;
insertNewUsers.Parameters.Add("#PasswordFormat", SqlDbType.Int).Value = 0;
pID = insertNewUsers.Parameters.Add("#return_value", SqlDbType.Int);
pID.Direction = ParameterDirection.ReturnValue;
try
{
if (insertNewUsers.Connection.State == ConnectionState.Closed)
{
insertNewUsers.Connection.Open();
}
insertNewUsers.ExecuteNonQuery(); // HERE IS WHERE IT FAILS
rowCount = (Int32)insertNewUsers.Parameters["#return_value"].Value;
} // END TRY
catch (Exception ex)
{
ErrorMessage.Text = ex.StackTrace.ToString();
}
finally
{
myConnection.Dispose();
}
}
}
Now if I run build in stored procedure with following parameters it runs and adds a user and creates a membership
DECLARE #return_value int,
#UserId uniqueidentifier
EXEC #return_value = [dbo].[aspnet_Membership_CreateUser]
#ApplicationName = N'/',
#UserName = N'Tester',
#Password = N'cUW3NXKEEjiNkxOjhLXwhHFQApQ=',
#PasswordSalt = N'GYkMYFzkDn0vm4Li',
#Email = N'Tester#gmail.com',
#PasswordQuestion = NULL,
#PasswordAnswer = NULL,
#IsApproved = 1,
#CurrentTimeUtc = N'20131027',
#CreateDate = N'20131027' ,
#UniqueEmail = 0,
#PasswordFormat = 0,
#UserId = #UserId OUTPUT
SELECT #UserId as N'#UserId'
SELECT 'Return Value' = #return_value
GO
I have checked datatype with the table and is fine. I'm not sure about the datetime stamp. on manual execution, i just have to give the 'yyyymmdd' like i have specified but in c# i have specified to be as seen in code. Hope to find some help on this
~Technically, you're missing a parameter in the DotNet code.
(outputUserIdParam seen below)
~Practically, you should use the MembershipProvider API. You are re-inventing the wheel with your implementation.
insertNewUsers.CommandType = CommandType.StoredProcedure;
insertNewUsers.Parameters.Add("#ApplicationName", SqlDbType.NVarChar, 256).Value = AppName;
insertNewUsers.Parameters.Add("#UserName", SqlDbType.NVarChar, 256).Value = UserName;
insertNewUsers.Parameters.Add("#Password ", SqlDbType.NVarChar, 128).Value = pwd;
insertNewUsers.Parameters.Add("#PasswordSalt", SqlDbType.NVarChar, 128).Value = string.Empty;
insertNewUsers.Parameters.Add("#Email", SqlDbType.NVarChar, 256).Value = Email;
// insertNewUsers.Parameters.Add(("#LoweredEmail"), SqlDbType.NVarChar, 256).Value = (Email.Text).ToLower();
insertNewUsers.Parameters.Add("#PasswordQuestion", SqlDbType.NVarChar, 256).Value = DBNull.Value;
insertNewUsers.Parameters.Add("#PasswordAnswer", SqlDbType.NVarChar, 128).Value = DBNull.Value;
insertNewUsers.Parameters.Add("#IsApproved", SqlDbType.Bit).Value = 1;
// insertNewUsers.Parameters.Add("#IsLockedOut", SqlDbType.NVarChar, 1).Value = 0;
insertNewUsers.Parameters.Add("#CurrentTimeUtc", SqlDbType.DateTime).Value = DateTime.UtcNow.Date;
insertNewUsers.Parameters.Add("#CreateDate", SqlDbType.DateTime).Value = DateTime.Today.ToLocalTime();
insertNewUsers.Parameters.Add("#UniqueEmail", SqlDbType.Int).Value = 0;
insertNewUsers.Parameters.Add("#PasswordFormat", SqlDbType.Int).Value = 0;
// Create parameter with Direction as Output (and correct name and type)
SqlParameter outputUserIdParam = new SqlParameter("#UserId", SqlDbType.UniqueIdentifier)
{
Direction = ParameterDirection.Output
};
insertNewUsers.Parameters.Add(outputUserIdParam);
pID = insertNewUsers.Parameters.Add("#return_value", SqlDbType.Int);
pID.Direction = ParameterDirection.ReturnValue;
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.