C# And Access 2007: Insert & Update functions not working properly? - c#

I have two functions. Insert functions provided by Soner Gönül (thanks),......
Table Name Students
Database
`Field Name Data Type
*StudentID Number
StudentName Text
StudentCNIC Text
StudentDOB Date/Time
*PK
using System.Data.OleDb;
private void Form1_Load(object sender, EventArgs e)
{
myCon = new OleDbConnection(#"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=|DataDirectory|\Access_and_CSharp.accdb");
this.studentsTableAdapter.Fill(this.access_and_CSharpDataSet.Students);
}
Insert Function
private void Insertbtn_Click(object sender, EventArgs e)
{
OleDbCommand cmd = new OleDbCommand();
cmd.CommandType = CommandType.Text;
cmd.CommandText = "INSERT INTO Students(StudentID, StudentName, StudentCNIC, StudentDOB) Values(#StudIDTxt, #StudNameTxt, #StudCNCITxt, #StudDOBTxt)";
cmd.Parameters.AddWithValue("#StudIDTxt", StudIDTxt.Text);
cmd.Parameters.AddWithValue("#StudNameTxt", StudNameTxt.Text);
cmd.Parameters.AddWithValue("#StudCNCITxt", StudCNCITxt.Text);
cmd.Parameters.AddWithValue("#StudDOBTxt", StudDOBTxt.Text);
cmd.Connection=myCon;
myCon.Open();
cmd.ExecuteNonQuery();
myCon.Close();
}
And this is the update function
private void Updatebtn_Click(object sender, EventArgs e)
{
OleDbCommand cmd = new OleDbCommand();
cmd.CommandType = CommandType.Text;
cmd.CommandText = "UPDATE [Students] set [StudentName] = ?, [StudentCNIC] = ?, [StudentDOB] = ? WHERE [StudentID] = ?";
cmd.Parameters.AddWithValue("#StudIDTxt", StudIDTxt.Text);
cmd.Parameters.AddWithValue("#StudNameTxt", StudNameTxt.Text);
cmd.Parameters.AddWithValue("#StudCNCITxt", StudCNCITxt.Text);
cmd.Parameters.AddWithValue("#StudDOBTxt", StudDOBTxt.Text);
cmd.Connection = myCon;
myCon.Open();
int rowsAffected = cmd.ExecuteNonQuery();
myCon.Close();
}
Problem 1 -
When I use the insert function I can see new data at the front end. But I cannot see the new data in Access. Other times when I close the application and restart, new recorded is not there. If I look in Access application and closed it then open VS2010 application new data is not there. What is going on?
Problem 2 -
When I use the update function, data remains updated while the application running first time. This is not true when the application is closed and running again. Where have I gone wrong?
For both of problems can anyone see where the problem(s) is/are?
Thanks in advance
EDIT
Updating to say I am looking the following website where I have gone wrong.
http://www.c-sharpcorner.com/uploadfile/e628d9/inserting-retrieving-records-from-ms-access-2007-using-odbc/
Update
I have Windows 7, MS Access 2007 and VS 2010. I am wondering if this is the problem. If it is then it's probably not worth the trouble. I have downloaded AccessDatabaseEngine but its 32bit so I don't know? Probably make my life easier if I use SQL Server instead of Access.
I think this question has been asked too many times.

For starters, make sure your database is NOT included with your project builds.
In Solution Explorer, find your database and specify Build Action = None and Copy to Output Directory = Do not copy
Your database should reside in a folder other than your bin folder, otherwise every time you fire up your project, you will copy to your output folder the same database that is in your project.
Instead, locate the database somewhere else (C:\Program Files (x86)\Common Files or some other location) and connect to it.
There could be other issues with your project, but this is a big one that is jumping out at me.

Related

Cannot create new record to the database; no error message

I'm trying to add new record to trans_daily table, however, the code snippet below executed on button click doesn't work.
THE PROBLEMATIC CODE
private void button1_Click(object sender, EventArgs e)
{
try
{
SqlConnection connection = new SqlConnection(conString);
connection.Open();
string strcom = "INSERT INTO trans_daily (retail_id, cust_name, quantity, " +
"price, date, visibility, remarks_id) VALUES (#RetailID, #CustomerName, " +
"#Quantity, #Price, #Date, #Visibility, #RemarksID)";
SqlCommand cmd = new SqlCommand(strcom, connection);
cmd.Parameters.AddWithValue("#RetailID", ddRetailType.SelectedValue);
cmd.Parameters.AddWithValue("#CustomerName", tbCustomer.Text);
cmd.Parameters.AddWithValue("#Quantity", float.Parse(tbQuantity.Text));
cmd.Parameters.AddWithValue("#Price", float.Parse(tbPrice.Text));
cmd.Parameters.AddWithValue("#Date", DateTime.Now);
cmd.Parameters.AddWithValue("#Visibility", 1);
cmd.Parameters.AddWithValue("#RemarksID", 1);
cmd.ExecuteNonQuery();
}
catch (Exception err)
{
Console.WriteLine(err.Message);
}
}
The following are the data types:
retail_id (int)
cust_name (varchar50)
quantity (float)
price (float)
date (datetime)
visibility (int)
remarks_id (int)
It's also worth to point out that no exception is being thrown.
What could have gone wrong?
THE WORKING CODE
In a separate function, I was able to pull out data from retail table on form load and placed the pulled out data to a dropdown list.
private void formAddTransaction_Load(object sender, EventArgs e)
{
try
{
objConnect = new DatabaseConnection();
conString = Properties.Settings.Default.MVGasConnectionString;
objConnect.Sql = "SELECT * FROM retail";
objConnect.connection_string = conString;
ds = objConnect.GetConnection;
MaxRows = ds.Tables[0].Rows.Count;
FillRetailTypes(conString);
}
catch (Exception err)
{
MessageBox.Show(err.Message);
}
}
public void FillRetailTypes(string constring)
{
ddRetailType.DataSource = ds.Tables[0];
ddRetailType.ValueMember = "id";
ddRetailType.DisplayMember = "type";
}
Try this code and you may find your error:
try
{
using(SqlConnection connection = new SqlConnection(conString))
using(SqlCommand cmd = new SqlCommand())
{
connection.Open();
string strcom = "INSERT INTO trans_daily ([retail_id], [cust_name], [quantity], " +
"[price], [date], [visibility], [remarks_id]) VALUES (#RetailID, #CustomerName, " +
"#Quantity, #Price, #Date, #Visibility, #RemarksID)";
cmd.CommandText = strcom;
cmd.Connection = connection;
cmd.Parameters.AddWithValue("#RetailID", SqlDbType.Int);
cmd.Parameter["#RetailID"].Value = ddRetailType.SelectedValue;
cmd.Parameters.AddWithValue("#CustomerName", SqlDbType.VarChar);
cmd.Parameter["#CustomerName"].Value = tbCustomer.Text;
cmd.Parameters.AddWithValue("#Quantity", SqlDbType.Float);
cmd.Parameter["#Quantity"].Value = float.Parse(tbQuantity.Text);
cmd.Parameters.AddWithValue("#Price", SqlDbType.Float);
cmd.Paramter["#Price"].Value = float.Parse(tbPrice.Text);
cmd.Parameters.AddWithValue("#Date", SqlDbType.DateTime);
cmd.Parameter["#Date"].Value = DateTime.Now;
cmd.Parameters.AddWithValue("#Visibility", SqlDbType.Int);
cmd.Parameter["#Visibility"].Value = 1;
cmd.Parameters.AddWithValue("#RemarksID", SqlDbType.Int);
cmd.Parameter["#RemarksID"].Value = 1;
int affectedRows = cmd.ExecuteNonQuery();
Console.WriteLine("You have inserted {0} rows", affectedRows);
}
}
catch(Exception e)
{
Console.WriteLine(e.Message);
}
This code will...
... automatically open and close your database connection and command object
... log the amount of affected rows in the database to the console
... log exception messages to the console. You may add a breakpoint to this line if you want to see the whole exception (if one occures)
As explained in this blog, it seems like the problem is in the connection string.
Inside the project folder, 2 .mdf files were created: one is found at the root of the folder (let's call it mdf_1) and the other is inside the bin\Debug folder (let's call it mdf_2).
Now, taking a look inside the Visual Studio (VS) editor, there are 2 .mdf files shown: one under the Server Explorer, and another under the Solution Explorer. Not taking note of the location (from the properties section) of these .mdf files made me think these 2 .mdf files were the same. The thing is, the one under the Server Explorer is mdf_1 while mdf_2 is the one under the Solution Explorer.
VS has a behavior that copies mdf_1 and overwrites mdf_2 everytime the program is run (because by default, .mdf is set to Copy always mdf_1 to mdf_2). My connection string was pointing to the mdf_2 which explains why despite cmd.ExecuteNonQuery() command returns 1, my successfully inserted records are always erased because of the behavior VS has. And since it is mdf_1 that is under Server Explorer, I could not verify the changes in DB. Simply put, I was making changes in mdf_2 while trying to look for the changes in mdf_1.
So to avoid this, I modified my connection string by changing the relative path |DataDirectory| in the connection string to the absolute path of mdf_1 so that no matter how often VS overwrites mdf_2, the changes I make during runtime in mdf_1 aren't overwritten. This was, changes are also reflected in the Server Explorer (where I verify if changes were actually made).
tl;dr : I was updating the .mdf file under bin\Debug folder during runtime while physically looking for the updates in the .mdf file located in the root of the project.

LocalDB changes persist in different mdf files - Why?

I am trying to rebuild an application that originally used sqlite to now use 'localdb'. (I want an application that can create its own database locally and at runtime without requiring a pre-installed instance of sql server or sql express on the target machine)
I want to move away from using a 'third party' library (sqlite) as experience has told me it can be a pain to get it working from scratch, and towards something supposedly more straightforward to get up and running from scratch.
Using code copied (and slightly modified) from the web I have managed to create an mdf file dynamically/programmatically, but I am puzzled by what happens if I run it more than once, even if I choose a new filename each time. Namely it seems to somehow keep the changes/additions made on each run. Below is the relevant code...
public partial class Form1 : Form
{
SqlConnection conn;
public void CreateSqlDatabase(string filename)
{
string databaseName =
System.IO.Path.GetFileNameWithoutExtension(filename);
conn = new SqlConnection(
String.Format(
#"Data Source=(LocalDB)\v11.0;Initial Catalog=master;Integrated Security=True"
));
conn.Open();
using (var command = conn.CreateCommand())
{
command.CommandText =
String.Format(
"CREATE DATABASE {0} ON PRIMARY (NAME={0}, FILENAME='{1}')"
, databaseName, filename);
command.ExecuteNonQuery();
command.CommandText =
String.Format("EXEC sp_detach_db '{0}', 'true'", databaseName);
command.ExecuteNonQuery();
}
conn.Close();
}
private void button1_Click(object sender, EventArgs e)
{
if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
CreateSqlDatabase(openFileDialog1.FileName);
}
}
private void button2_Click(object sender, EventArgs e)
{
conn.Open();
SqlCommand comm = conn.CreateCommand();
comm.CommandText =
"create table mytable (id int, name nvarchar(100))";
comm.ExecuteNonQuery();
comm.CommandText =
"insert into mytable (id,name) values (10,'testing')";
comm.ExecuteNonQuery();
comm.CommandText = "select * from mytable";
SqlDataReader reader = comm.ExecuteReader();
while (reader.Read())
{
textBox1.Text +=
reader["id"].ToString() + ", " + reader["name"].ToString() + "\r\n";
}
conn.Close();
}
}
If I run the app once It runs through fine.
If I run the app a second time, and choose a different filename for the database it tells me 'mytable' already exists.
If I comment out the create table code it runs, but the select query returns multiple rows indicating multiple inserts (one for each time the app runs)
I am just seeking to understand why this happens. Do I need to delete database/table each time if I want the app to behave as if it has created the database/table from scratch on each subsequent run?
You have initial catalog 'master' in your connection string. Are you sure you haven't created the tables in the master database instead of the newly created database?
After the creation & detach of the database file, you could try and change your connection to:
SqlConnection con = new SqlConnection(#"Data Source=(LocalDB)\v11.0;Integrated Security=True;AttachDbFilename=c:\xxx\xxx\xxx.mdf");

Invalid object name 'tbl_Shading_Analysis'.?

I am trying to insert textbox value into database in my asp.net project. While using this code some errors are generating. Please help me.
protected void btnSubmit_Click(object sender, EventArgs e)
{
SqlConnection con = new SqlConnection();
SqlCommand cmd = new SqlCommand();
con.ConnectionString = (#"connectionString");
con.Open();
cmd.Connection = con;
cmd.CommandText=("INSERT INTO tbl_Shading_Analysis(Load_Band) VALUES ('"+txtLoadBand.Text+"')");
cmd.ExecuteNonQuery();
con.Close();
}
I means the table tbl_Shading_Analysis doesn't exist in the connection you are using, it may cause if you have some triggers attached with the table there may be some issue.
Check if you are connected to the right server/database.
Check any triggers that run on that table as well and make sure all of them have the exact table name spelled correctly.
Try to use the full schema for the referenced table if you have checked above two point for correctness.
Ex: [DatabaseName].[Schema].[TableName] or [Database1].[smmdmm].[aid_data]
That error is coming because the table tbl_Shading_Analysis does not exist in your database.
Check your connection string if you have given the correct database name.
Check if you have created that table in the specified database.
Check if the spelling of the table name is different from what you have specified

Empty database table

I want to insert values in "Navn" row and "Varenr" row in the DB table, when I'm clicking on a button. I have following code:
private void button2_Click(object sender, EventArgs e)
{
using (SqlConnection cn = new SqlConnection(#"Data Source=(LocalDB)\v11.0;AttachDbFilename=|DataDirectory|\Produkt.mdf;Integrated Security=True"))
{
try
{
SqlCommand cm = new SqlCommand();
cm.Connection = cn;
string col1 = textBox2.Text;
string col2 = textBox3.Text;
//generate sql statement
cm.CommandText = "INSERT INTO ProduktTable (Navn,Varenr) VALUES (#col1,#col2)";
//add some SqlParameters
SqlParameter sp_add_col1 = new SqlParameter();
sp_add_col1.ParameterName = "#col1";
//data type in sqlserver
sp_add_col1.SqlDbType = SqlDbType.NVarChar;
//if your data type is not number,this property must set
//sp_add_col1.Size = 20;
sp_add_col1.Value = textBox2.Text;
//add parameter into collections
cm.Parameters.Add(sp_add_col1);
//in your insert into statement, there are how many parameter, you must write the number of parameter
SqlParameter sp_add_col2 = new SqlParameter();
sp_add_col2.ParameterName = "#col2";
//data type in sqlserver
sp_add_col2.SqlDbType = SqlDbType.NVarChar;
//if your data type is not number,this property must set
//sp_add_col2.Size = 20;
sp_add_col2.Value = textBox2.Text;
//add parameter into collections
cm.Parameters.Add(sp_add_col2);
//open the DB to execute sql
cn.Open();
cm.ExecuteNonQuery();
cn.Close();
}
catch (Exception ex)
{
MessageBox.Show("Error\n" + ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
But unfortunately, my data table is still empty:
I have set a breakpoint on the ExecuteNonQuery function, and it is triggered, when pressing on the button:
My table definition:
Your connection string is causing this:
Data Source=(LocalDB)\v11.0;AttachDbFilename=|DataDirectory|\Produkt.mdf;Integrated Security=True"
|DataDirectory| Your database that is being updated in this method is in your App Data Directory while the one you are trying to retrieve data from is in your project folder...
|DataDirectory| is a substitution string that indicates the path to the database. DataDirectory also makes it easy to share a project and also to deploy an application. For my PC my App Data Directory is:
C:\Users\MyUserName\AppData\...
If you browse to this location and then go to following folders
...\Local\Apps\2.0\Data
You will be able to find your particular application directory probably stored with your assembly name, or some hash when you go there you will find it the database there is being updated just fine. This connection string is best for deployment.
You can also try this:
If you notice that Server Explorer is detecting all the databases on my PC and you can notice that there are couple of MINDMUSCLE.MDF files but all are at different paths, this is because there is one file in DEBUG directory, one in my PROJECT directory, one in my APP DATA directory. The ones starting with the numbers are stored in my APP DATA directories... If you select your respective database file and then run the SELECT query against it, you will get your data.
I made a tutorial some time ago. May be it will help you:
Check the value that ExecuteNonQuery is returning. It should return an int with the number of records affected by the SQL statement.
If it comes back with a value other than 0, then you know a record is being inserted somewhere. Before you close the connection, run a SQL query against the table to select all of the records and see if they come back through the code.
SELECT * FROM ProduktTable
If you get some records, then you may want to double check the database you're looking at through the IDE and the one your inserting records into through the code. It could be possible that you've got two different databases and you're querying one while inserting into another one.
Those are the steps that I would go through to help narrow down the issue and sounds like something I've probably done before. I hope it helps!

C# database writing to table doesn't work

I have a problem using Visual Studio 2010. I am using a service-based database (.mdf).
I have created a table manually in Visual Studio with some information. The code I have written can read from the table but when I insert new information it looks like the data is added to some other database.
I can read information from the correct table but when I add information to the table I can’t see the changes in Server Explorer in Visual Studio.
I don't know why to different databases are used! Does anybody know the problem?
Here is my code:
public class DataAccess
{
private SqlConnection sqlConnection;
private SqlCommand sqlCommand;
private SqlDataAdapter dataAdapterAnimal;
private DataSet dataset;
private string connectionString = DBAccessLayer.Properties.Settings.Default.AnimalDBConnectionString;
public DataSet LoadAnimalDataSet()
{
dataset = new DataSet();
using (sqlConnection = new SqlConnection(connectionString))
{
sqlConnection.Open();
dataAdapterAnimal = new SqlDataAdapter("SELECT * FROM AnimalTable", sqlConnection);
dataAdapterAnimal.Fill(dataset, "AnimalTable");
sqlConnection.Close();
return dataset;
}
}
public void AddAnimal(int animalID, string name, double age, string category, string gender, string extraAnimalInfo)
{
sqlConnection = new SqlConnection(connectionString);
sqlCommand = new SqlCommand("INSERT INTO AnimalTable VALUES(#AnimalID, #Name, #Age, #Category, #Gender, #ExtraAnimalInfo)", sqlConnection);
try
{
sqlConnection.Open();
sqlCommand.Parameters.Add(new SqlParameter("#AnimalID", animalID));
sqlCommand.Parameters.Add(new SqlParameter("#Name", name));
sqlCommand.Parameters.Add(new SqlParameter("#Age", age));
sqlCommand.Parameters.Add(new SqlParameter("#Category", category));
sqlCommand.Parameters.Add(new SqlParameter("#Gender", gender));
sqlCommand.Parameters.Add(new SqlParameter("#ExtraAnimalInfo", extraAnimalInfo));
sqlCommand.ExecuteNonQuery();
sqlConnection.Close();
}
catch (Exception ex)
{
throw;
}
}
I haven't seen your connection string yet - but from your description, it seems it might be this problem here:
the whole User Instance and AttachDbFileName= approach is flawed - at best! When running your app in Visual Studio, it will be copying around the .mdf file (from your App_Data directory to the output directory - typically .\bin\debug - where you app runs) and most likely, your INSERT works just fine - but you're just looking at the wrong .mdf file in the end!
If you want to stick with this approach, then try putting a breakpoint on the myConnection.Close() call - and then inspect the .mdf file with SQL Server Mgmt Studio Express - I'm almost certain your data is there.
The real solution in my opinion would be to
install SQL Server Express (and you've already done that anyway)
install SQL Server Management Studio Express
create your database in SSMS Express, give it a logical name (e.g. MyDatabase)
connect to it using its logical database name (given when you create it on the server) - and don't mess around with physical database files and user instances. In that case, your connection string would be something like:
Data Source=.\\SQLEXPRESS;Database=MyDatabase;Integrated Security=True
and everything else is exactly the same as before...

Categories