retrieve updated parameter value on asp.net with sqlcommand - c#

I'm using a query to update a column value on table and also retrieve the updated value using the following way on the ASP.NET site. Is there any way to use single query instead of double queries as below?
using (SqlConnection connection = new SqlConnection(connStr)){
string updateUserQuery = "Update user_master set login_failed_attempts = login_failed_attempts + 1 where id = #id; Select #login_failed = login_failed_attempts from user_master where id = #id";
SqlCommand cmd = new SqlCommand(updateUserQuery, connection);
cmd.Parameters.Add("#id", SqlDbType.Int).Value = user_id;
SqlParameter outputIdParam = new SqlParameter("#login_failed", SqlDbType.Int)
{
Direction = ParameterDirection.Output
};
cmd.Parameters.Add(outputIdParam);
cmd.ExecuteNonQuery();
int loginFailedAttempts = int.Parse(outputIdParam.Value.ToString());
}
Updated code is given below after Matthew's answer.
string updateUserQuery = "Update user_master set login_failed_attempts = login_failed_attempts + 1 OUTPUT INSERTED.login_failed_attempts where id = #id";
SqlCommand cmd = new SqlCommand(updateUserQuery, connection);
cmd.Parameters.Add("#id", SqlDbType.Int).Value = user_id;
int loginFailedAttempts = (int)cmd.ExecuteScalar();

Use an OUTPUT clause.
UPDATE user_master
SET login_failed_attempts = login_failed_attempts + 1
OUTPUT INSERTED.login_failed_attempts
WHERE id = #id
Then change your ExecuteNonQuery to an ExecuteScalar and use the result from that accordingly.
You could also change it to an ExecuteReader and pull back multiple records, but given your use of #id I'm assuming you don't want that.

Related

c# Inserting int value into SQL table

I want to insert some data into SQL table. But while inserting int no matter what I've tried I get error:
System.Data.SqlClient.SqlException: 'Conversion failed when converting
the varchar value '#ID' to data type int.'
I even manually set ID to 1 simply to be 100 % sure it's int but still get that error
String query = "INSERT INTO table(dbo.table.ID, dbo.table.secondvar)
VALUES ('#ID','#secondvar')";
using (SqlCommand cmd = new SqlCommand(query, connection))
{
int ID = 1;
cmd.Parameters.AddWithValue("#ID", ID);
cmd.Parameters.AddWithValue("#secondvar", tableModel.secondvar);
connection.Open();
int result = cmd.ExecuteNonQuery();
Remove the quotes around the values. The framework handles that already.
VALUES ('#ID','#secondvar')
should be
VALUES (#ID,#secondvar)
ID is an integer so it must not be between '':
Change this line:
String query = "INSERT INTO table(dbo.table.ID, dbo.table.secondvar)
VALUES ('#ID','#secondvar')";
to this:
String query = "INSERT INTO table(dbo.table.ID, dbo.table.secondvar)
VALUES (#ID,#secondvar)";
And its better avoid using AddWithValue instead use it like:
String query = "INSERT INTO table(dbo.table.ID, dbo.table.secondvar)
VALUES (#ID,'#secondvar')";
using (SqlCommand cmd = new SqlCommand(query, connection))
{
int ID = 1;
cmd.Parameters.Add("#ID", SqlDbType.Int).Value = ID;
cmd.Parameters.Add("#secondvar", SqlDbType.VarChar).Value = somevalue;
//rest of the code
}

Get last ID from select query in C# WPF

I would like to get last selected person ID.
string personID = "SELECT PersonID FROM TestDatabase.[dbo].[Persons] where name LIKE 'XYZ%'";
SqlCommand cmd = new SqlCommand(personID, con);
SqlDataReader reader = cmd.ExecuteReader();
var lastSelectedSingleClientPhoneId = reader.GetDecimal(0);
But unfortunately it did not work. I already tried to get int16, int32 and int64. When i use INSERT I can get the ID using the following select:
SELECT SCOPE_IDENTITY();
Insert command below:
string insertPerson = "INSERT INTO TestDatabase.[dbo].[Persons] (firstName,secondName) VALUES (#firstName,#secondName);SELECT SCOPE_IDENTITY();";
SqlCommand cmd = new SqlCommand(insertPerson, con);
cmd.Parameters.AddWithValue("#firstName", txt_firstName.Text);
cmd.Parameters.AddWithValue("#secondName", txt_secondName.Text);
SqlDataReader reader = cmd.ExecuteReader();
reader.Read();
var lastInsertedPersontId = reader.GetDecimal(0);'
This should return all Persons beginning with 'XYZ' in the Persons database table.
string personID = "SELECT PersonID FROM TestDatabase.[dbo].[Persons] where name LIKE 'XYZ%'";
using(var cmd = new SqlCommand(personID, con))
using (var reader = cmd.ExecuteReader())
{
while(reader.Read())
{
Console.WriteLine(reader.GetValue(0));
}
}
I appreciate you're looking for a type to call GetXXX, but you can easily extend this pseudo-code to determine the appropriate type.
You can try combining the two SQL statements as one CommandText value then use ExecuteScalar to return the last inserted ID
string insertPerson = "INSERT INTO TestDatabase.[dbo].[Persons] (firstName,secondName) VALUES (#firstName,#secondName); SELECT SCOPE_IDENTITY();";
SqlCommand cmd = new SqlCommand(insertPerson, con);
cmd.Parameters.AddWithValue("#firstName", txt_firstName.Text);
cmd.Parameters.AddWithValue("#secondName", txt_secondName.Text);
int personID = (int)cmd.ExecuteScalar();
/// ... convert integer value to a string or do something
You can also try this SQL statement as an alternative:
SELECT TOP 1 PersonID FROM Persons ORDER BY PersonID DESC;

Trying to update db - no errors but no update either

I have a problem in trying to update a database using SQL update command and DataGridView.
Int16 ID, An;
// update db using sql command, the code does not update the database
SqlCommand cmd = new SqlCommand("update filme set ID = #ID, Nume = #Nume, Gen = #Gen, Descriere = #Descriere, Actori = #Actori, An = #An, Rating = #Rating, Pret = #Pret where ID = #ID");
cmd.CommandType = CommandType.Text;
cmd.Connection = connection;
cmd.Parameters.AddWithValue("#ID", SqlDbType.SmallInt).Value = Int16.TryParse("#ID", out ID);
cmd.Parameters.AddWithValue("#Nume", SqlDbType.NVarChar).Value = "#Nume";
cmd.Parameters.AddWithValue("#Gen",SqlDbType.NVarChar).Value = "#Gen";
cmd.Parameters.AddWithValue("#Descriere", SqlDbType.NVarChar).Value = "#Descriere";
cmd.Parameters.AddWithValue("#Actori", SqlDbType.NVarChar).Value = "#Actori";
cmd.Parameters.AddWithValue("#An", SqlDbType.SmallInt).Value = Int16.TryParse("#An", out An) ;
cmd.Parameters.AddWithValue("#Rating", SqlDbType.NVarChar).Value = "#Rating";
cmd.Parameters.AddWithValue("#Pret",SqlDbType.Money).Value = "#Pret";
connection.Open();
cmd.ExecuteNonQuery();
This code does not produce any errors, but does not update the database. Something is wrong but I don't know what.
I use Visual Studio Community and SQL Server 2012. The information from database are displayed in a DataGridView.
Thank you !
You set the #ID parameter with this line
Int16.TryParse("#ID", out ID);
what do you expect to be the result of converting the string #ID to an integer?
And Int16.TryParse returns a boolean, true if the conversion succeed, false otherwise.
Then you use
cmd.Parameters.AddWithValue("#ID", SqlDbType.SmallInt).Value = .....
The second parameter of AddWithValue is the Value to give to the parameter, not the type.
The remainder follows the same pattern and so this code will never work.
As an example, you should write:
SqlCommand cmd = new SqlCommand(#"update filme set Nume = #Nume, Gen = #Gen,
Descriere = #Descriere, Actori = #Actori,
An = #An, Rating = #Rating, Pret = #Pret
where ID = #ID", connection);
cmd.Parameters.Add(new SqlParameter
{ ParameterName = #Nume,
SqlDbType = SqlDbType.Int,
Value = Convert.ToInt32(someTextBox.Text) // Or some datagridview cell...
};
...and so on for the other parameters...
Notice also that I have removed the part about SET ID = #ID because this makes no sense. If you use the ID field as your search condition then updating it with the value that you are searching for could only lead, in the best situation, at no change for the ID field and in the worst situation to changing a different record from the intended one.
The way you use the .AddWithValue is all wrong .....
You have
cmd.Parameters.AddWithValue("#ID", SqlDbType.SmallInt).Value = Int16.TryParse("#ID", out ID);
but you're really defining the parameter name and datatype (which is a good thing!) and then you use the .Value = ... to handle the value assignment.
These lines of code should really be:
cmd.Parameters.Add("#ID", SqlDbType.SmallInt).Value = Int16.TryParse("#ID", out ID);
I bet using this approach, your code will work just fine.

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

Update Database from Dataset

My goal is to update the QTY for each SKU. I am using a SqlDataAdapter to accomplish this. The program runs fine. Just that no result happens.
QUESTION: Why is no result happening? My database remains unchanged.
Code below
public static void updateInventoryfromAMZ(DataTable datatable)
{
int index = 0;
string connString = System.Configuration.ConfigurationManager.ConnectionStrings["MyConnectionString"].ToString();
DataSet amzInventoryDataSet = new DataSet("AMZINVDATASET");
amzInventoryDataSet.Tables.Add(datatable);
// FOR EACH ROW - PERFORM AN UPDATE //
using (SqlConnection connection = new SqlConnection(connString))
{
SqlDataAdapter adapter = new SqlDataAdapter();
foreach (DataRow row in amzInventoryDataSet.Tables[index].Rows)
{
string sku = datatable.Rows[index]["seller-sku"].ToString();
string qty = datatable.Rows[index]["quantity"].ToString();
// Create the UpdateCommand.
SqlCommand command = new SqlCommand(
"UPDATE Inventory SET qty = #qty" +
"WHERE sku = #sku", connection);
// Add the parameters for the UpdateCommand.
command.Parameters.Add("#qty", SqlDbType.Int, qty.Length, qty);
command.Parameters.Add("#sku", SqlDbType.VarChar, sku.Length, sku);
adapter.UpdateCommand = command;
adapter.Update(amzInventoryDataSet.Tables[index]);
index++;
}
}
}
When you concatenating two sql strings, you better add space at the end of first string or at the beginning of second string. As Gordon Linoff pointed out your sql statement is incorrect. And also setting parameters and the values need to be change depending on the type of the parameters.
try below code, I have use SqlCommand and ExecuteNonQuery method to update each row data
using (SqlConnection connection = new SqlConnection(connString))
using (SqlCommand cmd = new SqlCommand("UPDATE Inventory SET qty = #qty WHERE sku = #sku", connection))
{
connection.Open();
var paramqty= cmd.Parameters.Add("#qty", SqlDbType.Int);
var parasku = cmd.Parameters.Add("#sku", SqlDbType.VarChar);
foreach (DataRow row in amzInventoryDataSet.Tables[0].Rows)
{
parasku.Value = row["seller-sku"].ToString();
paramqty.Value = int.Parse(row["quantity"].ToString());
cmd.ExecuteNonQuery();
}
}
I am thinking your problem are these lines:
"UPDATE Inventory SET qty = #qty" +
"WHERE sku = #sku", connection);
They are going to produce a string like:
"UPDATE Inventory SET qty = #qtyWHERE sku = #sku", connection);
And the variable #qtyWHERE is not defined.
Try this instead:
"UPDATE Inventory SET qty = #qty WHERE sku = #sku", connection);

Categories

Resources