I am having a weird problem. I am using vs2012 to connect to SQL Server CE and executing some insert queries.
public void EstablishConnection()
{
connection = new SqlCeConnection("Data Source=DataDump.sdf;Persist Security Info=False;");
try
{
connection.Open();
Console.WriteLine("Connection Successful");
}
catch (Exception exception)
{
Console.WriteLine(exception.Message);
}
}
public void AddRecord(string link,string content)
{
int num = 0;
var command = new SqlCeCommand("INSERT INTO Webpages(Link,Data) VALUES('"+link+"','"+content+"');",connection);
num = command.ExecuteNonQuery();
Console.WriteLine("Command Successful rows affected"+num);
var cmd2 = new SqlCeCommand("SELECT * FROM Webpages",connection);
SqlCeDataReader reader = cmd2.ExecuteReader();
while (reader.Read())
{
Console.WriteLine(reader[0]);
Console.WriteLine(reader[1]);
}
}
However I am having the problem that once VS is closed and when later I open it to display the data, the data is gone as it was never saved
How is that possible when it is clear then it executed the query?
It is a common scenario.
You have your database file listed between your project items.
Its property Copy to Output directory is set to Copy Always.
Now, you run your debug session with VS. The compile is succesfull and VS copies your sdf file from the project folder to the current output directory (BIN\DEBUG).
Your code runs smoothly and inserts the data in your database file (on the output directory).
You stop and restart the debug session to fix something, but, at restart, the VS recopies the empty file from the project folder to the output directory.
To break this circle, set Copy to Output Directory to Copy Never (or Copy if Newer)
EDIT Another source of confusion is due to the use of SERVER EXPLORER to view the contents of your database file. If the server explorer use a connection string that points to the database file in the project folder you never see the changes made to the database file in the Output Directory.
You should create two connections in Server Explorer, one named DEBUG DataDump that points to PROJECTFOLDER\BIN\DEBUG. You could use this connection to check the data inserted during debug or for other debugging tasks. Another one, called DISTRIBUTION DataDump, points to the file in the project folder and you make here your schema changes needed for the distribution of your app.
Said that, keep in mind that your code has a BIG problem. It is called Sql Injection
A parameterized query will avoid quotations problems and remove the Sql Injection
int num = 0;
var command = new SqlCeCommand("INSERT INTO Webpages(Link,Data) " +
"VALUES(#lnk, #cnt)",connection);
command.Parameters.AddWithValue("#lnk", link);
command.Parameters.AddWithValue("#cnt", content);
num = command.ExecuteNonQuery();
set Copy to Output Directory property as Copy if newer for your sdf file
it seems now you have set it as copy always which result :
The database file is copied from the project directory to the bin
directory every time that you build your application. Any changes made
to the data file in the output folder are overwritten the next time
that you run the application.
Related
So i have a problem updating record in my database. My code runs without error, but the record is not updated. Here is the code:
private void button3_Click(object sender, EventArgs e)
{
try
{
if (con.State == ConnectionState.Closed)
{
con.Open();
}
string sql = string.Format("update Alternatif set No ='" + textBox1.Text + "',Kecamatan='" + textBox2.Text + "',Kelurahan='" + textBox3.Text + "',Nama='" + textBox4.Text + "'where No ='" + textBox1.Text + "'");
OleDbCommand perintah = new OleDbCommand(sql, con);
perintah.ExecuteNonQuery();
MessageBox.Show("Data edited successfully");
perintah.Dispose();
con.Close();
}
catch (Exception)
{
MessageBox.Show("Data failed to edit");
}
}
I'm assuming you have proven that the query works to update the record in access - you should consider capturing the int that is returned from ExecuteNonQuery and if it is 0, no records were updated
You should also consider having a good read of http://bobby-tables.com and promise yourself never to write an SQL again like you have there. It is prone to sql injection attack and is a massive security issue
Access is a file based database and typically when added to a visual studio there is a dev version of the file (the file as it was when selected for addition to the project) that is copied to the build directory every time a build is run. The app typically updates the build copy in the bin directory, not the dev copy outside the bin directory.
Developers then go looking in the dev copy and are surprised that no change was made- they're looking in the wrong file.
Or they go looking in the build copy, but after another build has been run and the edited db has been overwritten with a fresh, empty copy of the dev db. Search your project folder for all db and ensure you're inspecting the right one
You can stop the build process replacing the bin folder version of the file every time by finding the db in the solution explorer, getting properties on it and setting the Copy To Output Directory to something other than Copy Always. I personally use Copy If Newer
I have following C# code in a console application.
Whenever I debug the application and run the query1 (which inserts a new value into the database) and then run query2 (which displays all the entries in the database), I can see the new entry I inserted clearly. However, when I close the application and check the table in the database (in Visual Studio), it is gone. I have no idea why it is not saving.
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data.SqlServerCe;
using System.Data;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
try
{
string fileName = "FlowerShop.sdf";
string fileLocation = "|DataDirectory|\\";
DatabaseAccess dbAccess = new DatabaseAccess();
dbAccess.Connect(fileName, fileLocation);
Console.WriteLine("Connected to the following database:\n"+fileLocation + fileName+"\n");
string query = "Insert into Products(Name, UnitPrice, UnitsInStock) values('NewItem', 500, 90)";
string res = dbAccess.ExecuteQuery(query);
Console.WriteLine(res);
string query2 = "Select * from Products";
string res2 = dbAccess.QueryData(query2);
Console.WriteLine(res2);
Console.ReadLine();
}
catch (Exception e)
{
Console.WriteLine(e);
Console.ReadLine();
}
}
}
class DatabaseAccess
{
private SqlCeConnection _connection;
public void Connect(string fileName, string fileLocation)
{
Connect(#"Data Source=" + fileLocation + fileName);
}
public void Connect(string connectionString)
{
_connection = new SqlCeConnection(connectionString);
}
public string QueryData(string query)
{
_connection.Open();
using (SqlCeDataAdapter da = new SqlCeDataAdapter(query, _connection))
using (DataSet ds = new DataSet("Data Set"))
{
da.Fill(ds);
_connection.Close();
return ds.Tables[0].ToReadableString(); // a extension method I created
}
}
public string ExecuteQuery(string query)
{
_connection.Open();
using (SqlCeCommand c = new SqlCeCommand(query, _connection))
{
int r = c.ExecuteNonQuery();
_connection.Close();
return r.ToString();
}
}
}
EDIT: Forgot to mention that I am using SQL Server Compact Edition 4 and VS2012 Express.
It is a quite common problem. You use the |DataDirectory| substitution string. This means that, while debugging your app in the Visual Studio environment, the database used by your application is located in the subfolder BIN\DEBUG folder (or x86 variant) of your project. And this works well as you don't have any kind of error connecting to the database and making update operations.
But then, you exit the debug session and you look at your database through the Visual Studio Server Explorer (or any other suitable tool). This window has a different connection string (probably pointing to the copy of your database in the project folder). You search your tables and you don't see the changes.
Then the problem get worse. You restart VS to go hunting for the bug in your app, but you have your database file listed between your project files and the property Copy to Output directory is set to Copy Always. At this point Visual Studio obliges and copies the original database file from the project folder to the output folder (BIN\DEBUG) and thus your previous changes are lost.
Now, your application inserts/updates again the target table, you again can't find any error in your code and restart the loop again until you decide to post or search on StackOverflow.
You could stop this problem by clicking on the database file listed in your Solution Explorer and changing the property Copy To Output Directory to Copy If Newer or Never Copy. Also you could update your connectionstring in the Server Explorer to look at the working copy of your database or create a second connection. The first one still points to the database in the project folder while the second one points to the database in the BIN\DEBUG folder. In this way you could keep the original database ready for deployment purposes and schema changes, while, with the second connection you could look at the effective results of your coding efforts.
EDIT Special warning for MS-Access database users. The simple act of looking at your table changes the modified date of your database ALSO if you don't write or change anything. So the flag Copy if Newer kicks in and the database file is copied to the output directory. With Access better use Copy Never.
Committing changes / saving changes across debug sessions is a familiar topic in SQL CE forums. It is something that trips up quite a few people. I'll post links to source articles below, but I wanted to paste the answer that seems to get the best results to the most people:
You have several options to change this behavior. If your sdf file is part of the content of your project, this will affect how data is persisted. Remember that when you debug, all output of your project (including the sdf) if in the bin/debug folder.
You can decide not to include the sdf file as part of your project and manage the file location runtime.
If you are using "copy if newer", and project changes you make to the database will overwrite any runtime/debug changes.
If you are using "Do not copy", you will have to specify the location in code (as two levels above where your program is running).
If you have "Copy always", any changes made during runtime will always be overwritten
Answer Source
Here is a link to some further discussion and how to documentation.
I have following C# code in a console application.
Whenever I debug the application and run the query1 (which inserts a new value into the database) and then run query2 (which displays all the entries in the database), I can see the new entry I inserted clearly. However, when I close the application and check the table in the database (in Visual Studio), it is gone. I have no idea why it is not saving.
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data.SqlServerCe;
using System.Data;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
try
{
string fileName = "FlowerShop.sdf";
string fileLocation = "|DataDirectory|\\";
DatabaseAccess dbAccess = new DatabaseAccess();
dbAccess.Connect(fileName, fileLocation);
Console.WriteLine("Connected to the following database:\n"+fileLocation + fileName+"\n");
string query = "Insert into Products(Name, UnitPrice, UnitsInStock) values('NewItem', 500, 90)";
string res = dbAccess.ExecuteQuery(query);
Console.WriteLine(res);
string query2 = "Select * from Products";
string res2 = dbAccess.QueryData(query2);
Console.WriteLine(res2);
Console.ReadLine();
}
catch (Exception e)
{
Console.WriteLine(e);
Console.ReadLine();
}
}
}
class DatabaseAccess
{
private SqlCeConnection _connection;
public void Connect(string fileName, string fileLocation)
{
Connect(#"Data Source=" + fileLocation + fileName);
}
public void Connect(string connectionString)
{
_connection = new SqlCeConnection(connectionString);
}
public string QueryData(string query)
{
_connection.Open();
using (SqlCeDataAdapter da = new SqlCeDataAdapter(query, _connection))
using (DataSet ds = new DataSet("Data Set"))
{
da.Fill(ds);
_connection.Close();
return ds.Tables[0].ToReadableString(); // a extension method I created
}
}
public string ExecuteQuery(string query)
{
_connection.Open();
using (SqlCeCommand c = new SqlCeCommand(query, _connection))
{
int r = c.ExecuteNonQuery();
_connection.Close();
return r.ToString();
}
}
}
EDIT: Forgot to mention that I am using SQL Server Compact Edition 4 and VS2012 Express.
It is a quite common problem. You use the |DataDirectory| substitution string. This means that, while debugging your app in the Visual Studio environment, the database used by your application is located in the subfolder BIN\DEBUG folder (or x86 variant) of your project. And this works well as you don't have any kind of error connecting to the database and making update operations.
But then, you exit the debug session and you look at your database through the Visual Studio Server Explorer (or any other suitable tool). This window has a different connection string (probably pointing to the copy of your database in the project folder). You search your tables and you don't see the changes.
Then the problem get worse. You restart VS to go hunting for the bug in your app, but you have your database file listed between your project files and the property Copy to Output directory is set to Copy Always. At this point Visual Studio obliges and copies the original database file from the project folder to the output folder (BIN\DEBUG) and thus your previous changes are lost.
Now, your application inserts/updates again the target table, you again can't find any error in your code and restart the loop again until you decide to post or search on StackOverflow.
You could stop this problem by clicking on the database file listed in your Solution Explorer and changing the property Copy To Output Directory to Copy If Newer or Never Copy. Also you could update your connectionstring in the Server Explorer to look at the working copy of your database or create a second connection. The first one still points to the database in the project folder while the second one points to the database in the BIN\DEBUG folder. In this way you could keep the original database ready for deployment purposes and schema changes, while, with the second connection you could look at the effective results of your coding efforts.
EDIT Special warning for MS-Access database users. The simple act of looking at your table changes the modified date of your database ALSO if you don't write or change anything. So the flag Copy if Newer kicks in and the database file is copied to the output directory. With Access better use Copy Never.
Committing changes / saving changes across debug sessions is a familiar topic in SQL CE forums. It is something that trips up quite a few people. I'll post links to source articles below, but I wanted to paste the answer that seems to get the best results to the most people:
You have several options to change this behavior. If your sdf file is part of the content of your project, this will affect how data is persisted. Remember that when you debug, all output of your project (including the sdf) if in the bin/debug folder.
You can decide not to include the sdf file as part of your project and manage the file location runtime.
If you are using "copy if newer", and project changes you make to the database will overwrite any runtime/debug changes.
If you are using "Do not copy", you will have to specify the location in code (as two levels above where your program is running).
If you have "Copy always", any changes made during runtime will always be overwritten
Answer Source
Here is a link to some further discussion and how to documentation.
I'm adding new lines to a database for our company's "order list" for each order created, using the firebird ado.net client. The code i've written works fine for listing items, but inserting new ones doesn't appear elsewhere (e.g. in flamerobin). What I think is happening is that the transaction isn't being committed, seeing as it's recognised within my code (can't add duplicate values).
Code:
using (FbConnection fbCon = new FbConnection)
{
fbCon.Open();
***command w/ parameterised command string***
using (FbTransaction fbTrans = fbCon.BeginTransaction())
using FbCommand orderCommand = new FbCommand(cmdString, fbCon, fbTrans)
{
***Adding parameters and values***
try
{
int recordsAffected = orderCommand.ExecuteNonQuery();
fbTrans.Commit();
}
catch (FbException E)
{
fbTrans.Rollback();
fbCon.Close();
throw E
}
}
recordsAffected returns 1 but I am not able to see the updated values in flamerobin or the db management program. Am i missing something?
If anyone else runs into this problem, it's in Visual Studio's debugging settings. https://visualstudiomagazine.com/blogs/tool-tracker/2012/05/dealing-with-local-databases-or-why-your-updates-dont-stick.aspx explains pretty clearly, but basically VS makes a copy of your database in bin/Debug of your project (Ostensibly to not mess with your data) but if you actually need to use/view the data externally, either link your external application to the debug database (e.g. flamerobin). You may also need to set your project database settings to Copy if Newer if you want your updates to stay, as the default setting copies the database into the folder each time you run your c# app.
I create simple example to create question easyer.
So in my c# project I create an mdf database with articles. Then I connect database in my program and read values from table articles. It gives me results, but not the latest.
If I have one result it showes me this one. Then I go in articles table to add one new article and run program again and in this case program showes me only the first one. But if I "Build solution" it finds all of them.
What I have to do? I wish, that program will have the latest result on startup.
SqlConnection cn = new SqlConnection(#"Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|\Database.mdf;Integrated Security=True;User Instance=True");
try
{
cn.Open();
string sqlQuery = "SELECT * FROM Articles";
SqlCommand sqlCommand = new SqlCommand(sqlQuery, cn);
SqlDataReader sqlDataRead = sqlCommand.ExecuteReader();
while (sqlDataRead.Read())
{
MessageBox.Show(Convert.ToString(sqlDataRead["ArticleLabel"]));
}
sqlDataRead.Close();
sqlDataRead.Dispose();
sqlCommand.Cancel();
cn.Close();
}
catch (Exception) { MessageBox.Show("Database error!"); Application.Exit(); }
If your MDF file has the property Copy To Output Directory set to Copy Always, then every time you build your application a fresh copy of the database file is copied from the project directory to the output Directory (BIN\DEBUG or BIN\RELEASE).
Of course this destroy any changes you have made in a previous run of your program
Change the property to Copy if Newer
Also, don't be fooled by what you see in the Server Manager Windows. The connections there could not point to the database in the Output directory but on the database in the Project Directory where you don't write anything.