Transaction Not Rolling Back C# MS-Access - c#

I wrote the transaction below in C# to insert data into 4 tables in Access. I deployed the application and when one of the users is inserting data, the insert is failing and the transaction isn't rolling back. I can tell that there's a failed insert because the ID column has skipped numbers when I do have a successful insert.
Would you be able to review my code to see what could be causing this? And secondly, how could I test for this prior to deploying? I can't seem to replicate the user error.
public static void InsertIndividualOwner(TaxInfo taxInfo, OwnerAddress address, OwnerEmailAddress emailAddress, IndividualOwner owner)
{
int ownerTaxInfoID = 0;
int addressRecord = 0;
int emailRecord = 0;
int ownerRecord = 0;
int specialistID = Properties.Settings.Default.DefaultUserId;
string insertTaxInfoString = "Insert Into TaxInfo (TIN, BIRT, CAL, PIN, DateAdded, ModifiedBySpecialistID) " +
"VALUES(#TIN, #BIRT, #CAL, #PIN, Date(), #ModifiedBySpecialistID)";
string insertAddressString = "Insert Into OwnerAddress (ownerTaxInfoID, streetAddress1, streetAddress2, city, stateID, zip, country, DateAdded, ModifiedBySpecialistID) " +
"Values(#ownerTaxInfoID, #streetAddress1, #streetAddress2, #city, #stateID, #zip, #country, Date(), #ModifiedBySpecialistID)";
string insertEmailAddressString = "Insert Into OwnerEmailAddress (ownerTaxInfoID, emailAddress, DateAdded, ModifiedBySpecialistID) Values (#ownerTaxInfoID,#emailAddress, Date(), #ModifiedBySpecialistID)";
string insertOwnerNameString = "Insert Into IndividualOwner (firstName, lastName, ownerTaxInfoID, DateAdded, ModifiedBySpecialistID) " +
"VALUES(#firstName, #lastName, #ownerTaxInfoID, Date(), #ModifiedBySpecialistID)";
string selectID = "Select ##Identity";
using (OleDbConnection connection = new OleDbConnection(Constants.ACCESSCONNECTIONSTRING))
{
connection.Open();
using (OleDbTransaction transaction = connection.BeginTransaction())
{
try
{
using (OleDbCommand insertTaxInfo = new OleDbCommand(insertTaxInfoString, connection, transaction))
{
insertTaxInfo.Parameters.AddWithValue("#TIN", taxInfo.tin);
insertTaxInfo.Parameters.AddWithValue("#BIRT", taxInfo.birtNo);
if (string.IsNullOrEmpty(taxInfo.cal))
{
insertTaxInfo.Parameters.AddWithValue("#CAL", DBNull.Value);
}
else insertTaxInfo.Parameters.AddWithValue("#CAL", taxInfo.cal);
if (string.IsNullOrEmpty(taxInfo.pin))
{
insertTaxInfo.Parameters.AddWithValue("#PIN", DBNull.Value);
}
else insertTaxInfo.Parameters.AddWithValue("#PIN", taxInfo.cal);
insertTaxInfo.Parameters.AddWithValue("#ModifiedBySpecialistID", specialistID);
try
{
insertTaxInfo.ExecuteNonQuery();
insertTaxInfo.CommandText = selectID;
ownerTaxInfoID = (int)insertTaxInfo.ExecuteScalar();
}
catch (OleDbException ex)
{
throw ex;
}
}
using (OleDbCommand insertAddress = new OleDbCommand(insertAddressString, connection, transaction))
{
insertAddress.Parameters.AddWithValue("#ownerTaxInfoID", ownerTaxInfoID);
insertAddress.Parameters.AddWithValue("#streetAddress1", address.streetAddress1);
if (address.streetAddress2 == "")
{
insertAddress.Parameters.AddWithValue("#streetAddress2", DBNull.Value);
}
else insertAddress.Parameters.AddWithValue("#streetAddress2", address.streetAddress2);
insertAddress.Parameters.AddWithValue("#city", address.city);
insertAddress.Parameters.AddWithValue("#stateID", address.stateID);
insertAddress.Parameters.AddWithValue("#zip", address.zip);
insertAddress.Parameters.AddWithValue("#country", address.country);
insertAddress.Parameters.AddWithValue("#ModifiedBySpecialistID", specialistID);
try
{
insertAddress.ExecuteNonQuery();
insertAddress.CommandText = selectID;
addressRecord = (int)insertAddress.ExecuteScalar();
}
catch (OleDbException ex)
{
throw ex;
}
}
using (OleDbCommand insertEmailAddress = new OleDbCommand(insertEmailAddressString, connection, transaction))
{
insertEmailAddress.Parameters.AddWithValue("#ownerTaxInfoID", ownerTaxInfoID);
insertEmailAddress.Parameters.AddWithValue("#emailAddress", emailAddress.emailAddress);
insertEmailAddress.Parameters.AddWithValue("#ModifiedBySpecialistID", specialistID);
try
{
insertEmailAddress.ExecuteNonQuery();
insertEmailAddress.CommandText = selectID;
emailRecord = (int)insertEmailAddress.ExecuteScalar();
}
catch (OleDbException ex)
{
throw ex;
}
}
using (OleDbCommand insertOwner = new OleDbCommand(insertOwnerNameString, connection, transaction))
{
insertOwner.Parameters.AddWithValue("#firstName", owner.firstName);
insertOwner.Parameters.AddWithValue("#lastName", owner.lastName);
insertOwner.Parameters.AddWithValue("#ownerTaxInfoID", ownerTaxInfoID);
insertOwner.Parameters.AddWithValue("#ModifiedBySpecialistID", specialistID);
try
{
insertOwner.ExecuteNonQuery();
insertOwner.CommandText = selectID;
ownerRecord = (int)insertOwner.ExecuteScalar();
}
catch (OleDbException ex)
{
throw ex;
}
}
transaction.Commit();
AddOwner?.Invoke();
}
catch (Exception ex)
{
transaction.Rollback();
throw ex;
}
}
}
}

Related

Restore SQL Server database failed SMO C#

I'm trying to restore a SQL-Server database but I don't know why it's throwing exception which message is "Restore failed for server '.'".
I'm executing two methods. One is defines as CheckDatabase and second one is RestoreDatabase. If I execute RestoreDatabase method first it works fine, but if I execute it after CheckDatabase method it explodes
This is my CheckDatabase():
private static void CheckDatabase(string period)
{
string connString = Config.ConnectionStrings.ConnectionStrings["connString"].ConnectionString;
string controlProcesoCommand = "select top 5 * from ControlProceso order by FechaInicio desc;";
using (SqlConnection conn = new SqlConnection(connString))
using (SqlCommand command = new SqlCommand(controlProcesoCommand, conn))
{
try
{
conn.Open();
var reader = command.ExecuteReader();
while (reader.Read())
{
int lastPeriodDb = int.Parse(reader["Periodo"].ToString());
int actualPeriod = int.Parse(period);
if (period.Equals(reader["Periodo"].ToString()))
throw new Exception(Resources.Messages.Period_already_processed);
else if (lastPeriodDb > actualPeriod)
throw new Exception(Resources.Messages.Period_saved_after_actual_period);
else break;
}
reader.Close();
}
catch (Exception ex)
{
throw ex;
}
finally
{
conn.Close();
conn.Dispose();
command.Cancel();
command.Dispose();
}
}
}
And this is my RestoreDatabase():
private static void RestoreDatabase()
{
try
{
SqlConnection conn = new SqlConnection(Config.ConnectionStrings.ConnectionStrings["connString"].ConnectionString);
string dbName = conn.Database;
string restoreFilePath = Config.AppSettings.Settings["RestoreFilePath"].Value;
Server myServer = new Server(conn.DataSource);
Database itauDatabase = new Database(myServer, dbName);
Restore dbRestore = new Restore();
dbRestore.Action = RestoreActionType.Database;
dbRestore.Database = itauDatabase.Name;
dbRestore.Devices.AddDevice(restoreFilePath, DeviceType.File);
dbRestore.ReplaceDatabase = true;
dbRestore.SqlRestore(myServer);
}
catch (Exception ex)
{
throw ex;
}
}
Each method works fine when I execute them separated.
Thanks!

No current row message appears while getting Max values from SQLite database

I want to get max value form database if database not empty. Program works fine but it gives No Current Row message on start. I've query like this,
public int GetMaxValue(String table, String column, int columnIndex)
{
try
{
int values = -1;
String query = "SELECT MAX(" + column + ") FROM " + table;
SQLiteCommand sQLiteCommand = new SQLiteCommand(query, sQLiteConnection);
sQLiteCommand.ExecuteNonQuery();
using (SQLiteDataReader sQLiteDataReader = sQLiteCommand.ExecuteReader())
{
if (!sQLiteDataReader.IsDBNull(0))
{
while (sQLiteDataReader.Read())
{
values = sQLiteDataReader.GetInt32(columnIndex);
sQLiteDataReader.Close();
return values;
}
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
return -1;
}
and call this method by,
string orderNo = database.GetMaxValue(Database.TABLE_ORDER, Database.INVOICE_NO_ORDER, 0).ToString();
in above function, i've check already if Reader Null then do not continue by this,
if (!sQLiteDataReader.IsDBNull(0))
}
but its not works. Kindly tell how to get rid of No Current Row message
This solve my problem
public Int32 GetMaxValue(String table, String column, int columnIndex)
{
try
{
Int32 values = -1;
String query = "SELECT MAX(" + column + ") FROM " + table;
SQLiteCommand sQLiteCommand = new SQLiteCommand(query, sQLiteConnection);
sQLiteCommand.ExecuteScalar();
using (SQLiteDataReader sQLiteDataReader = sQLiteCommand.ExecuteReader())
{
if (sQLiteDataReader.Read())
{
while (sQLiteDataReader.Read())
{
values = sQLiteDataReader.GetInt32(columnIndex);
return values;
}
}
sQLiteDataReader.Close();
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
return -1;
}

How to insert data into two SQL Server tables in asp.net

I have two tables, the first table is Course and this table contains three columns Course_ID, Name_of_course, DeptID; and the second table is Department and it has three columns DeptID, DepName, College.
I put a GridView to display the data that I will add it. But when I write the command to insert the data in both tables the data don't add. I used this command
protected void GridView1_SelectedIndexChanged(object sender, EventArgs e)
{
try
{
GridViewRow r = GridView1.SelectedRow;
Dbclass db = new Dbclass();
string s = "";
DataTable dt = db.getTable(s);
ddcollege.SelectedValue = dt.Rows[0]["College"].ToString();
dddept.SelectedValue = dt.Rows[1]["DepName"].ToString();
tbid.Text = r.Cells[0].Text;
tbcourse_name.Text = r.Cells[1].Text;
lblid.Text = tbid.Text;
lberr.Text = "";
}
catch (Exception ex)
{
lberr.Text = ex.Message;
}
}
protected void btadd_Click(object sender, EventArgs e)
{
try
{
if (tbid.Text == "")
{
lberr.Text = "Please input course id";
return;
}
if (tbcourse_name.Text == "")
{
lberr.Text = "Please input course name";
return;
}
string s = "Insert into Course(Course_ID,Name_of_course) values ('" + tbid.Text + "','" + tbcourse_name.Text + "')";
s = "INSERT INTO Department (DepName,College,DeptID) VALUES ('"+dddept.SelectedValue+"','"+ddcollege.SelectedValue+"','"+tbdeptID.Text+"')";
Dbclass db = new Dbclass();
if (db.Run(s))
{
lberr.Text = "The data is added";
lblid.Text = tbid.Text;
}
else
{
lberr.Text = "The data is not added";
}
SqlDataSource1.DataBind();
GridView1.DataBind();
}
catch (Exception ex)
{
lberr.Text = ex.Message;
}
}
Here is the Dbclass code:
public class Dbclass
{
SqlConnection dbconn = new SqlConnection();
public Dbclass()
{
try
{
dbconn.ConnectionString = #"Data Source=Fingerprint.mssql.somee.com;Initial Catalog=fingerprint;Persist Security Info=True;User ID=Fingerprint_SQLLogin_1;Password=********";
dbconn.Open();
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
//----- run insert, delete and update
public bool Run(String sql)
{
bool done= false;
try
{
SqlCommand cmd = new SqlCommand(sql,dbconn);
cmd.ExecuteNonQuery();
done= true;
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
return done;
}
//----- run insert, delete and update
public DataTable getTable(String sql)
{
DataTable done = null;
try
{
SqlDataAdapter da = new SqlDataAdapter(sql, dbconn);
DataSet ds = new DataSet();
da.Fill(ds);
return ds.Tables[0];
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
return done;
}
}
Thank you all
The main thing I can see is you are assigning two different things to your "s" variable.
At this point db.Run(s) the value is "Insert into Department etc" and you have lost the first sql string you assigned to "s"
Try:
string s = "Insert into Course(Course_ID,Name_of_course) values ('" + tbid.Text + "','" + tbcourse_name.Text + "')";
s += "INSERT INTO Department (DepName,College,DeptID) VALUES ('"+dddept.SelectedValue+"','"+ddcollege.SelectedValue+"','"+tbdeptID.Text+"')";
Notice the concatenation(+=). Otherwise as mentioned above using a stored procedure or entity framework would be a better approach. Also try to give your variables meaningful names. Instead of "s" use "insertIntoCourse" or something that describes what you are doing
When a value is inserted into a table(Table1) and and value has to be entered to into another table(Table2) on insertion of value to Table1, you can use triggers.
https://msdn.microsoft.com/en-IN/library/ms189799.aspx
"tbdeptID.Text" is giving you the department Id only right? You should be able to modify your first statement
string s = "Insert into Course(Course_ID,Name_of_course,) values ('" + tbid.Text + "','" + tbcourse_name.Text + "',)";
Please start running SQL Profiler, it is a good tool to see what is the actual query getting executed in server!

C# MySql Sometimes insert executed twice or not executed

I have to insert data to 3 tables in my MySql let say it was table1, table2 and table3
my problem is sometimes insert query for table2 is executed twice and sometimes it's not executed
Here is my code :
string Query = #"insert into table1(SellCode, SellDate, SellType, Discount, BuyerCode)
values (#SellCode, #SellDate, #SellType, #Discount, #BuyerCode)";
using (MySqlConnection conExpDB = new MySqlConnection(ConString))
using (MySqlCommand cmdExpDB = new MySqlCommand(Query, conExpDB))
{
try
{
conExpDB.Open();
cmdExpDB.Parameters.AddWithValue("#SellCode", SellCode);
cmdExpDB.Parameters.AddWithValue("#SellDate", DateTime.Now);
cmdExpDB.Parameters.AddWithValue("#SellType", "Retail");
cmdExpDB.Parameters.AddWithValue("#Discount", txtDiscount.Text);
cmdExpDB.Parameters.AddWithValue("#BuyerCode", "1");
int rowsUpdated = cmdExpDB.ExecuteNonQuery();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}//end try
}//end using
string QueryB = #"insert into table2(PaymentCode, PaymentAmount,
SellCode, PaymentDate)
values (#PaymentCode, #PaymentAmount, #SellCode, #PaymentDate)";
using (MySqlConnection conExpDB = new MySqlConnection(ConString))
using (MySqlCommand cmdExpDB = new MySqlCommand(QueryB, conExpDB))
{
try
{
conExpDB.Open();
cmdExpDB.Parameters.AddWithValue("#PaymentCode", paymentcode);
cmdExpDB.Parameters.AddWithValue("#PaymentAmount", PaymentAmount);
cmdExpDB.Parameters.AddWithValue("#SellCode", SellCode);
cmdExpDB.Parameters.AddWithValue("#PaymentDate", DateTime.Now);
int rowsUpdated = cmdExpDB.ExecuteNonQuery();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}//end try
}//end using
foreach (DataGridViewRow row in GridView.Rows)
{
string QueryDetail = #"insert into table3(SellDetailCode, SellCode,
ItemCode, Qty,
Price)
values (#SellDetailCode, #SellCode, #ItemCode, #Qty,
#Price)";
using (MySqlConnection conExpDB = new MySqlConnection(ConString))
using (MySqlCommand cmdExpDB = new MySqlCommand(QueryDetail, conExpDB))
{
try
{
conExpDB.Open();
cmdExpDB.Parameters.AddWithValue("#SellDetailCode", SellDetailCode);
cmdExpDB.Parameters.AddWithValue("#SellCode", SellCode);
cmdExpDB.Parameters.AddWithValue("#ItemCode", ItemCode);
cmdExpDB.Parameters.AddWithValue("#Qty", Qty);
cmdExpDB.Parameters.AddWithValue("#Price", Price);
int rowsUpdated = cmdExpDB.ExecuteNonQuery();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}//end try
}//end using
}//end foreach
Is there any effective method to detect the queries are inserted twice or not executed? Or is there any problem with my queries?
Because it's happened very rare it's difficult for me fixed this error

Trapping error and keep trucking

I have written a c# monitoring program to check values in a database. It runs 4 separate checks then outputs the results (Winform).
It was all running great then last week the first check hit a problem and whole program stopped.
So my question is how would I trap any errors in any of the 4 checks and keep going/ trucking?
Can I do it with try catch or would this halt program?
Code Sample
bool bTestDate;
object LastDataDate;
//-- Check A - Table 1
OdbcConnection DbConnection = new OdbcConnection("DSN=EDATA");
try
{
DbConnection.Open();
}
catch (OdbcException ex)
{
Console.WriteLine("connection to the DSN '" + connStr + "' failed.");
Console.WriteLine(ex.Message);
return;
}
OdbcCommand DbCommand = DbConnection.CreateCommand();
DbCommand.CommandText = "SELECT NAME, UNAME, DATIME_ENDED FROM XPF WHERE NAME='XXXX'";
OdbcDataReader DbReader = DbCommand.ExecuteReader();
int fCount = DbReader.FieldCount;
string myBatch;
string myUser;
string myDate;
while (DbReader.Read())
{
Console.Write(":");
myBatch = DbReader.GetString(0);
myUser = DbReader.GetString(1);
myDate = DbReader.GetString(2);
myDate = myDate.Remove(myDate.Length - 10);
for (int i = 0; i < fCount; i++)
{
String col = DbReader.GetString(i);
Console.Write(col + ":");
}
tbxxx.Text = string.Format("{0:dd/M/yy H:mm:ss}", myDate);
bool TestDate;
TestDate = CheckDate(Convert.ToDateTime(myDate));
CheckVerif(TestDate, lblVerifixxx);
}
//-- Check B - Table 2
string cnStr = setConnectionString();
string mySQL = "Select Max(TO_DATE(TIME_ID, 'DD/MM/YYYY')) FROM table";
OracleConnection cn = new OracleConnection(cnStr);
cn.Open();
OracleCommand cmd = new OracleCommand(mySQL, cn);
LastDataDate = cmd.ExecuteScalar();
cmd.Dispose();
tbLastDate.Text = string.Format("{0:dd MMM yy}", LastDataDate);
bTestDate = CheckDate(Convert.ToDateTime(LastDataDate));
CheckVerif(bTestDate, lblVerif);
//-- Check C - Table 3
mySQL = "Select Max(xxx_DATE) from AGENT";
OracleCommand cmd2 = new OracleCommand(mySQL, cn);
LastDataDate = cmd2.ExecuteScalar();
cmd2.Dispose();
tbxxx2.Text = string.Format("{0:dd MMM yy}", LastDataDate);
bool TestDatex;
TestDatex = CheckDate(Convert.ToDateTime(LastDataDate));
CheckVerif(TestDatex, lblVerif2);
You can use a try catch block with the expected exceptions and a general one, just to be certain you catch them all and not throw the exception, therefore not halting the program.
try
{
string s = null;
ProcessString(s);
}
// Most specific:
catch (ArgumentNullException e)
{
Console.WriteLine("{0} First exception caught.", e);
}
// Least specific:
catch (Exception e)
{
Console.WriteLine("{0} Second exception caught.", e);
}
Check https://msdn.microsoft.com/en-us/library/0yd65esw.aspx

Categories