Can a Sql Connection remain open if a second using statement exceptions - c#

Given the following:
try
{
using (var connection = new SqlConnection(_connectionString))
{
connection.Open();
using (SqlCommand queryCommand = new SqlCommand(QueryString, connection))
{
queryCommand.ExecuteScalar();
}
}
}
catch (Exception ex)
{
//logging occurs
}
If the .ExecuteScalar() method throws an exception, will the connection remain open?

No, because you are using the using-statement which ensures that the connection is disposed even in case of an exception. If you want the connection to stay open you have to use a Try/Catch:
using (var connection = new SqlConnection(_connectionString))
{
connection.Open();
using (SqlCommand queryCommand = new SqlCommand(QueryString, connection))
{
try
{
queryCommand.ExecuteScalar();
} catch (Exception ex)
{
// log this exception or do something else useful
}
// now do something else with the command/connection
}
}

Related

BeginTransaction() on sqltransaction freezes, how to use try catch to solve it?

I'm using SqlTransaction transaction = connection.BeginTransaction() in my C# application to get data from SQLServer.
The problem I have when there is no connection to server (no internet connection), then my application just freezes and stops working, no exception, no error, just freezes.
I tried use try catch to catch error, but even then application just freezes, and the only option is to kill application. Can anyone help me to catch this error and istead of freezeing give me error - like Connection to server failed. Please check internet connection.
Here is my class code for connection:
public static class RequestID
{
// Methods
public static int GetID(string server, string database, string user, string pass)
{
int num = 0;
using (SqlConnection connection = new SqlConnection(string.Format("server={0};database={1};uid={2};pwd={3};Connect Timeout=900", new object[] { server, database, user, pass })))
{
SqlCommand command = new SqlCommand("SELECT Value_Int FROM Param WHERE code= 'counter'");
SqlCommand command2 = new SqlCommand("UPDATE Param SET Value_Int = Value_Int + 1 WHERE code= 'counter'");
if (connection.State != ConnectionState.Open)
{
connection.Open();
}
try
{
using (SqlTransaction transaction = connection.BeginTransaction())
{
try
{
command.Connection = connection;
command.Transaction = transaction;
command2.Connection = connection;
command2.Transaction = transaction;
num = (int)command.ExecuteScalar();
command2.ExecuteNonQuery();
transaction.Commit();
}
catch (Exception)
{
transaction.Rollback();
throw;
}
finally
{
if (connection.State != ConnectionState.Closed)
{
connection.Close();
}
}
}
}
catch (Exception ex)
{
throw;
}
return num;
}
}
}
Problem is in line:
using (SqlTransaction transaction = connection.BeginTransaction())
Thanks in advance.
P.S. Application works just fine, the only problam so far then connection to internet lost. I wasn't able to find solution...
Your problem is because
connection.Open();
is outside of your try block so you will never hit the catch.
Move that inside your try block.

SqlConnection can't be opened within a 'using' clause of another SqlConnection?

I'm curious as to why this is. I ran into this scenario earlier today
using (SqlConnection oConn = new SqlConnection(ConnectionString))
{
using (SqlCommand cmd = new SqlCommand("IC_Expense_InsertCycle", oConn))
{
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("#PortalId", portalId);
cmd.Parameters.AddWithValue("#Description", description);
cmd.Parameters.AddWithValue("#StartDate", start);
cmd.Parameters.AddWithValue("#EndDate", end);
try
{
oConn.Open();
cmd.ExecuteNonQuery();
}
catch (SqlException ex)
{
throw ex;
}
}
}
//Get the new set of ExpenseCycles for binding
ExpenseCycle cycle = new ExpenseCycle(ConnectionString);
return cycle.GetExpenseCycles(portalId);
// ^^ this works just fine. The GetExpenseCycles call will basically set up the structure above with using SqlConnection and using SqlCommand
using (SqlConnection oConn = new SqlConnection(ConnectionString))
{
using (SqlCommand cmd = new SqlCommand("IC_Expense_InsertCycle", oConn))
{
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("#PortalId", portalId);
cmd.Parameters.AddWithValue("#Description", description);
cmd.Parameters.AddWithValue("#StartDate", start);
cmd.Parameters.AddWithValue("#EndDate", end);
try
{
oConn.Open();
cmd.ExecuteNonQuery();
}
catch (SqlException ex)
{
throw ex;
}
//Get the new set of ExpenseCycles for binding
ExpenseCycle cycle = new ExpenseCycle(ConnectionString);
return cycle.GetExpenseCycles(portalId);
//This didn't work. The INSERT statement was successful, but it was bringing back old entries, and did not include the newest one that was just inserted
}
}
The bottom code block was initially what I had, and the return count for my test environment was only 1, but there were 2 records in the database. It wasn't fetching that newly inserted record.
The basic code of GetExpenseCycles is the following:
using (SqlConnection oConn = new SqlConnection(ConnectionString))
{
using (SqlCommand cmd = new SqlCommand("IC_Expense_GetExpenseCyclesByPortal",oConn))
{
oConn.Open();
using (SqlDataReader sdr = cmd.ExecuteReader())
{
//Read List<expensecycle> here
}
}
}
Any ideas why? There were no exceptions thrown.
No exceptions thrown so no errors... I suspect the isolation-level on the connection
In the first scenario the connections don't overlap.
ExpenseCycle() use a connection string and I may safely assume it starts a new connection.
In the second example (problem case) the connections do overlap:
If the isolation-level is for instance read-committed and the "enclosing" connection hasn't yet stabilized its write (commit) the new connection don't pick up the changes, in this case the insert.
Possible solutions or things to try out:
1. Check the isolation-level on the connection
2. Pass the connection instead of the connectionstring to ExpenseCycle() (which is a better practice too imho)
You might have an ambient transaction in effect (if the code block is called within the scope of a transaction, new connections will join that transaction automatically. Using the TransactionScope class, you can get a handle of that transaction and commit it before the second call.
Also it looks like your second call is within the scope of the command's using block. Moving it outside of there might be enough to resolve your problem
using (SqlConnection oConn = new SqlConnection(ConnectionString))
{
using (SqlCommand cmd = new SqlCommand("IC_Expense_InsertCycle", oConn))
{
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("#PortalId", portalId);
cmd.Parameters.AddWithValue("#Description", description);
cmd.Parameters.AddWithValue("#StartDate", start);
cmd.Parameters.AddWithValue("#EndDate", end);
try
{
oConn.Open();
cmd.ExecuteNonQuery();
}
catch (SqlException ex)
{
throw ex;
}
}//close the SqlCommand
//Get the new set of ExpenseCycles for binding
ExpenseCycle cycle = new ExpenseCycle(ConnectionString);
return cycle.GetExpenseCycles(portalId);
//This might fix your problem.
}
The other option is to move the second call outside the using of the first using block like so
bool insertSuccessful;
using (SqlConnection oConn = new SqlConnection(ConnectionString))
{
using (SqlCommand cmd = new SqlCommand("IC_Expense_InsertCycle", oConn))
{
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("#PortalId", portalId);
cmd.Parameters.AddWithValue("#Description", description);
cmd.Parameters.AddWithValue("#StartDate", start);
cmd.Parameters.AddWithValue("#EndDate", end);
try
{
oConn.Open();
cmd.ExecuteNonQuery();
insertSuccessful=true;
}
catch (SqlException ex)
{
insertSuccessful=false
throw ex;
}
}//close the SqlCommand
}//close the connection
//Get the new set of ExpenseCycles for binding
if(insertSuccessful)
{
ExpenseCycle cycle = new ExpenseCycle(ConnectionString);
return cycle.GetExpenseCycles(portalId);
}
I think the first block should fix your problem. If not the second one definitely should.

Connection is closed exception

I'm new to C# and trying to establish a C# db connection. But I'm getting an exception.
ExecuteReader requires an open and available Connection. The connection's current state is closed.
following is the code
public void executeCommand()
{
SqlConnection con = new SqlConnection(connectionString);
try
{
con.Open();
}
catch (Exception ex)
{
}
SqlDataReader rdr = null;
SqlCommand cmd = new SqlCommand("SELECT * FROM Employees", con);
try
{
rdr = cmd.ExecuteReader();
}
catch (Exception)
{
throw;
}
rdr.Close();
// rdr.Close();
}
and this is my connection string
public static string connectionString =
"Data Source=(local);Initial Catalog=service;User Id='mayooresan';Password='password';";
Thanks for your time in advance.
Most probabbly connection object fails to open a connection, but as you are catching it, you can not figure out the error. To be clear:
try
{
con.Open();
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString()); //ADD THIS STRING FOR DEBUGGING, TO SEE IF THERE IS AN EXCEPTION.
}
Hope this helps.
You are catching any exceptions when opening the connection. Most likely the connection is not opening and is throwing an error. Remove the try/catch at the opening of the connection and you will probably see why the connection is not open
You don't close the connection and reader when an exception was raised, therefor you need to use the finally-block of a try/catch or the using-statement which closes implicitely:
using (SqlConnection connection = new SqlConnection(connectionString))
{
using(SqlCommand command = new SqlCommand(queryString, connection)
{
connection.Open();
using(SqlDataReader reader = command.ExecuteReader())
{
while (reader.Read())
{
// do something with it
}
}
}
}
Apart from that you should not use empty catch blocks. If a connection cannot be opened, it cannot be used. Then you should log that and throw the exception, but don't act as if nothing had happened.
Try wrapping everything in one try-catch block. As it stands now, if an exception is thrown when you try to open the connection, it will fail silently. Try this code instead:
try
{
SqlConnection con = new SqlConnection(connectionString);
SqlDataReader rdr = null;
SqlCommand cmd = new SqlCommand("SELECT * FROM Employees", con);
rdr = cmd.ExecuteReader();
}
catch(Exception)
{
throw;
}
are you debugging the code?
if not, you wont be able to see the exception because you don't have anything on your catch
Also I suggest this approach to use on your scenario:
using (SqlConnection connection = new SqlConnection(connectionString))
{
connection.Open();
SqlCommand command = new SqlCommand(queryString, connection);
SqlDataReader reader = command.ExecuteReader();
while (reader.Read())
{
Console.WriteLine(String.Format("{0}", reader[0]));
}
}

in a "using" block is a SqlConnection closed on return or exception?

First question:
Say I have
using (SqlConnection connection = new SqlConnection(connectionString))
{
connection.Open();
string storedProc = "GetData";
SqlCommand command = new SqlCommand(storedProc, connection);
command.CommandType = CommandType.StoredProcedure;
command.Parameters.Add(new SqlParameter("#EmployeeID", employeeID));
return (byte[])command.ExecuteScalar();
}
Does the connection get closed? Because technically we never get to the last } as we return before it.
Second question:
This time I have:
try
{
using (SqlConnection connection = new SqlConnection(connectionString))
{
int employeeID = findEmployeeID();
connection.Open();
SqlCommand command = new SqlCommand("UpdateEmployeeTable", connection);
command.CommandType = CommandType.StoredProcedure;
command.Parameters.Add(new SqlParameter("#EmployeeID", employeeID));
command.CommandTimeout = 5;
command.ExecuteNonQuery();
}
}
catch (Exception) { /*Handle error*/ }
Now, say somewhere in the try we get an error and it gets caught. Does the connection still get closed? Because again, we skip the rest of the code in the try and go directly to the catch statement.
Am I thinking too linearly in how using works? ie Does Dispose() simply get called when we leave the using scope?
Yes
Yes.
Either way, when the using block is exited (either by successful completion or by error) it is closed.
Although I think it would be better to organize like this because it's a lot easier to see what is going to happen, even for the new maintenance programmer who will support it later:
using (SqlConnection connection = new SqlConnection(connectionString))
{
int employeeID = findEmployeeID();
try
{
connection.Open();
SqlCommand command = new SqlCommand("UpdateEmployeeTable", connection);
command.CommandType = CommandType.StoredProcedure;
command.Parameters.Add(new SqlParameter("#EmployeeID", employeeID));
command.CommandTimeout = 5;
command.ExecuteNonQuery();
}
catch (Exception)
{
/*Handle error*/
}
}
Yes to both questions. The using statement gets compiled into a try/finally block
using (SqlConnection connection = new SqlConnection(connectionString))
{
}
is the same as
SqlConnection connection = null;
try
{
connection = new SqlConnection(connectionString);
}
finally
{
if(connection != null)
((IDisposable)connection).Dispose();
}
Edit: Fixing the cast to Disposable
http://msdn.microsoft.com/en-us/library/yh598w02.aspx
Here is my Template. Everything you need to select data from an SQL server. Connection is closed and disposed and errors in connection and execution are caught.
string connString = System.Configuration.ConfigurationManager.ConnectionStrings["CompanyServer"].ConnectionString;
string selectStatement = #"
SELECT TOP 1 Person
FROM CorporateOffice
WHERE HeadUpAss = 1 AND Title LIKE 'C-Level%'
ORDER BY IntelligenceQuotient DESC
";
using (SqlConnection conn = new SqlConnection(connString))
{
using (SqlCommand comm = new SqlCommand(selectStatement, conn))
{
try
{
conn.Open();
using (SqlDataReader dr = comm.ExecuteReader())
{
if (dr.HasRows)
{
while (dr.Read())
{
Console.WriteLine(dr["Person"].ToString());
}
}
else Console.WriteLine("No C-Level with Head Up Ass Found!? (Very Odd)");
}
}
catch (Exception e) { Console.WriteLine("Error: " + e.Message); }
if (conn.State == System.Data.ConnectionState.Open) conn.Close();
}
}
* Revised: 2015-11-09 *
As suggested by NickG; If too many braces are annoying you, format like this...
using (SqlConnection conn = new SqlConnection(connString))
using (SqlCommand comm = new SqlCommand(selectStatement, conn))
{
try
{
conn.Open();
using (SqlDataReader dr = comm.ExecuteReader())
if (dr.HasRows)
while (dr.Read()) Console.WriteLine(dr["Person"].ToString());
else Console.WriteLine("No C-Level with Head Up Ass Found!? (Very Odd)");
}
catch (Exception e) { Console.WriteLine("Error: " + e.Message); }
if (conn.State == System.Data.ConnectionState.Open) conn.Close();
}
Then again, if you work for EA or DayBreak games, you can just forgo any line-breaks as well because those are just for people who have to come back and look at your code later and who really cares? Am I right? I mean 1 line instead of 23 means I'm a better programmer, right?
using (SqlConnection conn = new SqlConnection(connString)) using (SqlCommand comm = new SqlCommand(selectStatement, conn)) { try { conn.Open(); using (SqlDataReader dr = comm.ExecuteReader()) if (dr.HasRows) while (dr.Read()) Console.WriteLine(dr["Person"].ToString()); else Console.WriteLine("No C-Level with Head Up Ass Found!? (Very Odd)"); } catch (Exception e) { Console.WriteLine("Error: " + e.Message); } if (conn.State == System.Data.ConnectionState.Open) conn.Close(); }
Phew... OK. I got that out of my system and am done amusing myself for a while. Carry on.
Dispose simply gets called when you leave the scope of using. The intention of "using" is to give developers a guaranteed way to make sure that resources get disposed.
From MSDN:
A using statement can be exited either when the end of the using statement is reached or if an exception is thrown and control leaves the statement block before the end of the statement.
Using generates a try / finally around the object being allocated and calls Dispose() for you.
It saves you the hassle of manually creating the try / finally block and calling Dispose()
In your first example, the C# compiler will actually translate the using statement to the following:
SqlConnection connection = new SqlConnection(connectionString));
try
{
connection.Open();
string storedProc = "GetData";
SqlCommand command = new SqlCommand(storedProc, connection);
command.CommandType = CommandType.StoredProcedure;
command.Parameters.Add(new SqlParameter("#EmployeeID", employeeID));
return (byte[])command.ExecuteScalar();
}
finally
{
connection.Dispose();
}
Finally statements will always get called before a function returns and so the connection will be always closed/disposed.
So, in your second example the code will be compiled to the following:
try
{
try
{
connection.Open();
string storedProc = "GetData";
SqlCommand command = new SqlCommand(storedProc, connection);
command.CommandType = CommandType.StoredProcedure;
command.Parameters.Add(new SqlParameter("#EmployeeID", employeeID));
return (byte[])command.ExecuteScalar();
}
finally
{
connection.Dispose();
}
}
catch (Exception)
{
}
The exception will be caught in the finally statement and the connection closed. The exception will not be seen by the outer catch clause.
I wrote two using statements inside a try/catch block and I could see the exception was being caught the same way if it's placed within the inner using statement just as ShaneLS example.
try
{
using (var con = new SqlConnection(#"Data Source=..."))
{
var cad = "INSERT INTO table VALUES (#r1,#r2,#r3)";
using (var insertCommand = new SqlCommand(cad, con))
{
insertCommand.Parameters.AddWithValue("#r1", atxt);
insertCommand.Parameters.AddWithValue("#r2", btxt);
insertCommand.Parameters.AddWithValue("#r3", ctxt);
con.Open();
insertCommand.ExecuteNonQuery();
}
}
}
catch (Exception ex)
{
MessageBox.Show("Error: " + ex.Message, "UsingTest", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
No matter where's the try/catch placed, the exception will be caught without issues.
Old thread but still relevant. I arrived here looking for a way out of having a using statement inside of a using statement. I am happy with this, notwithstanding any future insightful comments that change my mind. ;) Conversations here helped. Thanks. Simplified for readability -
public DataTable GetExchangeRates()
{
DataTable dt = new DataTable();
try
{
logger.LogInformation($"Log a message.");
string conStr = _config.GetConnectionString("conStr");
using (SqlCommand cmd = new SqlCommand("someProc", new SqlConnection(conStr)))
{
cmd.CommandType = CommandType.StoredProcedure;
cmd.Connection.Open();
dt.Load(cmd.ExecuteReader());
}
return dt;
}
catch (Exception ex)
{
logger.LogError(ex, ex.Message);
}
}

The C# using statement, SQL, and SqlConnection

Is this possible using a using statement C# SQL?
private static void CreateCommand(string queryString,
string connectionString)
{
using (SqlConnection connection = new SqlConnection(
connectionString))
{
SqlCommand command = new SqlCommand(queryString, connection);
command.Connection.Open();
command.ExecuteNonQuery();
}
}
What if there’s a error while opening the connection?
The using statement is try and finally
No catch
So if I catch outside the using brackets will the catch catch the connection opening error?
If not, how to implement this with using the using statement a shown above?
It's possible to do so in C# (I also see that code is exactly shown in MSDN http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlcommand.executenonquery.aspx). However, if you need to be defensive and for example log potential exceptions which would help troubleshooting in a production environment, you can take this approach:
private static void CreateCommand(string queryString,
string connectionString)
{
using (SqlConnection connection = new SqlConnection(
connectionString))
{
try
{
SqlCommand command = new SqlCommand(queryString, connection);
command.Connection.Open();
command.ExecuteNonQuery();
}
catch (InvalidOperationException)
{
//log and/or rethrow or ignore
}
catch (SqlException)
{
//log and/or rethrow or ignore
}
catch (ArgumentException)
{
//log and/or rethrow or ignore
}
}
}
If you want to catch any error then you'll need to wrap everything in try - catch block. using blocks simply ensure that non-managed resources are disposed, they cannot handle exceptions.
Also,SqlCommand implements IDisposable, so I'd suggest putting that in a using block as well.
Just write it out explicitely:
SqlConnection connection = new SqlConnection(connectionString);
try
{
using (SqlCommand command = new SqlCommand(queryString, connection))
{
command.Connection.Open();
command.ExecuteNonQuery();
}
}
catch (Exception e)
{
// ...handle, rethrow. Also, you might want to catch
// more specific exceptions...
}
finally
{
connection.Close();
}
Yes, you can put the using block in a try block, and the following catch will catch any errors related to the try block.
Add a unique index to the database for the fields and catch the error.
Don't reinstantiate the SQL Connection for each row. Opening and closing a connection is resource intensive. Try something like this:
protected void btn_insert_Click(object sender, EventArgs e)
{
string connStr = "your connection string";
SqlCommand cmd;
using (SqlConnection con = new SqlConnection(connStr))
{
con.Open();
foreach (GridViewRow g1 in GridView1.Rows)
{
try
{
cmd = new SqlCommand("command text", con);
cmd.ExecuteNonQuery();
}
catch (SqlException sqlEx)
{
//Ignore the relevant Sql exception for violating a sql unique index
}
}
}
}

Categories