I have a function that reads values from specified columns. It looks like this:
private bool OpenConnection() // Just opens the connection. No error here.
{
try
{
conn.Open();
return true;
}
catch (MySqlException ex)
{
MessageBox.Show("Connection not opened");
return false;
}
}
private void getStats(string user, string cate, string score)
{
if (OpenConnection())
{
try
{
string getuserstats = $"SELECT {cate} FROM scores WHERE user = '{user}'";
MySqlCommand cmd = new MySqlCommand(getuserstats, conn);
MySqlDataReader getscore = cmd.ExecuteReader();
MessageBox.Show(getscore.Read().ToString()); //outputs false.
while(getscore.Read())//does not run
{
MessageBox.Show("Reading!");//does not run
score = getscore.GetString(0);//does not run
MessageBox.Show(score); //does not run
}
getscore.Close();
conn.Close();
}
catch (Exception ex)
{
MessageBox.Show("Error getting scores!");
conn.Close();
}
}
else
{
MessageBox.Show("Connection not opened!");
}
}
The SQL command part seems to run fine, I tested it with some different querys and they all worked fine.
However, the SQL reader itself doesn't seem to run. I do not get an exception error either.
I used a message box to show the boolean value of my reader reading, and it outputted false. Why is this?
The most likely reason that Read() returns false is that no records match the query that you're performing. Are you sure there are any records in that table matching the given user name? And that the database you are connecting to is the one you think it's connecting to.
This won't be related, but the MySqlCommand and MySqlDataReader are both disposable, as is the connection, so you should place them in "using" blocks, or explicitly dispose them.
Related
I have an application in C# which receives data from different clients and insert that data into SQL Server. I get the data every second, or even faster, but I am facing some problem with my code:
static SqlConnection objSqlConn = null;
static SqlCommand objSqlCmd = null;
public static void SaveClientHistory(String strMessage, String strClientIP)
{
try
{
using (objSqlConn = new SqlConnection(strConnectionString))
{
using (objSqlCmd = new SqlCommand("procInsertHistory", objSqlConn))
{
objSqlCmd.CommandTimeout = 0;
objSqlCmd.CommandType = CommandType.StoredProcedure;
objSqlCmd.Parameters.AddWithValue("#strMessage", strMessage);
objSqlCmd.Parameters.AddWithValue("#strClientIP", strClientIP);
objSqlConn.Open();
objSqlCmd.ExecuteNonQuery();
}
}
}
catch (Exception Ex)
{
throw Ex;
}
finally
{
if(objSqlConn != null && objSqlConn.State != ConnectionState.Closed)
{
objSqlConn.Close();
objSqlConn.Dispose();
}
}
}
Different types of exceptions occurred:
The connection was not closed. The connection's current state is connecting.
Internal connection fatal error.
ExecuteNonQuery requires an open and available Connection. The connection's current state is connecting.
Please, advise me if there is any error in above code or suggest any other way to accomplish this task.
Thanks
Edited - simplified the procedure further to better troubleshoot the issue: removed the try/catch because it wasn't doing anything helpful; method is no longer static; all inputs are now passed in as parameters - including strConnectionString; the connection timeout is explicitly set; the connection is opened before the SqlCommand object is instantiated; the command timeout is now 10 seconds.
As performance is a concern of yours, note that you should not be worried about trying to keep a connection open for re-use. By default, SQL Server connection pooling is turned on, so there is no need to attempt to cache connections with your own methodology.
There seems like there is something going on besides attempting to open a connection and executing a non-query, so I tried to simplify your code a little further. I hope it helps with troubleshooting your issue.
public int SaveClientHistory(String strConnectionString, String strMessage, String strClientIP)
{
// You can double-up using statements like this (for slightly better readability)
using (SqlConnection objSqlConn = new SqlConnection(strConnectionString))
{
objSqlConn.ConnectionTimeout = 10; // Creating a connection times out after ten seconds
objSqlConn.Open();
using (SqlCommand objSqlCmd = new SqlCommand("procInsertHistory", objSqlConn))
{
objSqlCmd.CommandTimeout = 10; // Creating a command times out after ten seconds
objSqlCmd.CommandType = CommandType.StoredProcedure;
objSqlCmd.Parameters.AddWithValue("#strMessage", strMessage);
objSqlCmd.Parameters.AddWithValue("#strClientIP", strClientIP);
return objSqlCmd.ExecuteNonQuery();
}
}
}
It seems that all three errors are related with connection. In one of my applications, I implement you function like bellow. I hope this help you:
public static void SaveClientHistory(String strMessage, String strClientIP)
{
SqlConnection objSqlConn = new SqlConnection(strConnectionString);
SqlCommand objSqlCmd = new SqlCommand("procInsertHistory", objSqlConn)
objSqlCmd.CommandType = CommandType.StoredProcedure;
objSqlCmd.Parameters.AddWithValue("#strMessage", strMessage);
objSqlCmd.Parameters.AddWithValue("#strClientIP", strClientIP);
try{
objSqlConn.Open();
objSqlCmd.ExecuteNonQuery();
}
catch (Exception Ex)
{
throw Ex;
}
finally
{
if(objSqlConn.State == ConnectionState.Open)
objSqlConn.Close();
}
}
I am trying to write a method that will check if a database connection is valid or not. Here is the code behind my Test Connection button.
private void TestConn_btn_Click(object sender, EventArgs e)
{
DbConnection DBConnTest;
if (DataSrc_cbx.SelectedIndex == 1)
{
DBConnTest = new SqlConnection("Server="+DatabaseAddress_Value+"; Database="+DatabaseName_Value+";Trusted_Connection=true");
try
{
DBConnTest.Open();
MessageBox.Show("\nTEST SUCCESSFUL\n");
}
catch (Exception exception)
{
MessageBox.Show("TEST FAILED Exception Thrown: " + exception.Message);
}
finally
{
DBConnTest.Close();
}
}
}
The problem is that there is no exception thrown when I enter an invalid Database address ( or leave it empty all together), same applies to the Database name. It only throws an exception when there is no connection string, or in an incorrect format. So my question is, How do I make it check if there is indeed a server and a database on that server with the names input?
You can apply validations on your Web Page if the fields are empty then prompt user to enter something. Now use this statement to check whether this database exist or not??
select name from sys.sysdatabases
where dbid=db_id()
for user you need to ..
SELECT id FROM user WHERE login="JohnSmith"
and see if it gives you any rows. If yes - user exists.
You can use this work-around.
You need to execute a query to connect to the database.
For SQL Server, I usually use IDbCommand.ExecuteScalar to execute:
SELECT ##VERSION
For Oracle:
SELECT banner from v$version where banner like 'Oracle%'
Would you provide the complete code, please?
It would be something like:
try
{
using(SqlConnection conn = ...)
{
conn.Open();
using(SqlCommand command = conn.CreateCommand())
{
command.CommandText = "SELECT ##VERSION";
var result = (string) command.ExecuteScalar();
MessageBox.Show("\nTEST SUCCESSFUL\n" + result);
}
}
}
catch(Exception ex)
{
MessageBox.Show("TEST FAILED Exception Thrown: " + exception.Message);
}
Your code is working for me. The issue here is that you have to wait till the SQL timeout period elapses before the exception is thrown. This will not be a method that returns an immediate answer. If you wrap this try/catch with a WaitCursor, you will at least see when the code is running.
private void TestConn_btn_Click(object sender, EventArgs e)
{
this.Cursor = Cursors.WaitCursor;
DbConnection DBConnTest;
if (DataSrc_cbx.SelectedIndex == 1)
{
DBConnTest = new SqlConnection("Server="+DatabaseAddress_Value+"; Database="+DatabaseName_Value+";Trusted_Connection=true");
try
{
DBConnTest.Open();
MessageBox.Show("\nTEST SUCCESSFUL\n");
}
catch (Exception exception)
{
MessageBox.Show("TEST FAILED Exception Thrown: " + exception.Message);
}
finally
{
DBConnTest.Close();
}
}
this.Cursor = Cursors.Default;
}
Perhaps try:
using (SqlConnection conn = new SqlConnection(builder.ToString()))
{
try
{
conn.Open();
}
catch (SqlException ex)
{
foreach (SqlError error in ex.Errors)
{
Console.WriteLine(error.Number);
}
}
catch (Exception ex)
{
}
}
It will return the DB error code (run the following query for a list of error codes:
select * from sys.messages where language_id=1033 and severity between 11 and 16
Microsoft also provide some guidance here:
http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlerror.number(v=vs.110).aspx
Your code looks incomplete!
Take this example from Microsoft.conexão c# com sql server 2008
Good luck!
I have a windows services which is performing lot of Data processing. At some point, my service is crashed on closing a SQLConnection. When I comment the Close connection method call, Service is working consistently without crashing.
What could be the problem ? Below is a code snippet
private void DeleteTempTable()
{
_logger.Info("DeleteTempTable");
try
{
foreach (KeyValuePair<string, string> item in _stables)
{
string dropSql = string.Empty;
dropSql = string.Format("DROP TABLE [{0}];", item.Value);
SqlConnection oConnDropTables = new SqlConnection(connectionString);
oConnDropTables.Open();
if (!string.IsNullOrEmpty(dropSql))
{
using (SqlCommand cmd = new SqlCommand(dropSql, oConnDropTables))
{
cmd.ExecuteNonQuery();
}
}
if (oConnDropTables != null && oConnDropTables.State == ConnectionState.Open)
oConnDropTables.Close();
oConnDropTables = null;
}
}
catch (Exception ex)
{
_logger.Error("Error " + ex.Message);
throw ex;
}
}
When I comment the Close connection, service is working without crashing. Also it is not caught in the catch block. Also Connection is not Null and connectionstate is open only..
What I have tried:
1) Put "using" construct for connection - Didn't help
2) catching SQLException to check if anything I get- Didn't help
Removing that Close() should not make any problems go away, and frankly I don't believe it has. Since you don't yet understand the problem, it is premature to assume that a random code change has fixed it. Specifically:
with the Close(), it is returning the connection to the pool each time; when you call Open(), it will get back the same connection from the pool (cleansed, except for a few minor things)
without the Close(), the previous connection will be left to be garbage collected, which can cause either the connection-pool to become saturated, or the database-server's connection count to saturate; basically - bad things
What I suspect is happening is that you had some random error, that you now aren't seeing, by random. For example, network connectivity, or the unpredictable ordering of a Dictionary<,> (which means you don't know what order the tables are being DROPped, which is very important if there are foreign keys between them).
The only major problem with the current code is that it isn't using using. There are some redundant lines, though. This would be better:
foreach (var item in _stables)
{
var dropSql = string.Format("DROP TABLE [{0}];", item.Value);
using(var oConnDropTables = new SqlConnection(connectionString))
using (var cmd = new SqlCommand(dropSql, oConnDropTables))
{
oConnDropTables.Open();
cmd.ExecuteNonQuery();
}
}
or (preferable):
using(var oConnDropTables = new SqlConnection(connectionString))
{
oConnDropTables.Open();
foreach (var item in _stables)
{
var dropSql = string.Format("DROP TABLE [{0}];", item.Value);
using (var cmd = new SqlCommand(dropSql, oConnDropTables))
{
cmd.ExecuteNonQuery();
}
}
}
The issue is the creation of a new connection object each time the loop runs. When you close a SQL Connection, it is not actually closed but its returned to the app pool ready to be re-used. There is a limited number of connections you can open in SQL at once.
Try moving the SQLConnection object out of the loop and just execute commands in the loop and close the connection after the loop finishes.
private void DeleteTempTable()
{
_logger.Info("DeleteTempTable");
try
{
using(SqlConnection oConnDropTables = new SqlConnection(connectionString))
{
oConnDropTables.Open();
foreach (KeyValuePair<string, string> item in _stables)
{
string dropSql = string.Empty;
dropSql = string.Format("DROP TABLE [{0}];", item.Value);
if (!string.IsNullOrEmpty(dropSql))
{
using (SqlCommand cmd = new SqlCommand(dropSql, oConnDropTables))
{
cmd.ExecuteNonQuery();
}
}
}
}
}
catch (Exception ex)
{
_logger.Error("Error " + ex.Message);
throw ex;
}
}
I am catching a sql exception and not rethrowing it. This seems to mean that the connection is not returned to the pool as I would expect. Is this possible?
using (IDbCommand paymentCommand = this.Connection.CreateCommand())
{
try
{
//database stuff
}
catch (SqlException ex)
{
//LOG CALL
}
}
why don't you put using(...){} inside try{} block? This way even if exception is thrown, using block will dispose off IDBcmd obj.
It's not clear in your question how you are creating the connection, but you do need to make sure you Open it, then Close it, regardless of errors or not.
Typically I'll do something like this:
SqlConnection connection = null;
try {
connection.Open();
// Do stuff like run a query, setup your IDbCommand, etc.
} catch (Exception ex) {
// Log error
} finally {
if (connection != null) {
connection.Close();
}
}
This way, no matter what happens, your connection will be closed and returned to the pool. If you fail to Close(), you'll "leak" that connection and eventually run out of pooled connections to draw from. The lifetime of the connection should generally only be as long as it takes to issue your sql command, at which point you should be closing it.
It's not clear what you are experiencing with the connection pool. However, I would definitely wrap your connection in a using statement.
This is what I usually use (note that dac.GetConnection() is simply a class that centralizes the code to get a connection object):
using (SqlConnection connection = dac.GetConnection())
{
using (SqlCommand command = new SqlCommand("myProc", connection))
{
command.CommandType = CommandType.StoredProcedure;
try
{
connection.Open();
//add params, run query
}
catch (Exception ex)
{
//handle/log errror
}
finally
{
if (connection.State == ConnectionState.Open)
connection.Close();
}
}
}
Im making a system which should be running 24/7, with timers to control it. There are many calls to the database, and at some point, two methods are trying to open a connection, and one of them will fail. I've tried to make a retry method, so my methods would succeed. With the help from Michael S. Scherotter and Steven Sudit's methods in Better way to write retry logic without goto, does my method look like this:
int MaxRetries = 3;
Product pro = new Product();
SqlConnection myCon = DBcon.getInstance().conn();
string barcod = barcode;
string query = string.Format("SELECT * FROM Product WHERE Barcode = #barcode");
for (int tries = MaxRetries; tries >= 0; tries--) //<-- 'tries' at the end, are unreachable?.
{
try
{
myCon.Open();
SqlCommand com = new SqlCommand(query, myCon);
com.Parameters.AddWithValue("#barcode", barcode);
SqlDataReader dr = com.ExecuteReader();
if (dr.Read())
{
pro.Barcode = dr.GetString(0);
pro.Name = dr.GetString(1);
}
break;
}
catch (Exception ex)
{
if (tries == 0)
Console.WriteLine("Exception: "+ex);
throw;
}
}
myCon.Close();
return pro;
When running the code, the program stops at the "for(.....)", and the exception: The connection was not closed. The connection's current state is open... This problem was the reason why I'm trying to make this method! If anyone knows how to resovle this problem, please write. Thanks
You do
myCon.Open();
inside the for loop, but
myCon = DBcon.getInstance().conn();
outside of it. This way you try to open the same connection multiple times. If you want to protect against loss of DB connection you need to put both inside teh loop
You should move the call to myCon.Open outside the for statement or wrap myCon.Open() checking the connection state before re-opening the connection:
if (myCon.State != ConnectionState.Open)
{
myCon.Open();
}
Edited for new information
How about using Transactions to preserve data integrity, getting on-the-fly connections for multiple access and wrapping them in Using statements to ensure connections are closed? eg
Using (SqlConnection myCon = new SqlConnection('ConnectionString'))
{
myCon.Open();
var transaction = myCon.BeginTransaction();
try
{
// ... do some DB stuff - build your command with SqlCommand but use your transaction and your connection
var sqlCommand = new SqlCommand(CommandString, myCon, transaction);
sqlCommand.Parameters.Add(new Parameter()); // Build up your params
sqlCommand.ExecuteNonReader(); // Or whatever type of execution is best
transaction.Commit(); // Yayy!
}
catch (Exception ex)
{
transaction.RollBack(); // D'oh!
// ... Some logging
}
myCon.Close();
}
This way even if you forget to Close the connection, it will still be done implicitly when the connection gets to the end of its Using statement.
Have you tried adding
myCon.Close();
Into a Finally block. It looks like it is never being hit if you have an exception. I would highly recommend that you wrap the connection, command object etc in Using statements. This will ensure they are disposed of properly and the connection is closed.