I have a SQL Server database in a C# project.
I use a connection string to connect to it.. I can use the method ExecuteNonQuery to insert data, no problem there.
But when I delete, it only deletes it momentarily, as soon as I restart the application it kind of rolls back the deletion.. Any ideas?
PS: I tested the string in a direct query, and it worked fine there.
public void executeNonQuery(string input)
{
db.Open();
SqlCommand cmd = new SqlCommand(input, db);
cmd.ExecuteNonQuery();
db.Close();
}
EDIT: DELETION CODE:
private void buttonSletPost_Click(object sender, EventArgs e)
{
if(dataGridView1.GetCellCount(DataGridViewElementStates.Selected)>0){
for (int i = 0;i < dataGridView1.GetCellCount(DataGridViewElementStates.Selected); i++)
{
String str1 = String.Format("WARNING about to DELETE:\n {0} \n BE CAREFULL NO TURNING BACK NOW!", Regnskab.getInstance().dbSelectPostID(dataGridView1.SelectedCells[i].Value.ToString())[0].ToString());
if (MessageBox.Show(str1, "Confirm Deletion", MessageBoxButtons.YesNo) == DialogResult.Yes)
{
string str = String.Format("DELETE FROM PostTable WHERE PostID={0}", dataGridView1.SelectedCells[i].Value.ToString());
Database.getInstance().executeNonQuery(str);
Console.WriteLine(str);
}
}
}else {MessageBox.Show("No cells selected");}
}
Which will give following output:
DELETE FROM PostTable WHERE PostID=7
Connection string in app.config:
<connectionStrings>
<add name="EndProject.Properties.Settings.DBtestConnectionString" connectionString="Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|\DBtest.mdf;Integrated Security=True;Connect Timeout=30;User Instance=True" providerName="System.Data.SqlClient" />
private Database()
{
string connStr = ConfigurationManager.ConnectionStrings["EndProject.Properties.Settings.DBtestConnectionString"].ConnectionString;
db = new SqlConnection(connStr);
}
And then I open and close it, so the connection ain't open each time.
To be honest:
I don't exactly know where to see my DB info, here's some info from properties in VS2010.
Provider: .NET Framework Data Provider for SQL Server
Type: Microsoft SQL Server
Andrew's 3rd: I think they are deleted momentarily because I reloaded the information in my datagridview and from there it is gone. But then when I close the application and start it again, it is back...
Also i just checked with VS2010's server explorer and did a "Show Data" after I deleted (before I shut it down) and it wasn't deleted.
But I'm totally clueless now. :-(
Many applications use Transactions to manage db connections. SQL Server doesn't do it by default, but other factors in your application may be doing this.
Also, if you're really doing this, and your input is coming from a user interface, I can't wait to introduce you to Little Bobby Tables
Use the SQL Server Profiler to run a trace and capture the actual T-SQL statements that are getting executed on the database.
This is the easiest solution.
The behavior you're describing sounds like autocommit is off. Try the following and see if the record(s) stays deleted:
public void executeNonQuery(string input)
{
db.Open();
using (var txn = db.BeginTransaction())
{
SqlCommand cmd = new SqlCommand(input, db);
cmd.Transaction = txn;
cmd.ExecuteNonQuery();
db.Close();
txn.Commit();
}
}
Ok it was apperently me who was mistaken on the inserting part...
Someone suggested that i was because of the Visual Studio databases created every time the applikation ran.
So i installed MS SQL 2008 R2. Created a new DB with same layout.
Changed the connection string
And wuupti woo it seems to work, ill come back to this thread if it breaks down later..
But delete + insert both working greatly now :-)
Thanks to all who tried to help!
Related
first time using sql with C# and I seem to be running into an unbreakable wall. I'm trying to connect to my database which is on a different server on the same domain. This is all within a winform app. Also the windows account I am using for running this winform application has read and write permissions to the sql database already (Same domain account). I've set my connection string in my app.config as follows following the advice from connectionstrings.com
<connectionStrings>
<add name="my_db" connectionString="Server=10.xx.xx.xx;Database=my_db;Trusted_Connection=True;" providerName="System.Data.SqlClient" />
</connectionStrings>
I have the following method in Helper.cs where I am setting the Connection string from the config file.
public static string CnnVal(string name)
{
return ConfigurationManager.ConnectionStrings[name].ConnectionString;
}
Lastly, I have the following method in its own class, DbConnect.cs, and this method is called when I click a button on a form.
public void TestConnection()
{
try
{
using (var connection = new SqlConnection(Helper.CnnVal("my_db")))
{
var query = "Select 1";
System.Diagnostics.Debug.WriteLine($"Executing {query}");
var command = new SqlCommand(query, connection);
System.Diagnostics.Debug.WriteLine($"successful connection");
command.ExecuteScalar();
System.Diagnostics.Debug.WriteLine($"Successful query");
}
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine($"failure {ex.Message}");
}
}
I set breakpoints on "var command" and "command.ExecuteScalar();" lines and when looking at my Watch tab in visual studio, I can see that my connection is not opened and this leads to an InvalidOperationException from SqlCommand. I'm not sure why this is happening. I used sql server migration assistant this morning to migrate the server from mysql over to sql and my info all worked then (windows auth, ip, database name). What could the outlier be here? Do I have to put the port number in my connection string somewhere? I'm using the default 1433 port. Any help would be appreciated. Thanks
How to create database apps?
I have a textbox, button and label. The user enters a value = Luke and the program does the Select Address From Customers where Name='Luke'. It displays Address in the label.
I know this is a pretty stupid question, but I've looked everywhere, and all I can find is how to display all columns instead of just one thing.
Anymore advice on databases with c# would be very help as well. I am using Sql server Express 2012 and Visual Studio
The Code:
private void button1_Click(object sender, EventArgs e)
{
SelectData(textBox1.Text);
}
private void SelectData(string selectConnection)
{
string connectionStr =
#"Data Source=.\SQLEXPRESS;"+
#"AttachDbFilename=C:\SQL Server 2000 Sample Databases\NORTHWND.MDF;"+
#"Integrated Security=True;Connect Timeout=30;User Instance=True";
SqlConnection connection = new SqlConnection(connectionStr);
SqlCommand command = connection.CreateCommand();
command.CommandText = "SELECT Address FROM Customers"+
" WHERE CustomerName = '" + textBox1.Text + "'";
An advice for C# and Databases would be, to not put a string command together in the application.
There are many roads to success but some may lead to an unsecure Database query.
Personally I don't use, for example, the Entity Framework(Microsoft recommendation) etc. but I guess they might be helpfull for what you do so you should take a look at this.
Try to seperate the SQL Logic from the C# part so that IF your application grows and you can effort a Database administrator he doesn't have to know c# ;)
You are on the perfect track, now continuation to your code to display the address you can write like this:
label_address.text=command.executescalar();//if you have one row of address
else you can write
datareader dr =cmd.executereader()
while(dr.read())
{
label_address+=dr(0).tostring();+","//addressline1
label_address+=dr(1).tostring();//addressline2
}
hope its helpful
I have a Winforms application and database to save data from user.
When I insert data everything works fine but when I clean the solution and load the GUI of the database to see the old data.. I don't see the datam the datagridview is empty.
using (SqlConnection con = new SqlConnection(dataBase.Connection.ConnectionString))
{
using (SqlCommand wow = new SqlCommand("insert into GamesTbl(Type,Date,Time) Values(#type,#date,#time)", con))
{
wow.Parameters.AddWithValue("#type", "vsPC");
wow.Parameters.AddWithValue("#date", DateTime.Now.Date);
wow.Parameters.AddWithValue("#time", DateTime.Now.TimeOfDay);
try
{
con.Open();
wow.ExecuteNonQuery();
con.Close();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
}
What is wrong?
EDIT: binding data on DBGui_load
private void DBGui_Load(object sender, EventArgs e)
{
dataGridView1.DataSource = playersTblBindingSource;
playersTblBindingSource.DataSource = DB.GamesTbls;
}
EDIT: my connection string:
"Data Source=.\\SQLEXPRESS;AttachDbFilename=|DataDirectory|\\Database1.mdf;Integrated
Security=True;User Instance=True"
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 (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. Database1 - or while you're at it - give it a more sensible name...)
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=YourDatabase;Integrated Security=True
and everything else is exactly the same as before...
Seems liks you are missing DataBind.
private void DBGui_Load(object sender, EventArgs e)
{
dataGridView1.DataSource = playersTblBindingSource;
dataGridView1.DataBind(); // you are missing this
playersTblBindingSource.DataSource = DB.GamesTbls;
}
As an alternative solution, what you can do to fix the problem is to set the property of your database file in your solution as follows
Copy To Output Directory: do not copy
In my C# application, I do the following:
using (SqlConnection connection = new SqlConnection(connectionstr))
{
connection.Open();
SqlCommand com1 = new SqlCommand("insert into Anfangstierbestand(bestand, jahr, loginid) VALUES (" + bestand + ", " + jahr + ", " + loginid + ");", connection);
SqlCommand com2 = new SqlCommand("select * from Anfangstierbestand;", connection);
com1.Connection = connection;
int ferksum = 0;
com1.ExecuteNonQuery();
connection.Close();
connection.Open();
SqlDataReader read = com2.ExecuteReader();
while (read.Read())
{
ferksum += Convert.ToInt32(read[2]);
}
// MessageBox.Show("Fehler beim Erstellen des Tierbestandes", "Fehler"); }
MessageBox.Show(ferksum.ToString());
}
It's a simple insert to a database. I added com2 to check, if the insert works.
Unfortunately, the the value of com2 tells me, that it works, but when I go to the Server Explorer and press Execute SQL, there are no new values.
I don´t know the reason. The code above is just an example, since a few days, no insert works anymore(before, the same code works).
Does anybody know what the reason can be?
EDIT:
C#:
string connectionstr = "Data Source=.\\SQLEXPRESS;" + "AttachDbFilename=|DataDirectory|\\Datenbank\\FarmersCalc.mdf;" + "Integrated Security=True;" + "User Instance=true;";
EDIT2:
Server Explorer:
Data Source=.\SQLEXPRESS;AttachDbFilename="C:\Users\user\Desktop\Farmer´s Calc\Programmierung\WPF\Finanz_WPF\Finanz_WPF\Datenbank\FarmersCalc.mdf";Integrated Security=True;User Instance=True
EDIT3:
Here are the columns:
id int,
jahr int,
anzahl int,
loginid int
EDIT4:
Is it possible that it´s a problem that I opened my project with expression blend? Normally, I work with VS 2010...
EDIT5:
Even because I can not answer my question(<100 reputations) I write it here:
Shame on me. Some of you were right, it was the wrong database-file. But I´m still wondering, why this happened, because I did not change anything since a few days and before this, it worked!
Thanks to all for helping!
You're using user instances, why? Isn't it possible that the instance you're connecting to in Server Explorer is not the same as the instance where your app is inserting data? What happens when you select data from within the app, does it reflect your insert(s)? It seems to me based on your connection strings that these are two completely different MDF files - they have the same name but they are in different locations.
Is the issue implicit transactions? Do you need to issue a commit of the SQL Insert? If com2 tells you that it's there then it may only see it since it's in the context of the current SQL transaction.
You should share your connection string for both Server Explorer and your SqlConnection (connectionstr). Ensure that you setup your Server Explorer connection with User Instance=true;.
As a diagnostic,
connection.Open();
int n = com1.ExecuteNonQuery();
// log or show 'n' , the nr of rows affected
Edit, after seeing the connectionstrings:
local db files in |DataDirectory|\ are very prone to be overwritten by the next run or build command.
Make sure you set them to 'copy never' or 'copy if newer' in the VS Solution explorer.
Perhaps somewhere in the callstack above this code, someone has added a TransactionScope.
This would cause the connections to enroll automatically in the transaction, and the connections could see the data inserted via that not-yet-committed transaction. When the scope is exitted without calling scope.Complete, the transaction gets rolled back and no data is saved.
I have a problem,
private void button_Submit_Click(object sender, EventArgs e)
{
try
{
string connectionString = #"Data Source=Database_TouchPOS.sdf;Persist Security Info=False;";
using (SqlCeConnection connection = new SqlCeConnection(connectionString))
{
using (SqlCeCommand command = connection.CreateCommand())
{
connection.Open();
command.CommandText = "INSERT INTO Product (Title,Price,Category_Id) VALUES (#title, #price,#category_Id)";
command.Parameters.AddWithValue("#title", textBox_Title.Text);
command.Parameters.AddWithValue("#price", textBox_Price.Text);
command.Parameters.AddWithValue("#category_Id", comboBox_Category.SelectedIndex);
command.ExecuteNonQuery();
MessageBox.Show("Product Added Successfully...");
}
connection.Close();
}
}
catch (SqlException ex)
{
MessageBox.Show(ex.Message);
}
}
Everything seem to be fine, but still can't add data into database.
I did try with complete database path, example c:\project\database.sdf
I did a lot of search before asking. I saw similar problems but not even a single one works for me.
Data are added when compiling but not committed to database. I can see the data after second attempt of debugging.
Please kindly try to explain in detail.
Thanks
You are probably facing this, http://erikej.blogspot.com/2010/05/faq-why-does-my-changes-not-get-saved.html suggest you use a full path to your database file in your connection string.
Did you try to use transactions explicitly?
IDbTransaction transaction = connection.BeginTransaction();
//add to database
transaction.Commit(); // before close connection
This is a very old thread, so I don't know if it will help anyone if I put my answer.
I had this problem, too.
When I executed an update or insert code in C#, apparently, everything was ok, but when I looked up the database, there was no change.
The thing was that while debugging I had the database opened in a Management Studio. And somehow this obstructed the database changes even when there was no error message.
Closing the Management Studio and opening it after executing the code, the changes where perfectly stored in the data base.
Regards.
complete example for those seeking like me... #"Data Source=C:\Users\MYPC\Documents\Visual Studio 2010\Projects\MyProjectFolder\MyProject-1\bin\Debug\MyDatabase.sdf;Persist Security Info=False;";
thank for this example. This saved my day.