SqlConnection and SqlCommand with using statement - c#

I have a connection to a database set up like this to call a stored procedure. I am just wondering if this is the best way to do this.
I have two using statements one for the sqlConnection and one for the sqlCommand (which I am not really sure if its needed)
using (SqlConnection con1 = new SqlConnection(conString1))
{
using (SqlCommand cmd1 = new SqlCommand())
{
cmd1.Connection = con1;
cmd1.CommandType = CommandType.StoredProcedure;
cmd1.CommandText = "updateVendorEstNo";
cmd1.Parameters.AddWithValue("#plantNameNew", vPlantName.Value.ToString().Trim());
var result = cmd1.Parameters.Add("#result", SqlDbType.Int);
result.Direction = ParameterDirection.Output;
var resultDesc = cmd1.Parameters.Add("#resultDesc", SqlDbType.VarChar, 100);
resultDesc.Direction = ParameterDirection.Output;
con1.Open(); // open connection
cmd1.ExecuteNonQuery();
res = result.Value.ToString().Trim();
resDesc = resultDesc.Value.ToString().Trim();
}
}
My biggest question is when I am doing :
using (SqlCommand cmd1 = new SqlCommand())
Is it fine the way it is done right now.. or should it be more like,
using (SqlCommand cmd1 = new SqlCommand("updateVendorEstNo",con1))

I think that the way you have it is fine, because the using statement will ensure that the object is disposed of either way.

Related

OleDbCommand in Using block: COM object that has been separated from its underlying RCW cannot be used

I got error "System.Runtime.InteropServices.InvalidComObjectException: 'COM object that has been separated from its underlying RCW cannot be used.'" ONLY when i execute OleDbCommand object in using block with parameters
using (OleDbCommand comm = new OleDbCommand())
{
comm.Connection = conn;
comm.CommandType = CommandType.Text;
string txt = "SELECT* FROM [ListForGroup] WHERE [email] = #email";
comm.Parameters.Add("#email", OleDbType.VarWChar).Value = userEmail;
comm.CommandText = txt;
conn.Open();
OleDbDataReader reader = comm.ExecuteReader();
List<ListForGroups> list = returnLists(reader);
conn.Close();
cmbSelectList.DataSource = list;
cmbSelectList.DisplayMember = "listName";
cmbSelectList.ValueMember = "listForGroupsID";
}
Does anyone know reason for that. I can resolve it to use OleDbCommand object with CommandText without parameters but i read that's bad idea. And i want to do it in using block to be sure that all reasources will be released.
I resolved this problem
using (OleDbConnection conn = new OleDbConnection(connString))
{
OleDbCommand comm = new OleDbCommand();
comm.Connection = conn;
comm.CommandType = CommandType.Text;
string txt = "SELECT* FROM [ListForGroup] WHERE [email] = #email";
comm.Parameters.Add("#email", OleDbType.VarWChar).Value = userEmail;
comm.CommandText = txt;
conn.Open();
OleDbDataReader reader = comm.ExecuteReader();
List<ListForGroups> list = returnLists(reader);
cmbSelectList.DataSource = list;
cmbSelectList.DisplayMember = "listName";
cmbSelectList.ValueMember = "listForGroupsID";
}
I don't know why I didn't create OleDbConnection in brackets next to using. Another when to resolve it is to close connection after using block.

why these code work but dont add record to my database

SqlConnection conn = new SqlConnection();
conn.ConnectionString = #"Data Source=CASPER_NIRVANA\FARID;Initial Catalog=proje;Integrated Security=True";
SqlCommand cmd = new SqlCommand();
cmd.Connection = conn;
cmd.CommandText = "INSERT INTO projetablosu(basvuru_no)VALUES(#basvuru_no)";
cmd.Parameters.AddWithValue("basvuru_no", textBox1.Text);
cmd.ExecuteNonQuery();
Well, if it doesn't add the record to the database you can hardly say it works, can you?
You are missing the # in the parameter. Instead of
cmd.Parameters.AddWithValue("basvuru_no", textBox1.Text);
use
cmd.Parameters.Add("#basvuru_no", SqlDbType.VarChar).Value = textBox1.Text;
You should also read Can we stop using AddWithValue() already?
Also, as Artem wrote in his comment, you should dispose your disposable objects. The proper way to do it is with the using statement:
using (var conn = new SqlConnection(#"Data Source=CASPER_NIRVANA\FARID;Initial Catalog=proje;Integrated Security=True"))
{
using (var cmd = new SqlCommand("INSERT INTO projetablosu(basvuru_no)VALUES(#basvuru_no)", conn))
{
cmd.Parameters.Add("#basvuru_no", SqlDbType.VarChar).Value = textBox1.Text;
cmd.ExecuteNonQuery();
}
}
Also note that you can use the constructors to pass all the properties you have set manually in your code, making the code shorter and more readable.
SqlConnection conn = new SqlConnection(#"Data Source=CASPER_NIRVANA\FARID;Initial Catalog=proje;Integrated Security=True");
string query = "INSERT INTO projetablosu(basvuru_no)VALUES('"+textBox1.Text+"')";
SqlCommand cmd = new SqlCommand(query,conn);
cmd.ExecuteNonQuery();
// Try This Code, This Will Definately works for u

Error Trying To Fill Data Table

This is my syntax, but I get an error of
The SelectCommand property has not been initialized before calling 'Fill'.
what do I need to do in order to be able to fill the data table?
using (SqlConnection conn = new SqlConnection("Server=Test;Database=Test;Integrated Security=SSPI;"))
{
SqlCommand command = new SqlCommand();
command.CommandText = "SELECT * FROM [dbo].[selfservice] WHERE saleID = #userid;";
command.Parameters.Add("#userid", SqlDbType.VarChar);
command.Parameters["#userid"].Value = row.Field<string>("saleID");
command.Connection = conn;
using (SqlDataAdapter dataadapter1 = new SqlDataAdapter()
{
dataadapter1.Fill(dtData);
}
}
Notice that you're not using the command object. You need to add the select command to your adapter:
using (SqlDataAdapter dataadapter1 = new SqlDataAdapter()
{
dataadapter1.SelectCommand = command
dataadapter1.Fill(dtData);
}
you have to specify select command of SqlDataAdapter before Fill, also you are missing a close parenthesis at the end
using (SqlDataAdapter dataadapter1 = new SqlDataAdapter())
{
dataadapter1.SelectCommand=command;
dataadapter1.Fill(dtData);
}

SqlDataAdapter with using keyword

Is this the following code healthy? Or I don't need to use the using keyword as the SqlDataAdapter will handle closing the connection?
public static DataSet Fetch(string sp, SqlParameter [] prm)
{
using (SqlConnection con = new SqlConnection(ConStr))
{
using (SqlCommand cmd = con.CreateCommand())
{
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText = sp;
cmd.Parameters.AddRange(prm);
using (SqlDataAdapter dta = new SqlDataAdapter(cmd))
{
DataSet dst = new DataSet();
dta.Fill(dst);
return dst;
}
}
}
}
#MarkGravell I need a suggestions here, I am really looking to use DataReader, but I was looking all the time to use the using keyword to ensure closing the connections. Where with DataReader we can not use it because it will close the connection if we want to return the DataReader back to some method.
So do you think the following technique is fine with DataReader and the using keyword:
public static SqlDataReader Fetch(string sp, SqlParameter [] prm)
{
SqlCommand cmd = new SqlConnection(ConStr).CreateCommand();
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText = sp;
cmd.Parameters.AddRange(prm);
cmd.Connection.Open();
return cmd.ExecuteReader(CommandBehavior.CloseConnection);
}
using (SqlDataReader dtrPrize = Sql.Fetch("SelectPrize", new SqlParameter[] { new SqlParameter("id", id) }))
{
dtrPrize.Read();
Prize prize = new Prize();
prize.id = (int)dtrPrize[dtrPrize.GetOrdinal("id")];
prize.artitle = (string)dtrPrize[dtrPrize.GetOrdinal("artitle")];
prize.entitle = (string)dtrPrize[dtrPrize.GetOrdinal("entitle")];
prize.ardetail = (string)dtrPrize[dtrPrize.GetOrdinal("ardetail")];
prize.endetail = (string)dtrPrize[dtrPrize.GetOrdinal("endetail")];
prize.image = (string)dtrPrize[dtrPrize.GetOrdinal("image")];
prize.theme = (string)dtrPrize[dtrPrize.GetOrdinal("theme")];
prize.price = (int)dtrPrize[dtrPrize.GetOrdinal("price")];
prize.audience = (int)dtrPrize[dtrPrize.GetOrdinal("audience")];
prize.type = (byte)dtrPrize[dtrPrize.GetOrdinal("type")];
prize.status = (byte)dtrPrize[dtrPrize.GetOrdinal("status")];
prize.voucher = (string)dtrPrize[dtrPrize.GetOrdinal("voucher")];
prize.supplierid = (int)dtrPrize[dtrPrize.GetOrdinal("supplierid")];
prize.created = (DateTime)dtrPrize[dtrPrize.GetOrdinal("created")];
prize.updated = (DateTime)dtrPrize[dtrPrize.GetOrdinal("updated")];
return prize;
}
Healthy-ish; personally I'd say the unhealthy bit is the bit where it makes use of DataSet and DataAdapter, but that is perhaps just my personal bias.
Yes, you should dispose the adapter etc here (which is what the using does for you, obviously).
As a trivial pointless tidy, you can stack the usings - just makes it a little less verbose:
using (SqlConnection con = new SqlConnection(ConStr))
using (SqlCommand cmd = con.CreateCommand())
{
It will be enough to leave just the first using (the one on the Connection) because disposing the connection will dispose everything you need disposed.
However, there is no harm disposing everything, just a bit more code.

Can't get a SQL command to recognise the params added

I've not used basic SQL commands for a while and I'm trying to pass a param to a sproc and the run it. However when I run the code I get a "Not Supplied" error.
Code:
SqlConnection conn1 = new SqlConnection(DAL.getConnectionStr());
SqlCommand cmd1 = new SqlCommand("SProc_Item_GetByID", conn1);
cmd1.Parameters.Add(new SqlParameter("#ID", itemId));
conn1.Open();
cmd1.ExecuteNonQuery();
I'm not really sure why this would fail. Apologies for the basic question, but I'm lost!
Thanks in advance.
You should set the CommandType to StoredProcedure, set the connection and use Parameters.AddWithValue("#ID", itemID)
cmd1.CommandType = CommandType.StoredProcedure;
cmd1.Connection = conn1;
cmd1.Parameters.AddWithValue("#ID",itemID);
conn1.Open();
cmd1.ExecuteNonQuery();
If you want to use Parameters.Add() (which is obsolete), here is how you do it (you need to pass the type too)
cmd1.Parameters.Add("#ID", SqlDbType.Int); //string maybe, I don't know
cmd1.Parameters["#ID"].Value = itemID;
This should work:
SqlConnection conn1 = new SqlConnection(DAL.getConnectionStr());
SqlCommand cmd1 = new SqlCommand("SProc_Item_GetByID", conn1);
cmd1.CommandType = CommandType.StoredProcedure;
cmd1.Parameters.AddWithValue("#ID", itemId);
conn1.Open();
cmd1.ExecuteNonQuery();
And to make your code even better, put your SqlConnection and SqlCommand into using statements, so that they'll be freed automatically at the end of the using block:
using(SqlConnection conn1 = new SqlConnection(DAL.getConnectionStr()))
{
using(SqlCommand cmd1 = new SqlCommand("SProc_Item_GetByID", conn1))
{
cmd1.CommandType = CommandType.StoredProcedure;
cmd1.Parameters.AddWithValue("#ID", itemId);
conn1.Open();
cmd1.ExecuteNonQuery();
conn.Close();
}
}

Categories