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
Related
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 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.
private OleDbConnection conexao;
private Timer time = new Timer();
public void Conexao() //Conexão
{
string strcon = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=|DataDirectory|DB.accdb";
conexao = new OleDbConnection(strcon);
}
void tabela()
{
Conexao();
conexao.Open();
label1.Text = DateTime.Now.ToString();
string bn = "select D2 from Planilha where D2='" + label1.Text + "'";
textBox1.Text = label1.Text;
OleDbCommand Queryyy = new OleDbCommand(bn, conexao);
OleDbDataReader drr;
drr = Queryyy.ExecuteReader();
if (drr.Read() == true)
{
try
{
MessageBox.Show("Hi");
}
catch (OleDbException ex)
{
MessageBox.Show("" + ex);
}
}
}
private void timer1_Tick(object sender, EventArgs e)
{
tabela();
}
Timer Interval = 1000
(click for larger view)
I'm all afternoon trying to fix it but could not so I come here for help
I think asawyer's comment had it right I bet the problem is from the fact you are not handling your objects correctly, get rid of your class objects and work with using statements
public OleDbConnection Conexao() //Conexão
{
string strcon = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=|DataDirectory|DB.accdb";
return new OleDbConnection(strcon);
}
void tabela()
{
try
{
timer1.Enabled = false;
using(var conexao = Conexao())
{
conexao.Open();
label1.Text = DateTime.Now.ToString();
string bn = "select D2 from Planilha where D2='" + label1.Text + "'";
textBox1.Text = label1.Text;
using(OleDbCommand Queryyy = new OleDbCommand(bn, conexao))
using(OleDbDataReader drr = Queryyy.ExecuteReader())
{
if (drr.Read() == true)
{
try
{
MessageBox.Show("Hi");
}
catch (OleDbException ex)
{
MessageBox.Show("" + ex);
}
}
}
}
}
finally
{
timer.Enabled = true;
}
}
private void timer1_Tick(object sender, EventArgs e)
{
tabela();
}
Also from the fact that you are only reading the first column of the first row, you should use ExecuteScalar instead of ExecuteReader.
using(OleDbCommand Queryyy = new OleDbCommand(bn, conexao))
{
try
{
var result = Queryyy.ExecuteScalar();
if (result != null)
{
MessageBox.Show("Hi");
}
}
catch (OleDbException ex)
{
MessageBox.Show("" + ex);
}
}
}
You also should be using parametrized queries.
label1.Text = DateTime.Now.ToString();
string bn = "select D2 from Planilha where D2=#param1";
textBox1.Text = label1.Text;
using(OleDbCommand Queryyy = new OleDbCommand(bn, conexao))
{
Queryyy.Parameters.AddWithValue("#param1", label1.Text);
//....
i am having a crystal report , that is to be filled with stored procedure, but when i put any parameter of procedure in .rpt file it is giving me error like
"Invalid Argument provided. Failed to open a rowset."
my code is as below :
public void GroupwiseRegistrationReport()
{
SqlConnection connection;
DataSet ds = new DataSet();
DataTable dt = new DataTable();
connection = gen.con;
string SP = "";
SqlCommand command = connection.CreateCommand();
SqlTransaction transaction = null;
try
{
connection.Open();
transaction = connection.BeginTransaction();
if (rblReportFrom.SelectedValue == "0")
{
SP = "SPGroupwiseIndustriesEM1Report";
}
else
{
SP = "SPGroupwiseIndustriesEM2Report";
}
ValueData = new ArrayList();
ParameterData[0] = "#fromdate";
ValueData.Add(txtTotalBetweenFrom.Text.ToString().Trim());
ParameterData[1] = "#todate";
ValueData.Add(txtTotalBetweenTo.Text.ToString().Trim());
ds = gen.FunSearch_Trans(ParameterData, ValueData, SP, transaction, command);
dt = ds.Tables[0];
if (ds.Tables[0].Rows.Count > 0)
{
if (rblReportFrom.SelectedValue == "0")
{
repdoc.Load(Server.MapPath("~\\admin\\Reports\\Groupwise-EM-I-Registration-Report.rpt"));
}
else
{
repdoc.Load(Server.MapPath("~\\admin\\Reports\\Groupwise-EM-II-Registration-Report.rpt"));
}
repdoc.SetDataSource(ds.Tables[0]);
configureCrystalReports();
crvMSMEReportViewer.ReportSource = repdoc;
//Response.Buffer = true;
//Response.ClearContent();
//Response.ClearHeaders();
//repdoc.ExportToHttpResponse(ExportFormatType.PortableDocFormat, Response, true, "Exported Report");
tablereportviewer.Visible = true;
}
else
{
tablereportviewer.Visible = false;
message("No Records Found.");
}
transaction.Commit();
}
catch (Exception ex)
{
tablereportviewer.Visible = false;
error.LogError(ex);
transaction.Rollback();
}
finally
{
connection.Close();
}
}
Am i missing something or what i cant figure it out please help me..
And which is the best way to deal with crystal report ,is it with using dataset or directly stored proceure?
Update
i changed my code like below but now is giving me message like :"Missing parameter values.
". but i have only two parameter to pass which are "#fromdate" and "#todate"
here is a code snippet :
doc = new ReportDocument();
doc.Load(Server.MapPath("~\\admin\\Reports\\Groupwise-EM-II-Registration-Report.rpt"));
doc.SetDatabaseLogon(ConfigurationManager.AppSettings["userName"], ConfigurationManager.AppSettings["pwd"], ConfigurationManager.AppSettings["serverName"], "databaseName", false);
doc.SetParameterValue("#fromdate", txtTotalBetweenFrom.Text.ToString());
doc.SetParameterValue("#todate", txtTotalBetweenTo.Text.ToString());
crvMSMEReportViewer.ReportSource = doc;
crvMSMEReportViewer.RefreshReport();
protected void Page_Load(object sender, EventArgs e)
{
if (Session["ReportDataSet"] != null)
{
crvAccountReportParameter.ReportSource = (ReportDocument)Session["ReportDataSet"];
}
}
private void LoadReport()
{
doc = new ReportDocument();
DataSet dsData = null;
dsData = objAccountReportBAL.getAccountRegister(txtTotalBetweenFrom.Text.ToString(), txtTotalBetweenTo.Text.ToString());
doc.Load(Server.MapPath("CrSalesReport.rpt"));
doc.SetDataSource(dsData.Tables[0]);
Session["ReportDataSet"] = rptDoc;
crvAccountReportParameter.ReportSource = rptDoc;
crvAccountReportParameter.DataBind();
}
I have a form with a datagrid, which is populated wih data from a sqlserver database. The datagrid populates fine but I am having trouble posting back the changes made by the user, to the table in the sql database. My forms code is as follows:
public partial class frmTimesheet : Form
{
private DataTable tableTS = new DataTable();
private SqlDataAdapter adapter = new SqlDataAdapter();
private int currentTSID = 0;
public frmTimesheet()
{
InitializeComponent();
}
private void frmTimesheet_Load(object sender, EventArgs e)
{
string strUser = cUser.currentUser;
cMyDate cD = new cMyDate(DateTime.Now.ToString());
DateTime date = cD.GetDate();
txtDate.Text = date.ToString();
cboTSUser.DataSource = cUser.GetListOfUsers("active");
cboTSUser.DisplayMember = "UserID";
cboTSUser.Text = strUser;
CheckForTimeSheet();
PopulateTimeSheet();
}
private void CheckForTimeSheet()
{
string strUser = cboTSUser.Text;
cMyDate cD = new cMyDate(txtDate.Text);
DateTime date = cD.GetDate();
int newTSID = cTimesheet.TimeSheetExists(strUser, date);
if (newTSID != this.currentTSID)
{
tableTS.Clear();
if (newTSID == 0)
{
MessageBox.Show("Create TimeSheet");
}
else
{
this.currentTSID = newTSID;
}
}
}
private void PopulateTimeSheet()
{
try
{
string sqlText = "SELECT EntryID, CaseNo, ChargeCode, StartTime, FinishTime, Units " +
"FROM tblTimesheetEntries " +
"WHERE TSID = " + this.currentTSID + ";";
SqlConnection linkToDB = new SqlConnection(cConnectionString.BuildConnectionString());
SqlCommand sqlCom = new SqlCommand(sqlText, linkToDB);
SqlDataAdapter adapter = new SqlDataAdapter(sqlCom);
adapter.SelectCommand = sqlCom;
SqlCommandBuilder builder = new SqlCommandBuilder(adapter);
adapter.Fill(tableTS);
dataTimesheet.DataSource = tableTS;
}
catch (Exception eX)
{
string eM = "Error Populating Timesheet";
cError err = new cError(eX, eM);
MessageBox.Show(eM + Environment.NewLine + eX.Message);
}
}
private void txtDate_Leave(object sender, EventArgs e)
{
CheckForTimeSheet();
PopulateTimeSheet();
}
private void cboTSUser_DropDownClosed(object sender, EventArgs e)
{
CheckForTimeSheet();
PopulateTimeSheet();
}
private void dataTimesheet_CellValueChanged(object sender, DataGridViewCellEventArgs e)
{
try
{
adapter.Update(tableTS);
}
catch (Exception eX)
{
string eM = "Error on frmTimesheet, dataTimesheet_CellValueChanged";
cError err = new cError(eX, eM);
MessageBox.Show(eM + Environment.NewLine + eX.Message);
}
}
}
No exception occurs, and when I step through the issue seems to be with the SqlCommandBuilder which does NOT build the INSERT / UPDATE / DELETE commands based on my gien SELECT command.
Can anyone see what I am doing wrong?
What am I missing?
You need to set the UpdateCommand instead of SelectCommand on update:
SqlDataAdapter adapter = new SqlDataAdapter();
SqlCommandBuilder sqlBld = new SqlCommandBuilder(adapter)
adapter.UpdateCommand = sqlBld.GetUpdateCommand() ;
The question is old, but the provided answer by#Anurag Ranjhan need to be corrected.
You need not to write the line:
adapter.UpdateCommand = sqlBld.GetUpdateCommand() ;
and enough to write:
SqlDataAdapter adapter = new SqlDataAdapter();
SqlCommandBuilder sqlBld = new SqlCommandBuilder(adapter)
//remove the next line
//adapter.UpdateCommand = sqlBld.GetUpdateCommand() ;
The Sql update/insert/delete commands are auto generated based on this line
SqlCommandBuilder sqlBld = new SqlCommandBuilder(adapter)
You can find the generated update sql by executing the line:
sqlBld.GetUpdateCommand().CommandText;
See the example How To Update a SQL Server Database by Using the SqlDataAdapter Object in Visual C# .NET
The problem said by OP can be checked by reviewing the Sql Statement sent by the client in SQl Server Profiler.