I have an difficult situation :
this is my form :
the first button '...' is a btnAllegato. Code :
private void btnAllegato_Click(object sender, EventArgs e)
{
try
{
using (OpenFileDialog openFileDialog1 = new OpenFileDialog())
{
string path = string.Empty;
openFileDialog1.Title = "Seleziona richiestaIT (PDF)..";
openFileDialog1.Filter = ("PDF (.pdf)|*.pdf");
openFileDialog1.FilterIndex = 1;
openFileDialog1.FileName = "";
if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
//salva l'intero path
path = openFileDialog1.FileName;
//nome file + estensione
string temp = openFileDialog1.SafeFileName;
//elimina l'estensione del file con IgnoreCase -> case Unsensitive
temp = Regex.Replace(temp, ".pdf", " ", RegexOptions.IgnoreCase);
//datatime + replace
string timenow = System.DateTime.Now.ToString();
//replace data da gg//mm/aaaa ss:mm:hh -----> ad gg-mm-aaaa_ss-mm-hh
timenow = timenow.Replace(":", "-").Replace("/", "-");//.Replace(" ", " ");
_url = #"\\192.168.5.7\dati\SGI\GESTIONE IT\RichiesteIT\" + temp + timenow + ".pdf";
System.IO.File.Copy(path, _url);
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
after i have a button Inserisci >> (btnInserisci)
with this button i Create a DB Query to insert data...
private void btnInserisci_Click(object sender, EventArgs e)
{
try
{
if ((_IDRichiedente != -1) && (_data != string.Empty) && (_url != string.Empty))
{
MessageBox.Show(_url);
QueryAssist qa = new QueryAssist();
string query = "INSERT INTO RICHIESTA_IT(ID_Risorsa, descrizione_richiesta, modulo_pdf, data_richiesta) VALUES('" + _IDRichiedente + "', '" + txtBreveDescrizione.Text + "', '" + _url + "', '" + _data + "');";
MessageBox.Show(query);
qa.runQuery(query);
else
{
MessageBox.Show("Selezionare il richiedente,data o allegato!");
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
where
private int _IDRichiedente = -1;
private string _data = String.Empty;
private string _url = string.Empty;
is a fields of class.
QueryAssist is my class that connect, run query and disconnect to Access DB.
code :
class QueryAssist
{
System.Data.OleDb.OleDbConnection _OleDBconnection;
public QueryAssist()
{
this._OleDBconnection = null;
}
private bool connectionDB()
{
string connection = "Provider=Microsoft.ACE.OLEDB.12.0; Data Source=\"\\\\192.168.5.7\\dati\\Scambio\\Sviluppo\\Impostazioni temporanea db Censimento\\CensimentoIT.accdb\"";
try
{
_OleDBconnection = new System.Data.OleDb.OleDbConnection(connection);
_OleDBconnection.Open();
return true;
}
catch(Exception ex)
{
System.Windows.Forms.MessageBox.Show(ex.Message);
return false;
}
}
private void disconnectDB()
{
try
{
_OleDBconnection.Close();
}
catch (Exception ex)
{
System.Windows.Forms.MessageBox.Show(ex.Message);
}
}
public System.Data.DataTable runQuery(string query)
{
try
{
if (connectionDB())
{
System.Data.DataTable dataTable = new System.Data.DataTable();
System.Data.OleDb.OleDbCommand sqlQuery = new System.Data.OleDb.OleDbCommand(query, _OleDBconnection);
System.Data.OleDb.OleDbDataAdapter adapter = new OleDbDataAdapter(sqlQuery);
adapter.Fill(dataTable);
disconnectDB();
return dataTable;
}
}
catch(Exception ex)
{
System.Windows.Forms.MessageBox.Show(ex.Message);
}
return null;
}
public int countRowsQueryResult(string query)
{
try
{
if (connectionDB())
{
System.Data.DataTable dataTable = new System.Data.DataTable();
System.Data.OleDb.OleDbCommand sqlQuery = new System.Data.OleDb.OleDbCommand(query, _OleDBconnection);
System.Data.OleDb.OleDbDataAdapter adapter = new OleDbDataAdapter(sqlQuery);
adapter.Fill(dataTable);
disconnectDB();
return dataTable.Rows.Count;
}
}
catch (Exception ex)
{
System.Windows.Forms.MessageBox.Show(ex.Message);
}
return -1;
}
}
At firt time ... The application work good. I selected a file and other data and I click on button 'Inserisci>>' and all working good.
Next step when i want to insert other data ... when i click on '...' button for attachment a file i have the loop OpenFileDialog
To close, i must kill the process.
I have [STAThread] set on main of the program.
Connect to NAS isn't a problem ... I have try in local .. and i have the same problem..
If i click on btn '...' to OpenFileDialg then not click on button 'Inserisci>>'
OpenFileDialog work good for all time ...
But if i click on button 'Inserisci>>' on the next click on button '...' to OpenFileDialog application loop..
Sorry for bad english ..I'm here for clarification
The use of the runQuery method with an INSERT statement could be the cause of your problems. To insert a record you should use an OleDbCommand with the ExecuteNonQuery. A Fill method is used to fill a DataTable.
The fact that the record is inserted anyway happens because the underlying command used to fill the DataTable (ExecuteReader) ignores its sql command text and executes what you have passed. However after that the Fill method expects to fill a DataTable and not having a select statement could be potentially the cause of your problems.
I would use a different method when you need to Update/Delete or Insert new data
public int runNonQuery(string query)
{
try
{
if (connectionDB())
{
OleDbCommand sqlQuery = new OleDbCommand(query, _OleDBconnection);
int rows = sqlQuery.ExecuteNonQuery();
disconnectDB();
return rows;
}
}
catch(Exception ex)
{
System.Windows.Forms.MessageBox.Show(ex.Message);
return -1;
}
}
There are other problems in your code and are all connected to the way in which you concatenate together the string to form an sql statement. This is know as the worst practice possible with database code. If you take a bit of your time to investigate how to write a parameterized query you will avoid a lot of future problems.
Related
I wrote this code using Visual Studio 2015:
static string strconnect = "Dsn=mx86";
static public string strDoc_key = "";
static public bool bPicFounded = false;
OdbcDataAdapter dr = new OdbcDataAdapter();
DataSet ds = new DataSet();
Thread thread = null;
static public OdbcConnection dataConnection = new OdbcConnection(strconnect);
static public string strInitialDirectory = "";
public frmMain()
{
InitializeComponent();
try
{
if (dataConnection.State != ConnectionState.Open)
dataConnection.Open();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
private void frmMain_Load(object sender, EventArgs e)
{
if (dataConnection.State != ConnectionState.Open)
{
this.Invoke(new MethodInvoker(delegate { this.Close(); }));
}
try
{
// this.Invoke(new MethodInvoker(delegate
// {
DataTable mydt = new DataTable();
using (OdbcCommand ord = new OdbcCommand("", dataConnection))
{
ord.CommandText = "SELECT `AnläggningsNr` GroupID ,`Beskrivning` GroupName from `Utrustningar` " +
"WHERE (((`NivåUpp`)='TOP') AND ((`Enhet`)='00'))";
mydt.Load(ord.ExecuteReader());
cboGroups.SelectedIndexChanged -= cboGroups_SelectedIndexChanged;
if (mydt.Rows.Count > 0)
{
cboGroups.ValueMember = "GroupID";
cboGroups.DisplayMember = "GroupName";
cboGroups.DataSource = mydt.DefaultView;
cboGroups.SelectedIndex = 0;
cboGroups_SelectedIndexChanged(null, null);
}
cboGroups.SelectedIndexChanged += cboGroups_SelectedIndexChanged;
}
}
catch (Exception ex)
{
MessageBox.Show("a)Message is: " + ex.Message);
}
}
When I make x86 build, the combobox is filled with system.data.datarowview but when I make x64 build, it works fine.
What could be the reason for this problem?
When I replace
Display member value from
cboGroups.DisplayMember = "GroupName";
To
cboGroups.DisplayMember = mydt.columns[1].columnname
And make the same with value member it works good and give me the expected results
So when I try to debug to know the difference between the two expressions
I notice that
The string "GroubName" come with null terminated character like "GroubName\0" so mydt.columns[1].column name give the right column name with null terminated character
This is what I noticed
Ithink the proplem in odbc driver which give me this type of errors
I have a piece of code that going to the database every minute to check if there is any report that need to be run, and if there is any it runs it.
The issue is that my object initiation to a database class creates memory leak. If I look at task mgr "user Object" grown by 5 every time tick executing a code.
private void ReportRunTimer_Tick(object sender, EventArgs e)
{
DataConnection dataConnection = new DataConnection(); *<-- when executing this line User Object increasing.*
try
{
reportsToRun = dataConnection.GetListOfTheReportForReportRunTick();
if (reportsToRun.Count > 0)
foreach (string report in reportsToRun)
{
logs("Starting Automatic report generatin", "Successful");
Thread TicketReportMethodThread = new Thread(() => GenerateReport(report, 1));
TicketReportMethodThread.Start();
}
dataConnection = null;
} catch (Exception ex)
{
logs("Starting Automatic report generatin failed: " +ex.ToString(), "Error");
}
finally
{
reportsToRun.Clear();
}
}
DataConnection class
public List<string> GetListOfTheReportForReportRunTick()
{
List<string> RepoerList = new List<string>();
connString = "Server=xxx;Port=xxx;Database=xxx;Uid=xxx;password=xxxx;SslMode=none";
using (MySqlConnection mySqlConnection = new MySqlConnection(connString))
{
try
{
MySqlCommand mySqlCommand = mySqlConnection.CreateCommand();
mySqlCommand.CommandText = "SELECT reportname FROM reports WHERE nextruntime < NOW()";
mySqlConnection.Open();
MySqlDataReader mySqlDataReader = mySqlCommand.ExecuteReader();
while (mySqlDataReader.Read())
{
RepoerList.Add(mySqlDataReader["reportname"].ToString());
}
}
catch (MySqlException ex)
{
hd.logs("Failed to get reports with reportstorun_tick Error: " + ex.ToString(), "Error");
mySqlConnection.Close();
}
finally
{
mySqlConnection.Close();
mySqlConnection.Dispose();
}
}
return RepoerList;
}
DataConnection dataConnection = new DataConnection(); used in a few more places and this is the only one that causing an issue.
If I replace code in private void ReportRunTimer_Tick with code from public List GetListOfTheReportForReportRunTick() like bellow. Issue no longer exist, any ideas?
private void ReportRunTimer_Tick(object sender, EventArgs e)
{
List<string> reportsToRun = new List<string>();
try
{
connString = "Server=xxx;Port=xxx;Database=xxx;Uid=xxx;password=xxxx;SslMode=none";
using (MySqlConnection mySqlConnection = new MySqlConnection(connString))
{
try
{
MySqlCommand mySqlCommand = mySqlConnection.CreateCommand();
mySqlCommand.CommandText = "SELECT reportname FROM reports WHERE nextruntime < NOW()";
mySqlConnection.Open();
MySqlDataReader mySqlDataReader = mySqlCommand.ExecuteReader();
while (mySqlDataReader.Read())
{
reportsToRun.Add(mySqlDataReader["reportname"].ToString());
}
if (reportsToRun.Count > 0)
foreach (string report in reportsToRun)
{
logs("Starting Automatic report generatin", "Successful");
Thread TicketReportMethodThread = new Thread(() => GenerateReport(report, 1));
TicketReportMethodThread.Start();
}
}
catch (MySqlException ex)
{
logs("Failed to get reports with reportstorun_tick Error: " + ex.ToString(), "Error");
mySqlConnection.Close();
}
finally
{
mySqlConnection.Close();
mySqlConnection.Dispose();
}
}
}
catch (Exception ex)
{
logs("Starting Automatic report generatin failed: " + ex.ToString(), "Error");
}
finally
{
reportsToRun.Clear();
}
}
Issue is caused by
DataConnection dataConnection = new DataConnection(); *<-- when executing this line User Object increasing.*
reportsToRun = dataConnection.GetListOfTheReportForReportRunTick();
But I can't understand why.
I think the memory leak is because you're not disposing your MySqlDataReader. You can do this by just wrapping it in a using statement like this:
using(MySqlDataReader mySqlDataReader = mySqlCommand.ExecuteReader()){
while (mySqlDataReader.Read())
{
RepoerList.Add(mySqlDataReader["reportname"].ToString());
}
}
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!
i am trying to insert new row in Emp table in c# (disconnected mode), the new row successfully inserted but the dataset not updated, so when i search for the new row, i don't find it, but when i search for an old row, i find it.
the insertBTN button used to insert new row
the searchByID button used to search for row by its ID
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private SqlConnection conn;
private SqlDataAdapter adapter;
private DataSet ds;
private void Form1_Load(object sender, EventArgs e)
{
conn = new SqlConnection(#"data source=(local);initial catalog =Test;integrated security = true");
conn.Open();
adapter = new SqlDataAdapter("select * from Emp",conn);
ds = new DataSet();
adapter.Fill(ds,"Emp");
}
private void insertBTN_Click(object sender, EventArgs e)
{
try
{
int id = int.Parse(textBox1.Text);
string name = textBox2.Text;
string address = textBox3.Text;
int age = int.Parse(textBox4.Text);
int salary = int.Parse(textBox5.Text);
SqlCommand command = new SqlCommand("Insert into Emp values(" + id + ",'" + name + "','" + address + "'," + age + "," + salary + ")", conn);
command.ExecuteNonQuery();
adapter.Update(ds,"Emp");
MessageBox.Show("Employee added successfully");
}
catch (Exception exception)
{
MessageBox.Show(exception.Message);
}
}
private void searchByID_Click(object sender, EventArgs e)
{
try
{
int id = int.Parse(textBox1.Text);
foreach (DataRow row in ds.Tables["Emp"].Rows)
{
if (Convert.ToInt32(row["id"]) == id)
{
textBox2.Text = Convert.ToString(row["name"]);
textBox3.Text = Convert.ToString(row["address"]);
textBox4.Text = Convert.ToString(row["age"]);
textBox5.Text = Convert.ToString(row["salary"]);
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
}
The Update method of the DataAdapter doesn't read again but tries to execute the INSERT, DELETE and UPDATE commands derived from the original SELECT statement against the Rows in the DataTable that have their RowState changed
So, if you want to use the Update method of the adapter you could write
private void insertBTN_Click(object sender, EventArgs e)
{
try
{
DataRow row = ds.Tables["emp"].NewRow();
row.SetField<int>("id", int.Parse(textBox1.Text));
row.SetField<string>("name", textBox2.Text));
row.SetField<string>("address", textBox3.Text));
row.SetField<int>("age", int.Parse(textBox4.Text));
row.SetField<int>("salary", int.Parse(textBox5.Text));
ds.Tables["emp"].Rows.Add(row);
adapter.Update(ds,"Emp");
MessageBox.Show("Employee added successfully");
}
catch (Exception exception)
{
MessageBox.Show(exception.Message);
}
}
At this point your DataSet contains the added row because you have added it manually and then passed everything to the Update method to write it to the database.
However, keep in mind that the Update method to work requires certain conditions to be present. You could read them in the DbDataAdapter.Update page on MSDN.
Mainly you need to have retrieved the primary key of the table, do not have more than one table joined together and you have used the DbCommandBuilder object to create the required commands (Again the example in the MSDN page explain it)
Not related to your question, but you could change your search method and avoid writing a loop to search for the ID
private void searchByID_Click(object sender, EventArgs e)
{
try
{
int id = int.Parse(textBox1.Text);
DataRow[] foundList = ds.Tables["Emp"].Select("Id = " + id);
if(foundList.Length > 0)
{
textBox2.Text = foundList[0].Field<string>("name");
textBox3.Text = foundList[0].Field<string>("address");
textBox4.Text = foundList[0].Field<int>("age").ToString();
textBox5.Text = foundList[0].Field<int>("salary").ToString();
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
I have an application I'm trying to create, however I'm stuck.
I am trying to access the site's MySQL query within my code.
Right now I am just trying to test it, to make sure it works, but I'm having no luck with that.
I think I'm just overlooking something simple, but I'm not sure. Any help?
class DBConnect
{
private MySqlConnection connection;
private string server;
private string database;
private string uid;
private string password;
public List<string>[] list = new List<string>[1];
public DBConnect()
{
Initialize();
}
private void Initialize()
{
server = "localhost";
database = "XXX";
uid = "XXX";
password = "XXX";
string connectionString;
connectionString = "SERVER=" + server + ";" + "DATABASE=" + database
+ ";" + "UID=" + uid + ";" + "PASSWORD=" + password + ";";
connection = new MySqlConnection(connectionString);
}
//this will open the connection to MySql
private bool OpenConnection()
{
try
{
connection.Open();
return true;
}
//if there is a problem connecting, display one of the following connections
catch (MySqlException ex)
{
switch (ex.Number)
{
case 0:
MessageBox.Show("Cannot connect to server. Contact Admin");
break;
case 1045:
MessageBox.Show("Invalid username/password, please try again");
break;
}
return false;
}
}
//if the connection fails to connect to MySql server, the client will close the connection.
private bool CloseConnection()
{
try
{
connection.Close();
return true;
}
catch (MySqlException ex)
{
MessageBox.Show(ex.Message);
return false;
}
}
//Select statement
public List<string>[] Select()
{
int firstNumber = 2058;
**string query = "USE `db_order` SELECT `order_id` FROM `order_address` WHERE order_id=2058";**
//create a list to store the results
list[0] = new List<string>(0);
//Open's connection
if (this.OpenConnection() == true)
{
//creates a command from the query.
MySqlCommand cmd = new MySqlCommand(query, connection);
//creates a data reader, and executes the command.
MySqlDataReader dataReader = cmd.ExecuteReader();
while (dataReader.Read())
{
list[0].Add(dataReader["order_id"] + "");
}
//close Data Reader
dataReader.Close();
this.CloseConnection();
//returns list to be displayed
return list;
}
else
{
return list;
}
}
}
Here is the second class (i got rid of anything that isn't a part of the problem):
public partial class Form1
{
private void InitializeComponent()
{
// CustName
//
this.CustName.AutoSize = true;
this.CustName.Location = new System.Drawing.Point(200, 30);
this.CustName.Name = "CustName";
this.CustName.Size = new System.Drawing.Size(137, 13);
this.CustName.TabIndex = 0;
this.CustName.Text = "Customer\'s name goes here" + new DBConnect().list[0];
}
#endregion
}
Update
You add to the list from your DataReader like this
list[0].Add(dataReader["order_id"] + "");
So, which means you have a multi-dimensional (2-dimension to be exact) array of list. Therefore to access that you have to do like Select()[0][0] , check below:
DBConnect() DBCon = new DBConnect();
this.Custname.Text = DBCon.Select()[0].Count>0 ? "Customer\'s name goes here" +DBCon.Select()[0][0].ToString() : "No Customer to show";