Database is not updating after running stored procedure in asp app - c#

I have an asp app that should be able to let a user update an entry in a sql server database. When I run my stored procedure though in my method, nothing happens to the database.
public void updateFeature(Feature updatedFeature)
{
using (SqlConnection sqlConnection = new SqlConnection(GetConnectionString(updatedFeature.Environment)))
using (SqlCommand sqlCommand = sqlConnection.CreateCommand())
{
sqlCommand.CommandType = CommandType.StoredProcedure;
sqlCommand.CommandText = "usp_UpdateFeature";
sqlCommand.Parameters.AddWithValue("#FeatureName", updatedFeature.FeatureName);
sqlCommand.Parameters.AddWithValue("#FeatureID", updatedFeature.FeatureID);
sqlCommand.Parameters.AddWithValue("#FeatureDescription", updatedFeature.Description);
sqlCommand.Parameters.AddWithValue("#FieldName", updatedFeature.FieldName);
sqlCommand.Parameters.AddWithValue("#OnOffSwitch", updatedFeature.IsOn);
sqlCommand.Parameters.AddWithValue("#ChannelID", updatedFeature.ChannelID);
sqlCommand.Parameters.AddWithValue("#ProductID", updatedFeature.ProductID);
sqlConnection.Open();
int numberOfRowsChanged = sqlCommand.ExecuteNonQuery();
}
}
and my stored procedure looks like this
ALTER PROCEDURE [dbo].[usp_UpdateFeature]
(
#FeatureID int,
#FeatureName varchar(30),
#FeatureDescription varchar(200) = null,
#FieldName varchar(40),
#OnOffSwitch bit,
#ChannelID varchar(3),
#ProductID varchar(2)
)
AS
SET NOCOUNT ON
UPDATE FM_Feature
SET FeatureName = #FeatureName,
FeatureDescription = #FeatureDescription,
FieldName = #FieldName,
OnOffSwitch = #OnOffSwitch,
ProductID = #ProductID,
ChannelID = #ChannelID
WHERE FeatureID = #FeatureID
The numberOfRowsChanged parameter returns -1 but I do not get any exceptions or errors. Is there something that I am missing or not understanding?

I think that you need to open your connection before you create your command, i hope that will be helpful for you .
using (SqlConnection sqlConnection = new SqlConnection(GetConnectionString(updatedFeature.Environment))
sqlConnection.Open();
using (SqlCommand sqlCommand = sqlConnection.CreateCommand())
{
sqlCommand.CommandType = CommandType.StoredProcedure;
sqlCommand.CommandText = "usp_UpdateFeature";
sqlCommand.Parameters.AddWithValue("#FeatureName", updatedFeature.FeatureName);
sqlCommand.Parameters.AddWithValue("#FeatureID", updatedFeature.FeatureID);
sqlCommand.Parameters.AddWithValue("#FeatureDescription", updatedFeature.Description);
sqlCommand.Parameters.AddWithValue("#FieldName", updatedFeature.FieldName);
sqlCommand.Parameters.AddWithValue("#OnOffSwitch", updatedFeature.IsOn);
sqlCommand.Parameters.AddWithValue("#ChannelID", updatedFeature.ChannelID);
sqlCommand.Parameters.AddWithValue("#ProductID", updatedFeature.ProductID);
int numberOfRowsChanged = sqlCommand.ExecuteNonQuery();
}
enjoy it .

Related

How to get the return value of a stored procedure?

I have the following stored procedure and I want to obtain the value that it returns:
ALTER PROCEDURE [dbo].[ExistsItemID]
#ItemID uniqueidentifier
AS
BEGIN
IF (EXISTS (SELECT ItemID FROM Discounts WHERE ItemID = #ItemID))
BEGIN
RETURN 1
END
ELSE
BEGIN
RETURN 0
END
END
And in C# I have the following code:
using (SqlConnection sqlCon = new SqlConnection(scheduleConnection.ConnectionString))
{
sqlCon.Open();
SqlCommand sqlCmd = new SqlCommand("ExistsItemID", scheduleConnection);
sqlCmd.CommandType = CommandType.StoredProcedure;
sqlCmd.ExecuteScalar();
SqlParameter returno = new SqlParameter();
returno.Direction = ParameterDirection.ReturnValue;
int valor = returno.Value;
}
But it has not worked for me, how can I get the value of the stored procedure? First of all, thanks
You need to add the parameter to the command before executing it. Use the Add method on the Parameters collection.
using (SqlConnection sqlCon = new SqlConnection(scheduleConnection.ConnectionString))
{
sqlCon.Open();
SqlCommand sqlCmd = new SqlCommand("ExistsItemID", scheduleConnection);
sqlCmd.CommandType = CommandType.StoredProcedure;
SqlParameter returno = new SqlParameter();
returno.Direction = ParameterDirection.ReturnValue;
sqlCmd.Parameters.Add(returno);
sqlCmd.ExecuteScalar();
int valor = returno.Value;
}

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);

Web API to call the stored Procedure and return Result

I am creating a Web API that accepts two input parameter called ACC. Created a stored procedure to insert or update the Account table in the SQL server. Account table has just two fields AccountID nvarchar(50) (primaryKey) and Cnt int
CREATE PROCEDURE [dbo].[usp_InserUpadte]
#Account_TT AS Account_TT READONLY
AS
BEGIN
SET NOCOUNT ON;
BEGIN TRANSACTION;
MERGE dbo.[Account] prj
USING #Account_TT tt
ON prj.AccountID = tt.AccountID
WHEN MATCHED THEN UPDATE SET prj.Cnt = prj.Cnt+1
WHEN NOT MATCHED THEN INSERT (AccountID,Cnt)
VALUES (tt.AccountID, 1);
COMMIT TRANSACTION;
Now I tried to connect to the SQL server not sure how to how would I call the stored procedure into the ASP.NET Web API application and pass the Account ID in it to create or updadte the table
namespace WebService.Controllers
{
public class CreationController : ApiController
{
[HttpGet]
public HttpResponseMessage Get(string ACC)
{
string strcon = System.Configuration.ConfigurationManager.ConnectionStrings["DBConnection"].ConnectionString;
SqlConnection DbConnection = new SqlConnection(strcon);
I know we can call the query directly like
var strQuery = "SELECT * from ACCOUNT where ACC = :ACC"
But dont know how to call the above stored procedure and pass the Account Value. Any help is greatly appreciated.
Here is the complete working example.
Please have a look on it.
string strcon = ConfigurationManager.ConnectionStrings["DBConnection"].ConnectionString;
SqlConnection DbConnection = new SqlConnection(strcon);
DbConnection.Open();
SqlCommand command = new SqlCommand("[dbo].[usp_InserUpadte]", DbConnection);
command.CommandType = CommandType.StoredProcedure;
//create type table
DataTable table = new DataTable();
table.Columns.Add("AccountID", typeof(string));
table.Rows.Add(ACC);
SqlParameter parameter = command.Parameters.AddWithValue("#Account_TT", table);
parameter.SqlDbType = SqlDbType.Structured;
parameter.TypeName = "Account_TT";
command.ExecuteNonQuery();
DbConnection.Close();
To call a stored procedure you need to use a SqlCommand something like this:
string strcon = System.Configuration.ConfigurationManager.ConnectionStrings["DBConnection"].ConnectionString;
using (var connection = new SqlConnection(strcon)) {
using (var command = new SqlCommand("usp_InserUpadte", connection)) {
command.CommandType = CommandType.StoredProcedure;
command.Parameters.Add("#Account_TT ", SqlDbType.NVarChar).Value = ACC;
command.Open();
var reader = command.ExecuteReader();
// Handle return data here
}
}

SQL Output Inserted

I have two buttons on a page, one that logs a start time, and one that logs an end time.
The start time button performs an sql insert.
At that point i need to grab the primary key that's create. To do this i want to use the sql command (output inserted).
Then when the stop time is clicked,the row should be update with a stop time using the primary key from the start in the where clause.
I believe insert SQL is correct but i don't know how to pass the primary key to the next command.
Code dump, with what i have so far.
var command1 = "INSERT INTO [Time] ([Start Time], [Work Order]) OUTPUT INSERTED.PrimaryKey VALUES (#StartTime, #Work_Order)";
using (SqlConnection cnn1 = new SqlConnection(cnnString))
{
using (SqlCommand cmd1 = new SqlCommand(command1, cnn1))
{
cmd1.Parameters.AddWithValue("#StartTime", SqlDbType.DateTime).Value = System.DateTime.Now;
cmd1.Parameters.AddWithValue("#Work_Order", SqlDbType.Int).Value = e.CommandArgument;
cnn1.Open();
Label1.Text = cmd1.ExecuteScalar().ToString();
cnn1.Close();
}
}
var command = "UPDATE [Time] SET [Stop Time] = #StopTime WHERE [PrimaryKey] = #PrimaryKey";
using (SqlConnection cnn = new SqlConnection(cnnString))
{
using (SqlCommand cmd = new SqlCommand(command, cnn))
{
cmd.Parameters.AddWithValue("#StopTime", SqlDbType.DateTime).Value = System.DateTime.Now;
cmd.Parameters.AddWithValue("#PrimaryKey", *PrimaryKey from INSERT output*
cnn.Open();
cmd.ExecuteNonQuery();
}
}
instead of having it go to the label have it go to an int and then set the label text with the int. Then pass the int on the second part. Declare the int outside the scope of the using statements though or it will be disposed and you will get a null reference exception when you try and call it later.
Edit: To add, this would be better if you convert to stored procs and define the SqlParameter objects (you don't have them, you'll need them).
SqlParameter
int myPK;
var command1 = "INSERT INTO [Time] ([Start Time], [Work Order]) OUTPUT INSERTED.PrimaryKey VALUES (#StartTime, #Work_Order)";
using (SqlConnection cnn1 = new SqlConnection(cnnString))
{
using (SqlCommand cmd1 = new SqlCommand(command1, cnn1))
{
cmd1.Parameters.AddWithValue("#StartTime", SqlDbType.DateTime).Value = System.DateTime.Now;
cmd1.Parameters.AddWithValue("#Work_Order", SqlDbType.Int).Value = e.CommandArgument;
cnn1.Open();
myPk = Convert.ToInt32(cmd1.ExecuteScalar());
Label1.Text = myPk.ToString();
cnn1.Close();
}
}
var command = "UPDATE [Time] SET [Stop Time] = #StopTime WHERE [PrimaryKey] = #PrimaryKey";
using (SqlConnection cnn = new SqlConnection(cnnString))
{
using (SqlCommand cmd = new SqlCommand(command, cnn))
{
cmd.Parameters.AddWithValue("#StopTime", SqlDbType.DateTime).Value = System.DateTime.Now;
cmd.Parameters.AddWithValue("#PrimaryKey", myPK);
FindControl("Work_OrderLabel"); ;
cnn.Open();
cmd.ExecuteNonQuery();
}
}

C# guid and SQL uniqueidentifier

I want to create a GUID and store it in the DB.
In C# a guid can be created using Guid.NewGuid(). This creates a 128 bit integer. SQL Server has a uniqueidentifier column which holds a huge hexidecimal number.
Is there a good/preferred way to make C# and SQL Server guids play well together? (i.e. create a guid using Guid.New() and then store it in the database using nvarchar or some other field ... or create some hexidecimal number of the form that SQL Server is expecting by some other means)
Here's a code snippet showing how to insert a GUID using a parameterised query:
using(SqlConnection conn = new SqlConnection(connectionString))
{
conn.Open();
using(SqlTransaction trans = conn.BeginTransaction())
using (SqlCommand cmd = conn.CreateCommand())
{
cmd.Transaction = trans;
cmd.CommandText = #"INSERT INTO [MYTABLE] ([GuidValue]) VALUE #guidValue;";
cmd.Parameters.AddWithValue("#guidValue", Guid.NewGuid());
cmd.ExecuteNonQuery();
trans.Commit();
}
}
SQL is expecting the GUID as a string. The following in C# returns a string Sql is expecting.
"'" + Guid.NewGuid().ToString() + "'"
Something like
INSERT INTO TABLE (GuidID) VALUE ('4b5e95a7-745a-462f-ae53-709a8583700a')
is what it should look like in SQL.
You can pass a C# Guid value directly to a SQL Stored Procedure by specifying SqlDbType.UniqueIdentifier.
Your method may look like this (provided that your only parameter is the Guid):
public static void StoreGuid(Guid guid)
{
using (var cnx = new SqlConnection("YourDataBaseConnectionString"))
using (var cmd = new SqlCommand {
Connection = cnx,
CommandType = CommandType.StoredProcedure,
CommandText = "StoreGuid",
Parameters = {
new SqlParameter {
ParameterName = "#guid",
SqlDbType = SqlDbType.UniqueIdentifier, // right here
Value = guid
}
}
})
{
cnx.Open();
cmd.ExecuteNonQuery();
}
}
See also: SQL Server's uniqueidentifier
Store it in the database in a field with a data type of uniqueidentifier.
// Create Instance of Connection and Command Object
SqlConnection myConnection = new SqlConnection(GentEFONRFFConnection);
myConnection.Open();
SqlCommand myCommand = new SqlCommand("your Procedure Name", myConnection);
myCommand.CommandType = CommandType.StoredProcedure;
myCommand.Parameters.Add("#orgid", SqlDbType.UniqueIdentifier).Value = orgid;
myCommand.Parameters.Add("#statid", SqlDbType.UniqueIdentifier).Value = statid;
myCommand.Parameters.Add("#read", SqlDbType.Bit).Value = read;
myCommand.Parameters.Add("#write", SqlDbType.Bit).Value = write;
// Mark the Command as a SPROC
myCommand.ExecuteNonQuery();
myCommand.Dispose();
myConnection.Close();

Categories

Resources