I've this function, wich updates some records on an Azure SQL DB. The function is called every 10 minutes by a timer:
static public bool CaricaOccupazioniiMae(DataTable dtOccupazioni)
{
using (SqlConnection conn = new SqlConnection(GetSQLAzureConnectionStringiMae()))
{
conn.Open();
using (SqlTransaction tr = conn.BeginTransaction())
{
using (SqlCommand SQLCmd = new SqlCommand("DELETE_t_Promemoria", conn))
{
try
{
SQLCmd.CommandType = CommandType.StoredProcedure;
SQLCmd.Parameters.Add("#CodScuola", mCodiceScuolaiMae);
SQLCmd.Transaction = tr;
SQLCmd.ExecuteNonQuery();
}
catch (System.Exception ex)
{
tr.Rollback();
tr.Dispose();
return false;
}
}
using (SqlBulkCopy SQLCopy = new SqlBulkCopy(conn, SqlBulkCopyOptions.Default, tr))
{
try
{
SQLCopy.DestinationTableName = "t_Promemoria";
SQLCopy.WriteToServer(dtOccupazioni);
}
catch (System.Exception ex)
{
tr.Rollback();
tr.Dispose();
return false;
}
}
tr.Commit();
}
conn.Close();
}
return true;
}
in two occasions the function just hanged in there... The only thing I'm sure of, is that it haven't reach this block, meanwhile it goes through the conn.open():
SQLCmd.CommandType = CommandType.StoredProcedure;
SQLCmd.Parameters.Add("#CodScuola", mCodiceScuolaiMae);
SQLCmd.Transaction = tr;
SQLCmd.ExecuteNonQuery();
so the logical conclusion is that it hangs in one of those 2 points:
1) SqlTransaction tr = conn.BeginTransaction()
2) SqlCommand SQLCmd = new SqlCommand("DELETE_t_Promemoria", conn);
Have you any clues?
Thanks in advance!
Although I don't see too much wrong with your code, a bit of refactoring might work. If a transaction is not "committed" it will be rolled back by default and a bit less try/catch in there might help avoid resource lock:
using (SqlConnection conn = new SqlConnection(GetSQLAzureConnectionStringiMae()))
{
conn.Open();
using (SqlTransaction tr = conn.BeginTransaction())
{
try
{
using (SqlCommand SQLCmd = new SqlCommand("DELETE_t_Promemoria", conn))
{
SQLCmd.CommandType = CommandType.StoredProcedure;
SQLCmd.Parameters.Add("#CodScuola", mCodiceScuolaiMae);
SQLCmd.Transaction = tr;
SQLCmd.ExecuteNonQuery();
}
using (SqlBulkCopy SQLCopy = new SqlBulkCopy(conn, SqlBulkCopyOptions.Default, tr))
{
SQLCopy.DestinationTableName = "t_Promemoria";
SQLCopy.WriteToServer(dtOccupazioni);
}
tr.Commit();
}
catch (Exception ex)
{
tr.Rollback();
}
}
conn.Close();
}
return true;
}
If you really need to do both SQL operations (SqlCommand and SqlBulkCopy) in a different transaction, create a new one for each. The way I structured it above does everything in the same transaction and might solve your problem.
Related
I'm getting this error on phpMyAdmin
mysqli_connect(): (08004/1040): Too many connections
The only script that is using this DB:
public static bool checkIp(string ip)
{
Console.WriteLine("CHECKIP");
try
{
string sql = " SELECT * FROM `Ip tables` ";
MySqlConnection con = new MySqlConnection("host=hostname;user=username;password=password;database=database;");
MySqlCommand cmd = new MySqlCommand(sql, con);
con.Open();
MySqlDataReader reader = cmd.ExecuteReader();
while (reader.Read())
{
if (ip == reader.GetString("Ip"))
{
Console.WriteLine("Benvenuto, " + reader.GetString("Name"));
con.Close();
return true;
}
}
con.Close();
return false;
}
catch(SqlException exp)
{
throw new InvalidOperationException("Error", exp);
}
}
Does this code close the connection correctly or something is wrong?
EDIT:
I added this block after the catch block
finally
{
if(con.State == System.Data.ConnectionState.Open)
{
con.Close();
}
}
Any better way to write the code? Would finaly block still run if return is executed?
You should put your query in a using statement like this:
string conString= "host=hostname;user=username;password=password;database=database;"
using (MySqlConnection con = new MySqlConnection(conString))
{
con.Open();
using (MySqlCommand com = con.CreateCommand())
{
com.CommandText = "SELECT * FROM `Ip tables`";
using (MySqlDataReader dr = com.ExecuteReader())
{
while (reader.Read())
{
if (ip == reader.GetString("Ip"))
{
Console.WriteLine("Benvenuto, " + reader.GetString("Name"));
con.Close();
return true;
}
}
}
}
}
This will automatically close the connection without having to state con.Close()
I need delete data in oracle 10g database from ASP.NET 2.0 web site.
Method DeleteMonthPlan I use on execute delete command. Problem is that this command is executing long time "in browser" and finally delete command is not executed. Maybe it waits on commit? What is root of problem?
This SQL command DELETE C_PPC_PLAN WHERE MFG_MONTH='VALUE' is OK.
MFG_MONTH column type is VARCHAR2(16)
First I need call method DeleteMonthPlan and than I need call InsertDatePlan.
private static void DeleteMonthPlan(string monthIndex)
{
try
{
using (var conn = new OracleConnection(GenerateConnectionString()))
{
conn.Open();
var cmd = conn.CreateCommand();
cmd.CommandText = string.Format("DELETE C_PPC_PLAN WHERE MFG_MONTH='{0}'", monthIndex);
cmd.ExecuteNonQuery();
}
}
catch (Exception exception)
{
throw exception;
}
}
For example this method I use on insert and it is OK.
public void InsertDatePlan(DatePlan dp,
string monthIndex)
{
DeleteMonthPlan(monthIndex);
try
{
using (var conn = new OracleConnection(GenerateConnectionString()))
{
conn.Open();
var cmd = conn.CreateCommand();
cmd.Parameters.Add(":Site", OracleType.VarChar).Value = dp.Site;
cmd.Parameters.Add(":Week", OracleType.VarChar).Value = dp.MfgWeek;
cmd.Parameters.Add(":Month", OracleType.VarChar).Value = dp.MfgMonth;
cmd.Parameters.Add(":Year", OracleType.VarChar).Value = dp.MfgYear;
cmd.Parameters.Add(":Input", OracleType.Number).Value = dp.Input;
cmd.Parameters.Add(":Output", OracleType.Number).Value = dp.Output;
cmd.Parameters.Add(":LMUser", OracleType.VarChar).Value = dp.LmUser;
cmd.Parameters.Add(":PartNo", OracleType.VarChar).Value = dp.PartNo;
cmd.Parameters.Add(":PartNoDesc", OracleType.VarChar).Value = dp.PartNoDesc;
cmd.CommandText = string.Format("INSERT INTO C_PPC_PLAN (CREATE_TIME, SITE, MFG_DAY,MFG_WEEK,MFG_MONTH,MFG_YEAR,INPUT,OUTPUT,LM_TIME,LM_USER,PART_NO,PART_NO_DESC)"
+ " VALUES (to_date('{0}', 'dd-mm-yyyy hh24:mi:ss'), :Site ,to_date('{1}', 'dd-mm-yyyy hh24:mi:ss'),:Week,"
+ ":Month,:Year,:Input,:Output,to_date('{2}', 'dd-mm-yyyy hh24:mi:ss'),:LMUser,:PartNo,:PartNoDesc)"
, dp.CreateTime, dp.MfgDate, dp.LmTime);
cmd.ExecuteNonQuery();
}
}
catch (Exception exception)
{
throw exception;
}
}
I tried use transaction. I call this method on the bottom but is never finish it means that part
trans.Rollback(); or conn.Close(); is never executed.
private static void DeleteMonthPlan(string monthIndex)
{
var conn = new OracleConnection(GenerateConnectionString());
conn.Open();
OracleCommand cmd= conn.CreateCommand();
OracleTransaction trans = conn.BeginTransaction(IsolationLevel.ReadCommitted);
cmd.Transaction = trans;
try
{
cmd.CommandText = "DELETE C_PPC_PLAN WHERE MFG_MONTH='6'";
cmd.ExecuteNonQuery();
trans.Commit();
}
catch (Exception e)
{
trans.Rollback();
}
finally
{
conn.Close();
}
}
try
DELETE FROM C_PPC_PLAN WHERE MFG_MONTH='6'
BTW your code uses "literals" in some places instead of bind variables (params) which makes it vulnerable to SQL injection which is a really serious security problem!
I have a bunch of methods like so in my DAL in VS 2010. When I run the "new" Code Analysis option i get the message - Warning CA2000 object 'comm' is not disposed along all exception paths. Call System.IDisposable.Dispose on object 'comm' before all references to it are out of scope.
I understand I could use another using statement for the SQLCommand however if prefer to do it like I have with the Try/Finally block. My understanding is the Finally block executes last and does the cleanup. Does anyone see anything wrong here with my dispose call?
public List<Product> GetAllProducts()
{
List<Product> prodList = new List<Product>();
using (SqlConnection connection = new SqlConnection(GetConnection()))
{
SqlCommand comm = new SqlCommand("GetAllProducts", connection);
connection.Open();
comm.CommandType = CommandType.StoredProcedure;
SqlDataReader dr = comm.ExecuteReader();
try
{
while (dr.Read())
{
Product obj = new Product();
obj.ProductID = Convert.ToInt32(dr["ProductID"].ToString());
obj.Product = dr["Product"].ToString();
//etc....
prodList.Add(obj);
}
}
finally
{
comm.Dispose();
dr.Close();
}
}
return prodList;
}
}
If any of these three statements throw an exception, comm will not be disposed.
connection.Open();
comm.CommandType = CommandType.StoredProcedure;
SqlDataReader dr = comm.ExecuteReader();
Your try block would need to encompas these statements as well.
Put a using block around the command and dataReader so that they will always be disposed.
public List<Product> GetAllProducts()
{
List<Product> prodList = new List<Product>();
using (SqlConnection connection = new SqlConnection(GetConnection()))
{
using (SqlCommand comm = new SqlCommand("GetAllProducts", connection))
{
connection.Open();
comm.CommandType = CommandType.StoredProcedure;
using (SqlDataReader dr = comm.ExecuteReader())
{
try
{
while (dr.Read())
{
Product obj = new Product();
obj.ProductID = Convert.ToInt32(dr["ProductID"].ToString());
obj.Product = dr["Product"].ToString();
//etc....
prodList.Add(obj);
}
}
}
}
}
return prodList;
}
List<Measure_Type> MeasureList = new List<Measure_Type>();
SqlConnection conn = null;
SqlDataReader rdr = null;
SqlCommand cmd = null;
try
{
conn = new SqlConnection();
conn.ConnectionString = System.Configuration.ConfigurationManager.AppSettings["Conn"];
conn.Open();
cmd = new SqlCommand("SELECT Measure_ID, Mea_Name FROM MeasureTable WHERE IsActive=1", conn);
rdr = cmd.ExecuteReader();
if (rdr.HasRows == true)
{
while (rdr.Read())
{
MeasureTypeList.Add(new Measure_Type { MeasureTypeID = Convert.ToInt32(rdr[0]), MeasureTypeName = rdr[1].ToString() });
}
}
}
catch (Exception ex)
{
ExceptionPolicy.HandleException(ex, "Log");
}
finally
{
cmd.Dispose();
// close the reader
if (rdr != null) { rdr.Close(); }
// Close the connection
if (conn != null) { conn.Dispose(); }
}
return MeasureTypeList;
create conn = new SqlConnection(); inside the try block and then open it to solve this bug.
SERVER A: public string connStr = "Data Source=PH-09-5336;Initial Catalog=InventoryDB;Integrated Security=True";
SERVER B: public string connWIP = "Data Source=PWODU-COGNOSDB3;Initial Catalog=BI_SOURCE;
I have this method of inserting records to InventoryDB.DBO.FG_FILLIN from excell file.
Select records from BI_SOURCE.dbo.ODU_WIP_PI then update the null records(item Number) on InventoryDB.DBO.FG_FILLIN if its serialnumber is match on BI_SOURCE.dbo.ODU_WIP_PI serialnumber.
Problems:
I have tried to updated 13000 of records and it takes 5 minutes to be updated.
I need to update the new inserted record InventoryDB.DBO.FG_FILLIN that has only itemnumber that have null records.
But in my code it loops and update again all records in InventoryDB.DBO.FG_FILLIN
I really stack in this problem.
-------------------------------------INSERT RECORDS----------------------------------------
using (SqlConnection conn = new SqlConnection(connStr))
{
using (SqlCommand cmd = new SqlCommand("Insert into dbo.FG_FILLIN Select * FROM OPENROWSET('Microsoft.Jet.OLEDB.4.0','Excel 8.0;Database=" + filepath1 + ";HDR=YES','SELECT * FROM [" + Sheetname1 + "$]')", conn))
{
try
{
conn.Open();
cmd.ExecuteNonQuery();
txtsheet1.Text = string.Empty;
txtpath1.Text = string.Empty;
txtpath1.Focus();
MessageBox.Show("FILL IN Mass Upload Success!");
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
txtsheet1.Text = string.Empty;
txtpath1.Text = string.Empty;
txtpath1.Focus();
}
finally
{
if (conn.State == ConnectionState.Open) cmd.Connection.Close();
conn.Close();
}
}
---------------------------------SELECT UPDATE -----------------------------------
public void Update()
{
using (SqlConnection conn = new SqlConnection(connWIP))
{
try
{
conn.Open();
using (SqlDataAdapter dAd = new SqlDataAdapter("select WIP_serialNumber, WIP_ItemID from BI_SOURCE.dbo.ODU_WIP_PI", conn))
{
DataTable data = new DataTable();
dAd.Fill(data);
using (SqlConnection conn2 = new SqlConnection(connStr))
{
conn2.Open();
try
{
foreach (DataRow recordFromServerA in data.Rows)
{
using (SqlCommand dCmd = new SqlCommand("update [dbo].[FG_FILLIN] SET ItemNumber=#ItemNumber where SerialNumber=#SerialNumber", conn2))
{
dCmd.Parameters.AddWithValue("#ItemNumber", recordFromServerA["WIP_ItemAlias"]);
dCmd.Parameters.AddWithValue("#SerialNumber", recordFromServerA["WIP_serialNumber"]);
dCmd.ExecuteNonQuery();
}
}
}
catch (Exception ee)
{
MessageBox.Show(ee.Message);
}
finally
{
if (conn2.State == ConnectionState.Open) conn2.Close();
}
}
}
MessageBox.Show("All Records Updated Successfully!");
}
catch (Exception ee)
{
MessageBox.Show(ee.Message);
}
finally
{
if (conn.State == ConnectionState.Open) conn.Close();
}
}
}
#endregion
If I've understood your problem correctly you might be able to speed up the update process considerably by just executing a single SQL statement, rather than looping through each row individually.
How about this? After you've loaded your records into table A (FG_FILLIN), create an SQL UPDATE statement that uses a join from table A onto table B where the ItemNumber field in table A is null. Something like this should do it:
UPDATE [dbo].[FG_FILLIN]
SET ItemNumber = table2.WIP_ItemID
FROM [dbo].[FG_FILLIN] INNER JOIN BI_SOURCE.dbo.ODU_WIP_PI as table2
ON [dbo].[FG_FILLIN].SerialNumber = table2.WIP_SerialNumber
WHERE [dbo].[FG_FILLIN].ItemNumber IS NULL
another thing,
you could also wrap you stuff into a
using(var scope = new TransactionScope())
{
stuff
scope.Complete();
}
to make it a transaction
Does the following code leave the connection open if there is an exception?
I am using a Microsoft SQL compact edition database.
try
{
SqlCeConnection conn = new SqlCeConnection(ConnectionString);
conn.Open();
using (SqlCeCommand cmd =
new SqlCeCommand("SELECT stuff FROM SomeTable", conn))
{
// do some stuff
}
conn.Close();
}
catch (Exception ex)
{
ExceptionManager.HandleException(ex);
}
Surely a better way would be to declare a connection object before the try, establish a connection inside the try block and close it in a finally block?
SqlCeConnection conn = null;
try
{
conn = new SqlCeConnection(ConnectionString);
conn.Open();
using (SqlCeCommand cmd =
new SqlCeCommand("SELECT stuff FROM SomeTable", conn))
{
// do some stuff
}
}
catch (Exception ex)
{
ExceptionManager.HandleException(ex);
}
finally
{
if( conn != null ) conn.Close();
}
The way you are handling SqlCeCommand in your code with the help of a using block, you could do the same for the SqlCeConnection.
SqlCeConnection conn;
using (conn = new SqlCeConnection(ConnectionString))
{
conn.Open();
using (SqlCeCommand cmd =
new SqlCeCommand("SELECT stuff FROM SomeTable", conn))
{
// do some stuff
}
}
Note: You can use a using block for classes that implement IDisposable.
EDIT: This is same as
try
{
conn = new SqlCeConnection(ConnectionString);
conn.Open();
SqlCeCommand cmd = conn.CreateCommand();
cmd.CommandText = "...";
cmd.ExecuteNonQuery();
}
finally
{
conn.Close();
}
ref: http://msdn.microsoft.com/en-us/library/system.data.sqlserverce.sqlceconnection%28VS.80%29.aspx
Use Using
using(SqlConnection conn = new SqlConnection())
{
//put all your code here.
}
try
catch
finally
is the proper way to handle this, because connection should always be closed at the end. but you should check not only that conn != null, but also if conn state is not Closed.
You should use using statement, which handles the connection closing without hassles
http://davidhayden.com/blog/dave/archive/2005/01/13/773.aspx
You Have To Try Following Way.
Because Connection Close In Finally Block
try
{
SqlCeConnection conn = new SqlCeConnection(ConnectionString);
conn.Open();
using (SqlCeCommand cmd =
new SqlCeCommand("SELECT stuff FROM SomeTable", conn))
{
// do some stuff
}
}
catch (Exception ex)
{
}
finally
{
\\close connection here
}
Why not use a using around the connection as well as the SqlCeCommand ?