c# Connection must be valid and open to commit transaction TransactionScope - c#

I'm using Transactions on my Dao and in particular I'm using the TransactionScope object for the first time. But when I compile and start my procedure on my pc the method I wrote in will give me this error:
Connection must be valid and open to commit transaction
code:
public String insert(NewsVo news)
{
string query = "";
MySqlCommand cmd = null;
try
{
using (TransactionScope scope = new TransactionScope())
{
using (MySqlConnection conn = new MySqlConnection("Server=localhost;Uid=root;Pwd=root;Database=Sql300365_1"))
{
conn.Open();
Int32 numTotali = Int32.Parse(getCount());
for (int i = numTotali - 1; i >= 0; i--)
{
query = "UPDATE " + table + " SET " + table + ".Priorita = ?PrioritaSet WHERE Priorita = ?Priorita";
cmd = new MySqlCommand(query, conn);
cmd.Parameters.Add("?Priorita", MySqlDbType.Int64).Value = i;
cmd.Parameters.Add("?PrioritaSet", MySqlDbType.Int64).Value = i + 1;
cmd.ExecuteReader();
}
query = "INSERT INTO " + table + " (Priorita, Data, Titolo) VALUES (0, ?Data, ?Titolo)";
cmd = new MySqlCommand(query, conn);
//cmd.Transaction = Transazione;
cmd.Parameters.Add("?Data", MySqlDbType.VarChar, ConstDao.LENGHT_NEWS_DATA).Value = news.Data;
cmd.Parameters.Add("?Titolo", MySqlDbType.VarChar, ConstDao.LENGHT_NEWS_TITOLO).Value = news.Titolo;
cmd.ExecuteReader();
news.IdNumber = cmd.LastInsertedId.ToString();
scope.Complete();
}
}
}
catch (Exception ex)
{
throw new Exception(ex.Message.ToString());
}
finally
{
cmd.Dispose();
}
return news.IdNumber;
}

You need to move scope.Complete(); within your connection using as it is being disposed before you are completing your scope. Also, change your calls to use ExecuteNonQuery as opposed to ExecuteReader, as you are opening a SqlDataReader and not disposing of it.
using (MySqlConnection conn = new MySqlConnection("Server=localhost;Uid=root;Pwd=root;Database=Sql300365_1"))
{
conn.Open();
Int32 numTotali = Int32.Parse(getCount());
for (int i = numTotali - 1; i >= 0; i--)
{
query = "UPDATE " + table + " SET " + table + ".Priorita = ?PrioritaSet WHERE Priorita = ?Priorita";
cmd = new MySqlCommand(query, conn);
cmd.Parameters.Add("?Priorita", MySqlDbType.Int64).Value = i;
cmd.Parameters.Add("?PrioritaSet", MySqlDbType.Int64).Value = i + 1;
cmd.ExecuteNonQuery();
}
query = "INSERT INTO " + table + " (Priorita, Data, Titolo) VALUES (0, ?Data, ?Titolo)";
cmd = new MySqlCommand(query, conn);
cmd.Parameters.Add("?Data", MySqlDbType.VarChar, ConstDao.LENGHT_NEWS_DATA).Value = news.Data;
cmd.Parameters.Add("?Titolo", MySqlDbType.VarChar, ConstDao.LENGHT_NEWS_TITOLO).Value = news.Titolo;
cmd.ExecuteNonQuery();
news.IdNumber = cmd.LastInsertedId.ToString();
scope.Complete();
}

ok Ok i have inverted using connection with scope
And I opened the connection before scope and works !
I hope it is right, thank you !
public String insert(NewsVo news)
{
string query = "";
MySqlCommand cmd = null;
try
{
using (MySqlConnection conn = new MySqlConnection("Server=localhost;Uid=root;Pwd=root;Database=Sql300365_1"))
{
using (TransactionScope scope = new TransactionScope())
{
conn.Open();
Int32 numTotali = Int32.Parse(getCount());
for (int i = numTotali - 1; i >= 0; i--)
{
query = "UPDATE " + table + " SET " + table + ".Priorita = ?PrioritaSet WHERE Priorita = ?Priorita";
cmd = new MySqlCommand(query, conn);
cmd.Parameters.Add("?Priorita", MySqlDbType.Int64).Value = i;
cmd.Parameters.Add("?PrioritaSet", MySqlDbType.Int64).Value = i + 1;
cmd.ExecuteNonQuery();
}
query = "INSERT INTO " + table + " (Priorita, Data, Titolo) VALUES (0, ?Data, ?Titolo)";
cmd = new MySqlCommand(query, conn);
cmd.Parameters.Add("?Data", MySqlDbType.VarChar, ConstDao.LENGHT_NEWS_DATA).Value = news.Data;
cmd.Parameters.Add("?Titolo", MySqlDbType.VarChar, ConstDao.LENGHT_NEWS_TITOLO).Value = news.Titolo;
cmd.ExecuteNonQuery();
news.IdNumber = cmd.LastInsertedId.ToString();
scope.Complete();
}
}
}
catch (Exception ex)
{
throw new Exception(ex.Message.ToString());
}
finally
{
cmd.Dispose();
}
return news.IdNumber;
}

Related

How can i use HiddenField id as a variable for its value in c#

I have 1000 hiddenfield. How can i put their value in sql database using for loop. Like:
for (int i = 1; i < 1000; i++)
{
Control hiddenfield = this.FindControl("HiddenField" + i);
String p = Convert.ToString(hiddenfield.Value);
string sqlquery = ("INSERT INTO [" + table_name2 + "] (CT1) VALUES ('" + p + "')");
SqlCommand command = new SqlCommand(sqlquery, Connection);
command.ExecuteNonQuery();
}
change tablename as requred!
string query = "INSERT INTO tablename ( CT1 ) VALUES ( #value )";
SqlConnection con = new SqlConnection(constr);
SqlCommand cmd = new SqlCommand(query, con);
try
{
cmd.Parameters.Add("#value", System.Data.SqlDbType.VarChar);
con.Open();
for (int i = 1; i < 1000; i++)
{
Control hiddenfield = this.FindControl("HiddenField" + i);
String p = Convert.ToString(hiddenfield.Value);
cmd.Parameters["#value"].Value = p;
cmd.ExecuteNonQuery();
}
}
catch (Exception ex)
{
//Show exception as required!
}
finally
{
con.Close();
con.Dispose();
cmd.Dispose();
}

Issue with Open DataReader which must be closed first

I am getting the following error in my code:
"There is already an open DataReader associated with this Command
which must be closed first."
I have two SqlDataReaders and I made sure that I closed the first one after loading the DataViewGrid.
Below is the function that is giving me the issue. I marked the line that is throwing the error. I've tried variations with 'try' and 'using', I've tried to rename diff SqlConnections, SqlDataReaders and SqlCommands. I am at a loss here.
Can I not have an open SqlDataReader and SqlCommand open at the same time on one connection?
private void ApprovedTransferAction(int rowNum) {
bool foundFlag = false;
//int XferQty = (int)gridData.Rows[rowNum].Cells["FinalQty"].Value;
string PorgID = "";
using (SqlConnection conn = new SqlConnection(Global.connString)) {
conn.Open();
// Locate id in PorgReqs
string sqlSelectQuery = "SELECT id FROM PorgReqs WHERE location_id = #NewLocationID AND vendor_id = #VendorID AND item_id = #Item";
using (SqlCommand sqlSelect = new SqlCommand(sqlSelectQuery, conn)) {
sqlSelect.Parameters.Add("#NewLocationID", SqlDbType.VarChar, 60).Value = gridData.Rows[rowNum].Cells["NewLocation"].Value;
sqlSelect.Parameters.Add("#VendorID", SqlDbType.VarChar, 60).Value = gridData.Rows[rowNum].Cells["Vendor"].Value;
sqlSelect.Parameters.Add("#Item", SqlDbType.VarChar, 60).Value = gridData.Rows[rowNum].Cells["Item"].Value;
using (SqlDataReader sqlDataReader2 = sqlSelect.ExecuteReader()) {
// If Item is found at Target Location; FinalQty of Source Added to AddlQty of Target
if (sqlDataReader2.HasRows) {
sqlDataReader2.Read();
PorgID = Convert.ToString(sqlDataReader2["id"]);
MessageBox.Show("Found ID: " + PorgID);
string sqlUpdateQuery = "UPDATE PorgReqs SET AddlQty += #XferQty WHERE id = #ID";
using (SqlCommand sqlUpdate = new SqlCommand(sqlUpdateQuery, conn)) {
sqlUpdate.Parameters.Add("#XferQty", SqlDbType.Int).Value = (int)gridData.Rows[rowNum].Cells["FinalQty"].Value;
sqlUpdate.Parameters.Add("#ID", SqlDbType.Int).Value = sqlDataReader2["id"];
sqlUpdate.CommandType = CommandType.Text;
sqlUpdate.ExecuteNonQuery();
} // End sqlUpdate Command
} else { // Item was not found at Target location
string sqlUpdateQuery = "UPDATE PorgReqs SET " +
" location_id = #TargetLoc, " +
" requirement_location_id = #TargetLoc, " +
" ship_to_location_id = #TargetLoc " +
" WHERE " +
" location_id = #SourceLoc AND " +
" vendor_id = #VendorID AND " +
" item_id = #Item";
using (SqlCommand sqlUpdate = new SqlCommand(sqlUpdateQuery, conn)) {
sqlUpdate.Parameters.Add("#TargetLoc", SqlDbType.Int).Value = gridData.Rows[rowNum].Cells["NewLocation"].Value;
sqlUpdate.Parameters.Add("#SourceLoc", SqlDbType.Int).Value = gridData.Rows[rowNum].Cells["Location"].Value;
sqlUpdate.Parameters.Add("#VendorID", SqlDbType.Int).Value = gridData.Rows[rowNum].Cells["Vendor"].Value;
sqlUpdate.Parameters.Add("#Item", SqlDbType.VarChar, 60).Value = gridData.Rows[rowNum].Cells["Item"].Value;
sqlUpdate.CommandType = CommandType.Text;
sqlUpdate.ExecuteNonQuery(); // ERROR HERE
} // End sqlUpdate Command
} // End Else
sqlDataReader2.Close();
}
/*} catch (Exception ex) {
Console.WriteLine(ex.Message);
MessageBox.Show("Try SQLReader: " + ex.Message);
} */
} // End sqlSelect Command
} // End SQL Connection
// See if id exists in grid
MessageBox.Show("Checking Grid");
foreach (DataGridViewRow row in gridData.Rows) {
if (foundFlag == true)
break;
else if (row.Cells["id"].Value.ToString() == PorgID) {
// Update grid
row.Cells["AddlQty"].Value = Convert.ToInt32(gridData.Rows[rowNum].Cells["FinalQty"].Value) + Convert.ToInt32(row.Cells["AddlQty"].Value);
row.Cells["FinalQty"].Value = Convert.ToInt32(row.Cells["RecQty"].Value) + Convert.ToInt32(row.Cells["AddlQty"].Value);
foundFlag = true;
MessageBox.Show("Found: " + foundFlag);
} // End If
} // End ForEach
// Remove the Row from the Grid
gridData.Rows.RemoveAt(rowNum);
}
Just add MultipleActiveResultSets=true to your connection string.

c# Writing Increasing Numbers in a While to a Database

Im trying to write "Increasing Numbers/Price" in a While with incrementing in my Database, but still didnt work...
Without a while /incrementing my other code works very well, and i get writed data in my database but with the "while code" not... can anyone help me out? thx you
namespace Testing
{
class Program
{
static void Main(string[] args)
{
SqlConnection con;
string str;
string Buyable;
Buyable = "0";
int count = 10;
double Add = 0.00000000;
for (int i = 0; i < count; i++)
{
Add = Add + 0.00000005;
try
{
str = #"..........";
con = new SqlConnection(str);
con.Open();
Console.WriteLine("Database connected");
string query = "INSERT INTO[dbo].[Table]([Price], [Buyable]) VALUES('" + Add + "'," + Buyable + ")";
SqlCommand ins = new SqlCommand(query, con);
ins.ExecuteNonQuery();
Console.WriteLine("Stored");
Console.ReadKey();
}
catch (SqlException)
{
}
}
}
}
}
Try this:
static void Main(string[] args)
{
double Add = 0D; //You really should use a **decimal** for anything to do with money!
int Buyable = 0;
int count = 10;
string str = #"..........";
string sql = "INSERT INTO[dbo].[Table]([Price], [Buyable]) VALUES(#Add, #Buyable);"; // + Add + "'," + Buyable + ")";
using (SqlConnection con = new SqlConnection(str))
using (SqlCommand ins = new SqlCommand(sql, con))
{
ins.Parameters.Add("#Add", SqlDbType.Float);
ins.Parameters.Add("#Buyable", SqlDbType.Int); //guessing at parameter type here
con.Open();
Console.WriteLine("Database connected");
for (int i = 0; i < count; i++)
{
Add += 0.00000005D;
try
{
ins.Parameters["#Add"].Value = Add;
ins.Parameters["#Buyable"].Value = Buyable;
ins.ExecuteNonQuery();
Console.WriteLine("Stored");
Console.ReadKey();
}
catch (SqlException ex)
{
//Do *something* with the exception here!
Console.WriteLine("Error using the database. The message is:\n{0}", ex.Message);
}
}
}
}
Don't leave the connection open and try to use using with all disposable objects in your C# life.
str = #"..........";
using(con = new SqlConnection(str))
{
con.Open();
Console.WriteLine("Database connected");
string query = "INSERT INTO[dbo].[Table]([Price], [Buyable]) VALUES('" + Add + "'," + Buyable + ")";
SqlCommand ins = new SqlCommand(query, con);
ins.ExecuteNonQuery();
Console.WriteLine("Stored");
Console.ReadKey();
}
Here you are writing con.Open(); in loop without closing previous connection con.Close(); which cause to throw error , write con.Close(); after ins.ExecuteNonQuery(); and try.
Another solution is Open your connection before loop and close after for loop ends .. I think this may help you

Login form with SQLite in C#

I'm having a problem making a loginform with sqlite in C#. this is the code
SQLiteConnection connectionstring;
connectionstring = " Data Source = C:\Crystal Management\Crystal Management\bin\Debug\Konaku.db; Version = 3 ";
public void LoadData()
{
try
{
SQLiteCommand SelectCommand = new SQLiteCommand("SELECT `Username`, `Password` FROM `LoginData` WHERE `Username` = '" + flatTextBox1.Text + "' AND `Password` = '" + flatTextBox2.Text + "'", connectionstring);
SQLiteDataReader myReader;
connectionstring.Open();
myReader = SelectCommand.ExecuteReader();
int count = 0;
while (myReader.Read())
{
count = count + 1;
}
if (count == 1)
{
Base bs = new Base();
bs.Show();
this.Hide();
connectionstring.Close();
}
else if (count == 0)
{
flatAlertBox1.kind = FlatUI.FlatAlertBox._Kind.Error;
flatAlertBox1.Text = "data not right";
connectionstring.Close();
}
else
{
}
}
catch (Exception ex) {
MessageBox.Show(ex.Message);
connectionstring.Close();
}
}
it is showing error in this line of code
connectionstring = " Data Source = C:\\Crystal Management\\Crystal Management\bin\\Debug\\Konaku.db; Version = 3 ";
message error is : Cannot implicitly convert type 'string' to 'Finisar.SQLite.SQLiteConnection'
what can I do with this?
This is the proper way to query SQL. Always use "using" for disposable class like SQLiteConnection, SQLiteCommand, and SQLiteDataReader. Use parameterized queries to avoid sql injection.
public void LoadData()
{
try
{
using (var conn = new SQLiteConnection(#"Data Source=C:\Crystal Management\Crystal Management\bin\Debug\Konaku.db;Version=3"))
{
conn.Open();
using (var cmd = new SQLiteCommand("SELECT Username,Password FROM LoginData WHERE Username='#username' AND Password = '#password'", conn))
{
cmd.Parameters.AddWithValue("#username", flatTextBox1.Text);
cmd.Parameters.AddWithValue("#password", flatTextBox2.Text);
using (var reader = cmd.ExecuteReader())
{
var count = 0;
while (reader.Read())
{
count = count + 1;
}
if (count == 1)
{
Base bs = new Base();
bs.Show();
Hide();
}
else if (count == 0)
{
flatAlertBox1.kind = FlatUI.FlatAlertBox._Kind.Error;
flatAlertBox1.Text = "data not right";
}
}
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
It should be like this
sql_con = new SQLiteConnection
("Data Source=C:\Crystal Management\Crystal Management\bin\Debug\Konaku.db;Version=3;New=False;Compress=True;");

Nothing happens on query execution

I have this simple code C# and SQL Server database:
int refcodenum = getOrderNum();
string refcode = "E" + refcodenum;
byte[] personalpic = getBarcode(refcodenum);
SqlCommand cm2 = new SqlCommand();
cm2.Connection = cn;
cm2.CommandText = "Update Clients set ReferenceNumber='" + refcode + "',ReferenceBarcode=#photo where NetNumber='"+id+"'";
cm2.Parameters.Add("#photo", SqlDbType.Image, personalpic.Length).Value = personalpic;
// here like cursor stop
cm2.ExecuteNonQuery();
lastpage = "x";
File.Delete(Directory.GetCurrentDirectory() + #"\myimage.jpg");
I have run it but nothing happens on query execution I used MessageBox like that to identify the line that has the problem
int refcodenum = getOrderNum();
string refcode = "E" + refcodenum;
byte[] personalpic = getBarcode(refcodenum);
SqlCommand cm2 = new SqlCommand();
cm2.Connection = cn;
MessageBox.Show("1");
cm2.CommandText = "Update Clients set ReferenceNumber='" + refcode + "',ReferenceBarcode=#photo where NetNumber='"+id+"'";
MessageBox.Show("2");
cm2.Parameters.Add("#photo", SqlDbType.Image, personalpic.Length).Value = personalpic;
MessageBox.Show("3");
// here cursor stops
cm2.ExecuteNonQuery();
// that messagebox isn't shown
MessageBox.Show("4");
lastpage = "x";
File.Delete(Directory.GetCurrentDirectory() + #"\myimage.jpg");
Any help will be appreciated
You haven't opened your Connection. See below.
You should also use the using syntax to make use of IDisposable
int refcodenum = getOrderNum();
string refcode = "E" + refcodenum;
byte[] personalpic = getBarcode(refcodenum);
var sqlCmdText = "Update Clients set ReferenceNumber='" + refcode + "',ReferenceBarcode=#photo where NetNumber='"+id+"'";
try
{
using (var sqlConnection = new SqlConnection([YOUR CONNECTION STRING HERE]))
{
using (var sqlCommand = new SqlCommand(sqlCmdText, sqlConnection))
{
sqlCommand.CommandType = CommandType.Text;
sqlCommand.Parameters.Add("#photo", SqlDbType.Image, personalpic.Length).Value = personalpic;
sqlConnection.Open();
sqlCommand.ExecuteNonQuery();
}
}
}
catch (Exception ex)
{
throw new DataException(ex.Message);
}

Categories