I have two SQL queries:
SqlCommand cmdone = new SqlCommand("update HardwareDetails Set Transstat = #Transstat where AssetNo = #AssetNo", con);
cmdone.Parameters.AddWithValue(#"Transstat", "Raised");
cmdone.Parameters.AddWithValue(#"AssetNo", txtAsset.Text);
cmdone.ExecuteNonQuery();
cmdone.Dispose();
And:
SqlCommand cmd = new SqlCommand("Insert into TransferRequest(FrmName,FrmEmpId,ToName) values (#FrmName,#FrmEmpId,#ToName", con);
cmd.Parameters.AddWithValue(#"FrmName", txtfrm.Text);
cmd.Parameters.AddWithValue(#"FrmEmpId", Global.transferorid);
cmd.Parameters.AddWithValue(#"ToName", txtName.Text);
cmd.ExecuteNonQuery();
cmd.Dispose();
Is there a way to combine them into a single query?
Put a semi-colon between the two SQL statements, and add all the parameters.
using (SqlCommand cmd = new SqlCommand("UPDATE HardwareDetails SET Transstat = #Transstat WHERE AssetNo = AssetNo; INSERT INTO TransferRequest (FrmName, FrmEmpId, ToName) VALUES (#FrmName, #FrmEmpId, #ToName)", con))
{
cmd.Parameters.AddWithValue(#"Transstat", "Raised");
cmd.Parameters.AddWithValue(#"AssetNo", txtAsset.Text);
cmd.Parameters.AddWithValue(#"FrmName", txtfrm.Text);
cmd.Parameters.AddWithValue(#"FrmEmpId", Global.transferorid);
cmd.Parameters.AddWithValue(#"ToName", txtName.Text);
cmd.ExecuteNonQuery();
}
Comments:
Its best practice (because its safer) to create your cmd within a using block.
AddWithValue should not be used, instead create the SqlParameter using its constructor and specify the type and precision. E.g. cmd.Parameters.Add(new SqlParameter("#Transstat", SqlDataType.VarChar, 6) { Value = "Raised"});
As pointed out by Liam as it stands this does break the Single Responsibility Principle. Personally I would only use this method if the two statements are linked/related in some way.
string query = #"
update HardwareDetails Set Transstat = #Transstat where AssetNo = #AssetNo
Insert into TransferRequest(FrmName,FrmEmpId,ToName) values (#FrmName,#FrmEmpId,#ToName)";
SqlCommand cmd= new SqlCommand(query,con);
cmd.Parameters.AddWithValue(#"Transstat", "Raised");
cmd.Parameters.AddWithValue(#"AssetNo", txtAsset.Text);
cmd.Parameters.AddWithValue(#"FrmName", txtfrm.Text);
cmd.Parameters.AddWithValue(#"FrmEmpId", Global.transferorid);
cmd.Parameters.AddWithValue(#"ToName", txtName.Text);
cmd.ExecuteNonQuery();
cmd.Dispose();
Related
I am trying to update my ms access db with windows application and I am having a hard time. When I run it I don't get any errors but it does update like once or twice when I test it but then doesn't work again if I do it again a third time.
This is the code I use
Conn.Open();
Command.CommandType = CommandType.Text;
Command.CommandText ="UPDATE TABLE SET c_qty=#qty WHERE id = #ID";
Command.Parameters.AddWithValue("#qty", txtQty.Text);
Command.Parameters.AddWithValue("#ID", txtID.Text);
Command.ExecuteNonQuery();
Conn.Close();
I felt I was doing this right or on the right track of having it correct but seems to be more of a issue then I thought. Any help would be great
Quantity and Id are hopefully integers and you should pass them as such.
Also Table is a reserved word, if this really is the name of your table you should enclose it with square brackets.
You should also pass in the correct db types in your parameters and not use AddWithvalue which does not allow this.
Code
Conn.Open();
Command.CommandType = CommandType.Text;
Command.CommandText ="UPDATE [TABLE] SET c_qty= ? WHERE id = ?";
Command.Parameters.Add(new OleDbParameter("#qty", OleDbType.Int) {Value = int.Parse(txtQty.Text)});
Command.Parameters.Add(new OleDbParameter("#ID", OleDbType.Int) {Value = int.Parse(txtID.Text)});
var rowsUpdated = Command.ExecuteNonQuery();
// output rowsUpdated to the log, should be 1 if id is the PK
Conn.Close();
Finally use using blocks for your Disposables. If you were to get an Exception here then connection would remain open until Garbage collection runs which means you might have a problem with other connection attempts to this Access database.
Revised with using blocks
using (OleDbConnection Conn = new OleDbConnection("connectionStringHere"))
using (OleDbCommand Command = new OleDbCommand("UPDATE [TABLE] SET c_qty= ? WHERE id = ?", Conn))
{
Command.Parameters.Add(new OleDbParameter("#qty", OleDbType.Int) {Value = int.Parse(txtQty.Text)});
Command.Parameters.Add(new OleDbParameter("#ID", OleDbType.Int) {Value = int.Parse(txtID.Text)});
Conn.Open();
var rowsUpdated = Command.ExecuteNonQuery();
// output rowsUpdated to the log, should be 1 if id is the PK
}
Finally OleDbCommand does not support named parameters, see OleDbCommand.Parameters
I was wondering if it is possible for the update button to save the changes made in the table. I wrote this code but I have no idea how it could possibly work
This is the code i wrote for the update button:
string conString = "Data Source=MIRANDA-PC;Initial Catalog=Futebol do Rosa;Integrated Security=True";
SqlConnection con = new SqlConnection(conString);
string selectSql = "Update Players$ set Player Name='" + dataGridView2.Text + "";
SqlCommand cmd = new SqlCommand(selectSql, con);
con.Open();
This is the table I want to update the values in:
Well, you just need to execute your query with ExecuteNonQuery.
But more important, you should always use parameterized queries. This kind of string concatenations are open for SQL Injection attacks.
Also use using statement to dispose your SqlConnection and SqlCommand.
And if your table or column names more than one word, you need to use them with [] as [Player Name]. And honestly, it is a little bit weird to use $ sign in a table name.
using(SqlConnection con = new SqlConnection(conString))
using(SqlCommand cmd = con.CreateCommand())
{
cmd.CommandText = "Update Players$ set [Player Name] = #name";
cmd.Parameters.Add("#name", SqlDbType.NVarChar, 16).Value = dataGridView2.Text;
con.Open();
cmd.ExecuteNonQuery();
}
You have to execute your SQL query with your db object.
dbinstance.ExecuteSqlCommand(string sqlcommand, object[] params);
This method is both for DDL and DML.
you can also use ExecuteNonQuery method.
cmd.CommandText = "Update Players$ set [Player Name] = #Playername";
cmd.Parameters.Add("#Playername", SqlDbType.NVarChar, 16).Value = dataGridView2.Text;
con.Open();
cmd.ExecuteNonQuery();
The best solution (if possible) to to convert your DAL (Data Access Layer) to Entity-framework based, instead of writing your own SQL queries. This is safe-by-design and never is vulnerable to SQL Injection of any kind.
Here is some mockup code:
using (AppEntities currDb = new AppEntities)
{
Players PlayerToEdit =
from player in currDb.Players
where player.PlayerID == lngPlayerID
select player.First();
PlayerToEdit.PlayerName = dataGridView2.Text;
currDb.SaveChanges();
}
You can read about it some more here:
https://msdn.microsoft.com/en-us/data/ef.aspx
I want to create a table at the runtime and store information into it.
Below the code which i tried.
SqlConnection con = new SqlConnection(#"Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|\Database.mdf;Integrated Security=True;User Instance=True;");
con.Open();
String crt = "CREATE TABLE trail (Name Varchar(50) NOT NULL, Sex Varchar(50) NOT NULL)";
SqlCommand cov = new SqlCommand(crt, con);
cov.ExecuteReader();
String add = "Insert into trail value (#nam,#sex)";
SqlCommand cmd = new SqlCommand(add,con);
cmd.Parameters.AddWithValue("#nam",TextBox1.Text);
cmd.Parameters.AddWithValue("#sex", RbtGender.SelectedValue);
cmd.ExecuteReader();
con.Close();
Response.Redirect("Success.aspx");
There is no point to use ExecuteReader with CREATE statement. It does not return any data anyway (and it retursn SqlDataReader, it is not a void method). Use ExecuteNonQuery instead to execute your queries. Same with INSERT statement also.
And it is values not value. Take a look at INSERT (Transact-SQL) syntax.
Also use using statement to dispose your SqlConnection and SqlCommand like;
using(SqlConnection con = new SqlConnection(connString))
using(SqlCommand cov = con.CreateCommand())
{
//
}
Don't use AddWithValue by the way. Use one of Add overloads. This method has some problems.
Read: http://blogs.msmvps.com/jcoehoorn/blog/2014/05/12/can-we-stop-using-addwithvalue-already/
I wrote this code before
cmd.Connection = con;
Then I wrote this
cmd.ExecuteReader();
I'm using the following code to clear a database table:
public void ClearAll()
{
SqlCommand info = new SqlCommand();
info.Connection = con;
info.CommandType = CommandType.Text;
info.CommandText = "edit_.Clear()";
}
Why does it not work?
With a sql command you usually pass a TSQL statement to execute. Try something more like,
SqlConnection con = new SqlConnection(ConfigurationSettings.AppSettings["con"]);
SqlCommand cmd = new SqlCommand();
cmd.CommandText = "DELETE FROM Edit_ ";
cmd.Connection = con;
con.Open();
cmd.ExecuteNonQuery();
con.Close();
You need to execute the command, so info.Execute() or info.ExecuteNonQuery().
Try info.CommandText='DELETE FROM edit_';
The CommandText attribute is the TSQL statement(s) that are run.
You also need a info.ExecuteNonQuery();
1) Decide whether to use a TRUNCATE or a DELETE statement
Use TRUNCATE to reset the table with all its records and indexes:
using (SqlCommand command = connection.CreateCommand())
{
command.CommandType = CommandType.Text;
command.CommandText = "TRUNCATE TABLE [dbo].[Edit_]";
command.ExecuteNonQuery();
}
Use DELETE to delete all records but do not reset identity/auto increment columns
using (SqlCommand command = connection.CreateCommand())
{
command.CommandType = CommandType.Text;
command.CommandText = "DELETE FROM [dbo].[Edit_]";
command.ExecuteNonQuery();
}
Note that there is another line in the samples. In the sample you provided the SQL statement never gets executed until you call one of the ExecuteXXX() methods like ExecuteNonQuery().
2) Make sure you use the correct object (are you sure its called edit_?). I recommend to put the schema before the table name as in the examples before.
3) Make sure you use the correct connection string. Maybe everything worked fine on the production environment ;-)
I am getting exception: "Specific cast is not valid", here is the code
con.Open();
string insertQuery = #"Insert into Tender (Name, Name1, Name2) values ('Val1','Val2','Val3');Select Scope_Identity();";
SqlCommand cmd = new SqlCommand(insertQuery, con);
cmd.ExecuteNonQuery();
tenderId = (int)cmd.ExecuteScalar();
In the interests of completeness, there are three issues with your code sample.
1) You are executing your query twice by calling ExecuteNonQuery and ExecuteScalar. As a result, you will be inserting two records into your table each time this function runs. Your SQL, while being two distinct statements, will run together and therefore you only need the call to ExecuteScalar.
2) Scope_Identity() returns a decimal. You can either use Convert.ToInt32 on the result of your query, or you can cast the return value to decimal and then to int.
3) Be sure to wrap your connection and command objects in using statements so they are properly disposed.
using (SqlConnection connection = new SqlConnection(connectionString))
{
using (SqlCommand command = new SqlCommand(sql, connection))
{
connection.Open();
int tenderId = (int)(decimal)command.ExecuteScalar();
}
}
Try this:-
con.Open();
string insertQuery = #"Insert into Tender (Name, Name1, Name2) values ('Val1','Val2','Val3');Select Scope_Identity();";
SqlCommand cmd = new SqlCommand(insertQuery, con);
tenderId = Convert.ToInt32(cmd.ExecuteScalar());
EDIT
It should be this as it is correctly pointed out that scope_identity() returns a numeric(38,0) :-
tenderId = Convert.ToInt32(cmd.ExecuteScalar());
Note: You still need to remove the:-
cmd.ExecuteNonQuery();
Test the following first:
object id = cmd.ExcuteScalar()
Set a break point and have a look at the type of id. It is probably a Decimal and cannot directly be casted to int.
it needs Convert.ToInt32(cmd.ExecuteScalar());