C# Oledb Connection can't update - c#

I'm an IT student who's always wanted to be in code hell (nah not really I really like this path I'm taking) so I'm just a beginner at using database.
so I have this problem of mine, specifically, when I try to update the form or at least the label itself, I can't connect to the Access Database I'm trying to get data from when I press the button, I like to know if I can even update the form or it's following items without losing connection to the database
if it's possible, and a better solution if you may as well, thanks in advance!
private void Form1_Load(object sender, EventArgs e)
{
Timer timer = new Timer();
timer.Interval = (1 * 1000);
timer.Tick += new EventHandler(timer_Tick);
timer.Start();
}
private void timer_Tick(object sender, EventArgs e)
{
label1.Text = "";
}
private void button1_Click(object sender, EventArgs e)
{
string select = "select Input from tbl_Dta1";
string connectionValue = #"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=TestDatabase.accdb";
try
{
using (OleDbConnection nConnection = new OleDbConnection(connectionValue))
{
OleDbCommand cmd = new OleDbCommand(select, nConnection);
nConnection.Open();
dr = cmd.ExecuteReader();
while (dr.Read())
{
string update = dr.GetValue(0).ToString();
label1.Text = update;
}
dr.Close();
}
}
catch(Exception ex)
{
MessageBox.Show("Failed to connect to Data source");
}
}
btw, the code I just made is actually a test code
I'm testing if the timer would interrupt the connection
and the purpose of the current content of this code is just to test if the database cell I'm getting is right or wrong

Related

is it possible to link a text box to a database?

i'm currently working on my C# "WindowForm" Project and i want to know if it's possible to link a textbox from any form to a database and update the textbox content from time to time so the users of my application would get up to dates information of what i'm willing to post in this form (textbox).
thank you,
If you want to refresh the text in real time from a datatable, you can try SqlDependency.
The following is a simple demo.
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
System.Data.SqlClient.SqlConnection conn = null;
System.Data.SqlClient.SqlCommand command = null;
// Set connection string
SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder
{
DataSource = #"datasource name",
// set database
InitialCatalog = #"catalog name",
// access the database using the existing windows security certificate
IntegratedSecurity = true
};
private void Form1_Load(object sender, EventArgs e)
{
conn = new System.Data.SqlClient.SqlConnection(builder.ConnectionString);
command = conn.CreateCommand();
command.CommandText = "select text from dbo.TableText where id<>20 order by id desc ";
// Start
SqlDependency.Start(builder.ConnectionString);
// Get data
GetData();
}
private void GetData()
{
command.Notification = null;
SqlDependency dependency = new SqlDependency(command);
dependency.OnChange += new OnChangeEventHandler(sqlDependency_OnChange);
using (SqlDataAdapter adapter = new SqlDataAdapter(command))
{
System.Data.DataSet ds = new DataSet();
adapter.Fill(ds, "test");
string text = ds.Tables["test"].Rows[0]["Text"].ToString();
textBox.Text = text;
}
}
void sqlDependency_OnChange(object sender, SqlNotificationEventArgs e)
{
// Because it is a child thread, you need to update the ui with the invoke method.
if (this.InvokeRequired)
{
this.Invoke(new OnChangeEventHandler(sqlDependency_OnChange), new object[] { sender, e });
}
else
{
SqlDependency dependency = (SqlDependency)sender;
dependency.OnChange -= sqlDependency_OnChange;
// After the notification, the current dependency is invalid, you need to re-get the data and set the notification.
GetData();
}
}
private void Form1_FormClosed(object sender, FormClosedEventArgs e)
{
// Clear resource
SqlDependency.Stop(builder.ConnectionString);
conn.Close();
conn.Dispose();
}
}
For more info about SqlDependency, you can refer to Detecting Changes with SqlDependency.
Hope this can help you.

How to list all the database's tables in datagridview in winforms, and attach a checkbox to each table to carry out re-indexing of selected table?

I am very new to C# and trying to develop a tool to re-index selected tables of a sql server database so the user don't have to go into database and run any commands.
namespace DBTool
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void dataGridView1_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
}
private void Form1_Load(object sender, EventArgs e)
{
}
private void radioButton1_CheckedChanged(object sender, EventArgs e)
{
}
private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
}
public DataSet GetTableNames()
{
try
{
//Local variables
DataSet resultSet = new DataSet();
//Get the connection string from the config file
string connectionString = ConfigurationManager.ConnectionStrings["DBTool.Properties.Settings.ConStr"].ConnectionString;
//Create a new database connection
SqlConnection connection = new SqlConnection(connectionString);
//Set the stored procedure 'sproc_Get_Tables_Names' as the command to be executed
using (SqlCommand cmd = new SqlCommand("sproc_Get_Tables_Names", connection))
{
//Setup the command object
SqlDataAdapter adapter = new SqlDataAdapter(cmd);
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandTimeout = 0;
//Open the connection
if (connection.State != ConnectionState.Open)
{
connection.Open();
}
//Execute the query and fill out the dataset
adapter.Fill(resultSet);
//Close the connection
connection.Close();
//Return the result of the stored procedure
return resultSet;
}
}
catch (Exception ex)
{
MessageBox.Show("An error occurred due to the following exception: " + ex.ToString() + ".","Error",MessageBoxButtons.OK,MessageBoxIcon.Error);
return null;
}
}
private void button1_Click(object sender, EventArgs e)
{
DataSet set = GetTableNames();
dataGridView1.DataSource = set.Tables[0];
}
private void dataGridView1_CellContentClick_1(object sender, DataGridViewCellEventArgs e)
{
}
}
}
I ran your code against one of my databases (with a different stored proc) and it works. Are you getting any exception? Try setting timeout on the connection string to something low and running again.
The fact that the code works implies that SQL Server/Network Connectivity/Permissions are an issue, and the timeout is so long that you never get an exception back.
Some things to try:
Does the stored proc execute ok on the server?
If so, how much data is it returning? Are you returning a ridiculous
amount of data and it's taking an age?
Does the user supplied by the connection string have permissions to
execute the stored proc?
Can you make a connection to the SQL Server using SQL Management
Studio using the same credentials?

Updating Microsoft Access using OleDbAdapter.Update

I have been able to bind the data in my MS Access database to textboxes on a form. But when I update the data, no changes are made to the database. I made a simplified example to demonstrate my problem. The form contains only two textboxes (txtFirstName and txtLastName) and two buttons (Save and Refresh). Refresh just reloads the DataTable from the database. I load the record with ID 1 and try to update. The code is below. I know that the updates to the textboxes also update the DataTable. However, the Update function of the data adapter does nothing because no Update commands are generated by the OleDbCommandBuilder. Can anyone tell me what I am doing wrong?
Thanks so much!
// Global data
public DataTable CaseTable = new DataTable();
private OleDbCommand dbCmd;
private OleDbDataAdapter adapter;
private OleDbCommandBuilder builder;
private OleDbConnection dbConn = null;
public frmCustomer()
{
InitializeComponent();
CaseTable.Columns.Add("ID");
CaseTable.Columns.Add("FirstName");
CaseTable.Columns.Add("LastName");
this.txtFirstName.DataBindings.Add("Text", CaseTable, "FirstName"); //, true, DataSourceUpdateMode.OnPropertyChanged);
this.txtLastName.DataBindings.Add("Text", CaseTable, "LastName"); //, true, DataSourceUpdateMode.OnPropertyChanged);
}
private void frmCustomer_Load(object sender, EventArgs e)
{
dbConn = new OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=Customers.accdb");
dbCmd = new OleDbCommand("Select * From Customers Where ID = 1", dbConn);
adapter = new OleDbDataAdapter(dbCmd);
builder = new OleDbCommandBuilder(adapter);
RefreshForm();
}
private void RefreshForm()
{
CaseTable.Clear();
adapter.Fill(CaseTable);
if (CaseTable.Rows.Count < 1)
{
MessageBox.Show("Item Not Found", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
}
private void btnSave_Click(object sender, EventArgs e)
{
if (adapter.Update(CaseTable) < 1)
MessageBox.Show("No updates");
}
private void btnRefresh_Click(object sender, EventArgs e)
{
RefreshForm();
}
I don't know why this works, but here is how I fixed my problem. At the end of RefreshForm I add the line
CaseTable.Rows[0].BeginEdit();
and at the beginning of the Save event handler I add the line
CaseTable.Rows[0].EndEdit();
Now the changes are carried back to the database. I'm not sure why none of the online references I found made reference to this.

operation getting slower of fetching data from database and showing them into auto-complete text-box using textBox_TextChanged event

I am developing a winform app.I have a textbox.In this text box a user can write something into it.My job is to match every letter and comparing the text with database and show a suggestion of 10 words similar of the text from database.What i did was that:
private void textBox1_TextChanged(object sender, EventArgs e)
{
string a = textBox1.Text;
// Autocomplete for textbox
AutoCompleteStringCollection namesCollection = new AutoCompleteStringCollection();
SqlCeConnection con = new SqlCeConnection(#"Data Source=" + Directory.GetCurrentDirectory() + #"\Database\ghfghfgh.sdf;Password=1020;");
con.Open();
SqlCeCommand cmnd = con.CreateCommand();
cmnd.CommandType = CommandType.Text;
int fetchAmount = 10;
string userInput = textBox1.Text;
cmnd.CommandText = string.Format("SELECT top ({0}) english FROM dic WHERE english like '{1}%'",
fetchAmount.ToString(), userInput);
SqlCeDataReader dReader=null;
dReader = cmnd.ExecuteReader();
if (dReader !=null)
{
while (dReader.Read())
namesCollection.Add(dReader["english"].ToString());
}
else
{
// MessageBox.Show("Data not found");
}
dReader.Close();
textBox1.AutoCompleteMode = AutoCompleteMode.Suggest;
textBox1.AutoCompleteSource = AutoCompleteSource.CustomSource;
textBox1.AutoCompleteCustomSource = namesCollection;
// end of autocomplete
con.Close();
}
But it is getting too slower.Sometimes it crashes.I need a solution .What can i do to make it faster????
What can i do to make it faster and efficient????
Hard to do with your current design. However, I think it is common to use Timer (System.Windows.Forms.Timer).
private void textBox1_TextChanged(object sender, EventArgs e)
{
timerText.Stop();
timerText.Start();
}
private void TimerText_Ticket(object sender, EventArgs e) // forget what event args type is it
{
//do the operation
timerText.Stop();
}
This way, you won't do query each time you make text change, but instead spend a brief period of time before the execution.
Open the connection on Form level rather than on the event handler.
For ultimate performance, bypass the Query processor
private SqlCeConnection conn;
Form__Load()
{
conn = new SqlCeConnection(connectionString);
conn.Open();
}

Help with updating access database using Update(dataTable)

I have looked all over the place but I cant seem to get this to work.
I am trying to update an Access database from a DataGridView. The loading of the database to the grid works fine. I used the instructions described in this site.
However, to update the database based on changes made to the DataGridView, I used the command dataAdapter.Update(datatable);, but depending on the placement (next to this code) the code runs but the database does not update. If I put it in a button it throws an exception "syntax error in insert into statement".
Other question: Should I close the connection variable after loading the DataGridView? If so, should I reopen it to perform the update and then reclose it? How does that work?.
Any help would be greatly appreciated.
EDIT: Putted whole class as Tim asked.
public partial class Pantalla_Proyecto : Form
{
private Inicio Inicio;
private List<string> Logueado;
private OleDbConnection conn;
private OleDbDataAdapter Adaptador;
private DataTable Tabla;
private BindingSource Bsource;
private OleDbCommandBuilder Builder;
public Pantalla_Proyecto(Inicio Inicio, List<string> Logueado)
{
this.Inicio =Inicio;
this.Logueado = Logueado;
InitializeComponent();
}
private void Pantalla_Proyecto_Load(object sender, EventArgs e)
{
}
private void importarCDPToolStripMenuItem_Click(object sender, EventArgs e)
{
Importar_CDP Importar_CDP = new Importar_CDP();
Importar_CDP.Show();
}
private void importarListasToolStripMenuItem_Click(object sender, EventArgs e)
{
WindowsFormsApplication1.Formularios.Lista_Lazos.Importar_Listas1 Importar_Listas = new WindowsFormsApplication1.Formularios.Lista_Lazos.Importar_Listas1();
Importar_Listas.Show();
}
private void dataGridView1_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
}
private void button1_Click(object sender, EventArgs e)
{
}
private void flowLayoutPanel2_Paint(object sender, PaintEventArgs e)
{
}
private void menuStrip1_ItemClicked(object sender, ToolStripItemClickedEventArgs e)
{
}
private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
string sql = "Select * From ["+TABLE (THIS IS A STRING I GET FROM PREVIOUS FORM)+"]";
conn = new OleDbConnection(#"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=proyectos\" + Location(this is a string i get on the previous form) + ".mdb;User Id=admin;Password=;");
conn.Open();
// Extraemos info de mi database y la meto en un datatable
Adaptador = new OleDbDataAdapter(sql, conn);
Builder = new OleDbCommandBuilder(Adaptador);
Tabla = new DataTable();
Adaptador.Fill(Tabla);
// LLENO EL DATA GRID VIEW
Bsource = new BindingSource();
Bsource.DataSource = Tabla;
dataGridView1.DataSource = Bsource;
dataGridView1.Dock = DockStyle.Fill;
Adaptador.Update(Tabla);//if i put it here nothing happens
conn.Close();
}
private void dataGridView1_Validating(object sender, CancelEventArgs e)
{
}
private void button1_Click_1(object sender, EventArgs e)
{
conn.Open();
Adaptador.Update(Tabla);//IF i put it here i get an exception
conn.Close();
}
To elaborate, as per OP's request, on the using statement, let's take the comboBox1_SelectedIndexChanged method:
private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
string sql = "Select * From ["+TABLE (THIS IS A STRING I GET FROM PREVIOUS FORM)+"]";
using (conn = new OleDbConnection(#"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=proyectos\" + Location(this is a string i get on the previous form) + ".mdb;User Id=admin;Password=;"))
{
conn.Open();
// Extraemos info de mi database y la meto en un datatable
Adaptador = new OleDbDataAdapter(sql, conn);
// Remove the OleDbCommandBuilder
Tabla = new DataTable();
Adaptador.Fill(Tabla);
// LLENO EL DATA GRID VIEW
Bsource = new BindingSource();
Bsource.DataSource = Tabla;
dataGridView1.DataSource = Bsource;
dataGridView1.Dock = DockStyle.Fill;
// ** NOTE:
// At this point, there's nothing to update - all that
// has happened is that you've bound the DataTable
// to the DataGridView.
Adaptador.Update(Tabla);//if i put it here nothing happens
} // Your connection will be closed at this point when the using
// statement goes out of scope.
}
UPDATE
MSDN says "When you create a new instance OleDbCommandBuilder, any existing OleDbCommandBuilder associated with this OleDbDataAdapter is released."
However, if you want to get away from the OleDbCommandBuilder completely, you can do so (I updated my code above to do just that). Since you believe you're having issues with special characters, it's probably worthwhile to do it this way.
Something like this should help - you'll have to modify the update command based on what your table columns are:
private void button1_Click_1(object sender, EventArgs e)
{
conn.Open();
Adaptador.UpdateCommand = "<Your SQL here>" // I.e., UPDATE [TABLE] SET....
try
{
Adaptador.Update((DataTable)Bsource.DataSource);
}
catch (Exception ex)
{
// Do something with the exception
}
}
This code is a slightly modified version of what MSDN has:
How to: Bind Data to the Windows Forms DataGridView Control
Note that they use a SqlDbCommandBuilder in the example, but the overall principle remains the same.
Based on David-W-Fenton's comment, you might want to do your connection and dataadapter initializations in the Form_Load event, and then close the connection on Form_Closing event.
First thing to check is the runtime path of the Access file that you're actually updating.
If you're using VS.NET, that the MDB file is part of your project, and that the "Copy Local" option is set to true on the MDB file, then it could just be that every time you run your program you overwrite the updates from the last execution.
I'm just mentioning because I've been bitten by this one ;-)
Cheers

Categories