SqlDataReader Close and SqlConnection - sql-server

What happens with the connection in this case? I don't know if reader.Close() close the open sqlconnection.
private static void ReadOrderData(string connectionString)
{
string queryString = "SELECT OrderID, CustomerID FROM dbo.Orders;";
using (SqlConnection connection = new SqlConnection(connectionString))
{
SqlCommand command = new SqlCommand(queryString, connection);
connection.Open();
SqlDataReader reader = command.ExecuteReader();
// Call Read before accessing data.
while (reader.Read())
{
Console.WriteLine(String.Format("{0}, {1}", reader[0], reader[1]));
}
// Call Close when done reading.
reader.Close();
}
}

reader.Close() won't close the SqlConnection, but since you have a using statement, once you exit the using block the connection will get closed anyway.

Closing the reader will not alter the state of the connection. If you did want to do this you can pass CommandBehavior.CloseConnection to the ExecuteReader method of the SqlCommand instance.
SqlDataReader reader = command.ExecuteReader(CommandBehavior.CloseConnection);
It is recommended you put a using block around all your disposable types like your SqlDataReader instance.
using(SqlDataReader reader = command.ExecuteReader()) {
// rest of code
}
See also CommandBehavior for more options.

Check Connection State
if(connection.State == ConnectionState.Open)
{
connection.Close();
}
connection.Open();
And since you are doing
using (SqlConnection connection =
new SqlConnection(connectionString))
{
this will make sure connection is disposed as it inherits from IDisposable despite Exception. And object are disposed once they exit their corresponding scope.
And better use
using(SqlCommand command = new SqlCommand(queryString, connection))
and
using(SqlDataReader reader = command.ExecuteReader())
for the same reason mentioned above.

Related

Perform SUM query in ADO.NET

I am getting following error
;expected
I am trying to find sum of column values in my webform.
protected void Page_Load(object sender, EventArgs e)
{
con.Open();
SqlCommand cmd = con.CreateCommand();
cmd.CommandType = CommandType.Text;
cmd.CommandText = "Select SUM("AMOUNT DEPOSITED ") From MAIN_TABLE6";
Double amount = cmd.ExecuteScalar();
Label3.Text = amount.ToString();
}
Use brackets to enclose your columns in SQL Server.
protected void Page_Load(object sender, EventArgs e)
{
con.Open();
SqlCommand cmd = con.CreateCommand();
cmd.CommandType = CommandType.Text;
cmd.CommandText = "Select SUM([AMOUNT DEPOSITED]) From MAIN_TABLE6";
Double amount = cmd.ExecuteScalar();
Label3.Text = amount.ToString();
}
I update-voted the answer by #ϻᴇᴛᴀʟ because he solved the problem with the brackets. However I like to see that database objects are closed and disposed. If database objects are kept local to the methods where they are used then using blocks accomplish this even if there is and error.
It is possible to pass the connection string directly to the constructor of the connection and pass the command text and connection to the constructor of the command. CommandType.Text is the default value so it is not necessary to set it.
I have opened the connection directly before the .Execute... and it is closed immediately after. The user interface is not updated until the connection is closed.
protected void Page_Load(object sender, EventArgs e)
{
double amount;
using (SqlConnection con = new SqlConnection("Your connection string"))
using (SqlCommand cmd = new SqlCommand("Select SUM([AMOUNT DEPOSITED]) From MAIN_TABLE6;", con))
{
con.Open();
amount = (double)cmd.ExecuteScalar();
}
Label3.Text = amount.ToString();
}

Conversion failed when converting from a character string to uniqueidentifier - Doesn't Rollback the transaction

The actual issue is not this - "Conversion failed when converting from a character string to uniqueidentifier" but the issue is that, the transaction doesn't get rolled back after you hit the issue.
My code here,
var connectionstring = "Server= ****; Database= ****; Integrated Security=True;";
var errorInformation = new List<string>();
using (SqlConnection objConn = new SqlConnection(connectionstring))
{
objConn.Open();
var objTrans = objConn.BeginTransaction(); // Begins here
var sql = $"insert into tblProject values('7', 'TestProject')";
SqlCommand insertCommand = new SqlCommand(sql, objConn, objTrans);
try
{
insertCommand.ExecuteNonQuery();
// ProjectID is a unique Identifier in database
SqlCommand cmd = new SqlCommand("SELECT * FROM SOMEOTHERTABLE WHERE PROJECTID=''", objConn, objTrans);
cmd.CommandType = CommandType.Text;
var dataTable = new DataTable("SomeTableName");
using (var adapter = new SqlDataAdapter(cmd))
{
var dt = adapter.Fill(dataTable); // Exception happens here
}
objTrans.Commit(); // Commit here
}
catch (Exception ex)
{
errorInformation.Add(ex.Message);
}
var sql1 = $"insert into tblProject values('8', 'TestProject')";
SqlCommand objCmd2 = new SqlCommand(sql1, objConn, objTrans);
objCmd2.ExecuteNonQuery();
if (errorInformation.Any())
{
objTrans.Rollback(); // Rollback here
}
}
The query that gets executed after the exception, using the same connection object will not rollback. This is a bug that Microsoft needs to look into. Otherwise their rollback feature is not reliable.
I would expect either my second insert command to fail or my rollback to be successful.

Local SQL Server connection fail

I'm trying to connect to a local SQL Server database file and do not know if connection string is right:
SqlConnection con = new SqlConnection(#"Data Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename=C:\Users\ma\Documents\mydb.mdf;Integrated Security=True;");
SqlDataAdapter sda = new SqlDataAdapter("SELECT plataform FROM plataforms", con);
DataSet myDataSet = new DataSet();
sda.Fill(myDataSet);
I have such code wrapped in a try catch and always throws this exception:
Reference to object not established as an instance of an object
What's wrong?
EDIT:
Sorry, I have been commenting code to see what line arises such error and it's the following:
DataRowCollection drc = myDataSet.Tables["plataforms"].Rows;
Sorry, I made a wrong question.
I think You must open connection before Fill
SqlConnection con = new SqlConnection(#"Data Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename=C:\Users\ma\Documents\mydb.mdf;Integrated Security=True;");
SqlDataAdapter sda = new SqlDataAdapter("SELECT plataform FROM plataforms", con);
SqlDataAdapter dAdapter = new SqlDataAdapter();
dAdapter.SelectCommand = sda;
DataSet myDataSet = new DataSet();
try {
con.Open();
sda.Fill(myDataSet);
} catch (Exception ex) {
throw (ex);
} finally {
con.Close();
}
you can try this code.

Hitting "COM object that has been separated from its underlying RCW cannot be used" error

I am trying to write a Windows Form program on top of .NET 4.0 and accessing Microsoft Access Database. I can read and write with no problem but sometimes, I get this error:
COM object that has been separated from its underlying RCW cannot be used.
I tried to call this method (GetIDBasedonTeamName) with different inputs twice (on the same thread). The second time this is run, I got that error.
OleDbConnection conn = new OleDbConnection();
OleDbConnection mDB = new OleDbConnection();
OleDbCommand comm = new OleDbCommand();
OleDbCommand cmd;
OleDbDataReader dr;
public void OpenConnection(string name) // always call this method first in other methods to initialise connection
{
conn.ConnectionString = "Provider = Microsoft.Jet.OLEDB.4.0;Data source="
+ Application.StartupPath + "\\AppData\\" + name + ".mdb;";
conn.Open();
comm.Connection = conn;
comm.Parameters.Clear();
}
public string GetIDBasedonTeamName(string teamName)
{
string toReturn = "";
try
{
OpenConnection("form");
comm.CommandText = "Select ID from TeamDetails WHERE TeamName=#teamName";
comm.Parameters.AddWithValue("TeamName", teamName);
dr = comm.ExecuteReader();
while (dr.Read())
{
toReturn = dr[0].ToString();
}
}
catch (OleDbException e)
{
string err = e.Message.ToString();
return null;
}
finally
{
}
conn.Close();
dr.Close();
return toReturn;
}
Exception happened on dr = comm.ExecuteReader();.
The method that was calling this method have this 2 lines inside:
InfoConfig.team1id = Convert.ToInt32(dbm.GetIDBasedonTeamName(cbxTeam1.Text));
InfoConfig.team2id = Convert.ToInt32(dbm.GetIDBasedonTeamName(cbxTeam2.Text));
What could be the cause? I read around and they mentioned not to use different threads but it is the same thread here.
Thanks,
Guo Hong
Building on Martin Liversage's answer:
public string GetIDBasedonTeamName(string teamName) {
var connString = "Provider = Microsoft.Jet.OLEDB.4.0;Data source="
+ Application.StartupPath + "\\AppData\\" + name + ".mdb;";
using (var conn = new OleDbConnection(connString)) {
conn.Open();
using (var cmd = conn.CreateCommand()) {
cmd.CommandText="Select ID from TeamDetails WHERE TeamName = #teamName";
cmd.Parameters.AddWithValue("TeamName", teamName);
using (var rdr = cmd.ExecuteReader()) {
if (rdr.Read()) {
return (string)rdr["TeamName"];
}
//if no valid results will return null
}
}
}
}
Instead of creating the objects only once and storing them in fields in your class you should create, use and close the objects in your method. It is probably the Close you call in the end the method that releases the underlying COM objects giving you the exception on the second call.

What is the error in this code?

I want to delplay the row in the richtextbox
private void button1_Click(object sender, EventArgs e) {
SqlConnection con = new SqlConnection("Data Source=MOSTAFA\\SQLEXPRESS;Initial Catalog=company;Integrated Security=True");
SqlCommand com = new SqlCommand("select * from data where id='"+textBox1.Text+"')",con);
con.Open();
SqlDataReader read = com.ExecuteReader();
if (read.Read())
richTextBox1.Text = "id" + read[0].ToString();
else
label3.Text=("The client didn't found");
}
There's an error in your generated query. You have a closing parenthesis without an opening one. The line as you have it would produce:
select * from data where id='sometest')
which will yield a syntax error from SQL Server.
Try this instead:
SqlCommand com = new SqlCommand("select * from data where id='"+textBox1.Text+"'",con);
You have an extra parenthesis in that SQL statement.
But more importantly, you are leaving yourself wide open for SQL Injection. To get around this devastating and easily avoidable issue is to use parameterized queries.

Resources