I'm working a WinForms based C# tool which has an attached MDF file based database. I'm trying to use the SqlCommand.ExecuteNonQuery() method to save a record to this attached MDF database, but the record is not saved. No error or exception occurs; only problem is that the record is not actually saved.
I have a Console.WriteLine at the top which shows the query I'm trying to run. Its correct syntax-wise, and if I copy-paste it from the output windows and run it separately, it works.
I have correctly defined the connection string as the following, and it works fine for fetching records:
public static String connectionString = #"Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|\TestBuildDB.mdf;Integrated Security=True;Connect Timeout=30;User Instance=True";
Here the function I'm using to save records:
public static void PerformDBWriteTransaction(string inputSQLStatement)
{
Console.WriteLine(inputSQLStatement);
DataTable returnDataTable = new DataTable();
SqlConnection sqlConnection = new SqlConnection();
sqlConnection.ConnectionString = connectionString;
SqlCommand cmd = new SqlCommand();
cmd.Connection = sqlConnection;
cmd.CommandType = CommandType.Text;
cmd.CommandText = inputSQLStatement;
cmd.Connection.Open();
try
{
cmd.ExecuteNonQuery();
}
catch (SqlException ex)
{
errorMessages.Clear();
errorMessages.Append("The following errors were found in the SQL statement:\n\n");
for (int i = 0; i < ex.Errors.Count; i++)
{
errorMessages.Append("Index #" + i + "\n" +
"Message: " + ex.Errors[i].Message + "\n" +
"LineNumber: " + ex.Errors[i].LineNumber + "\n" +
"Source: " + ex.Errors[i].Source + "\n" +
"Procedure: " + ex.Errors[i].Procedure + "\n");
}
MessageBox.Show(errorMessages.ToString());
}
finally
{
cmd.Connection.Close();
}
}
Can someone tell me what might be the problem ? Do I need to perform a 'commit' somehow ?
EDIT:
I have found the problem, and have written up a solution below .. Thanks to all who helped me out though :)
I found the problem ! It was very simple, and it was stupid really :) .. The code above is all correct .. Yes, people pointed out optimizations, etc, but still the code above was correct.
The problem was that when I imported the TestDB.MDF file into my Visual 2010 project, a copy of that was made inside the project's folder. When you run/debug the program, another copy of the this file is made and is put in the \bin\Debug\ folder. In the connection string I was using, I had mentioned: AttachDbFilename=|DataDirectory|\TestBuildDB.mdf .. This meant that all reads/writes were done to the copy in the bin\Debug folder. However, the TestDB.MDF file I was looking into to verify if records were inserted or not, was in the project's folder ! So basically, there were two MDF files, and I was writing the records into one file, but was trying to find them in the other :)
When you add an MDF file into your VS2010 Project, VS2010 by default makes a connection to that MDF file, from where you can browse the stuff in that MDF file .. The MDF file used for this purpose was the one placed in the project's folder, NOT the one in bin\Debug\ folder. And like I said earlier, my code used the one in the bin\Debug folder :)
So what I've done now is that I've removed the Test.MDF file reference from my project, which removes the copy present in the project's folder. However, I DO have a copy of TestDB.MDF file in the bin\Debug\ folder, which I connect to from within my application. And if I want to browse the MDf file outside my project, I use SQL Management Studio. The only problem here is that an MDF file can only be used by one program at a given time. So if I have to use it with my application, I have to take it offline from SQL Management studio, and vica versa !
I hope this explanation helps someone out there :)
The solution to this problem is very simple just give the full path of the original MDF file in the connection String like this:
connectionString="Data Source=(LocalDB)\v11.0;AttachDbFilename=**C:\VISUAL STUDIO 2012\PROJECTS\ENGLISHTOHINDIDICTIONARY\ENGLISHTOHINDIDICTIONARY\DICTIONARY.MDF**;Initial Catalog=Dictionary;Integrated Security=false"
providerName="System.Data.SqlClient"
That's it, your problem is solved.
I had the same challenge, I simply changed the database property "Copy to Output Directory" from "Copy always" to "Do not copy" then moved my database.mdf (drag & drop from my IDE) into the bin\debug folder.
Tip:
The bin directory is normally hidden, use the "Show All Files" to display it
Provide a catch clause for all Exceptions. If there something wrong other than SqlException, you will never see what is it and your db will neved be updated. Imagine there is a FormatException...
Also check the return of ExecuteNonQuery : it's the number of rows affected by the query.
First, you should always wrap up your IDisposable objects in a using to ensure they're closed and disposed of properly (and that connection pooling can do its thing). Second, when modifying data wrap up your sql in a transaction to maintain data integrity.
Try the following code and see if any exceptions are raised. I wouldn't normally recommend catching Exception as it's too general, I'd let that bubble up to the calling mechanism and handle it there - but for this instance it will show you any and all issues. I think your particular issue is at the .Open stage of the connection, so try stepping through.
public static void PerformDBWriteTransaction(string inputSQLStatement)
{
DataTable returnDataTable = new DataTable();
try
{
using (SqlConnection sqlConnection = new SqlConnection(connectionString))
{
sqlConnection.Open();
using (SqlTransaction sqlTrans = sqlConnection.BeginTransaction())
{
try
{
using (SqlCommand cmd = new SqlCommand(inputSQLStatement, sqlConnection))
{
cmd.CommandType = CommandType.Text;
cmd.Transaction = sqlTrans;
cmd.ExecuteNonQuery();
}
}
catch (SqlException sqlEx)
{
sqlTrans.Rollback();
throw sqlEx;
}
sqlTrans.Commit();
}
}
}
catch (Exception ex)
{
errorMessages.Clear();
errorMessages.Append("The following errors were found in the SQL statement:\n\n");
for (int i = 0; i < ex.Errors.Count; i++)
{
errorMessages.Append("Index #" + i + "\n" +
"Message: " + ex.Errors[i].Message + "\n" +
"LineNumber: " + ex.Errors[i].LineNumber + "\n" +
"Source: " + ex.Errors[i].Source + "\n" +
"Procedure: " + ex.Errors[i].Procedure + "\n");
}
MessageBox.Show(errorMessages.ToString());
}
}
Hi I am working on library database when I add student record executionNonQuery
shows error like invalid column name page opens but saving data from not happening.
Here I have given the code statement
public partial class add_student_info : Form
{
SqlConnection con = new SqlConnection(#"Data Source=DESKTOP-SPT6GLG\SQLEXPRESS;Initial Catalog=library_managment;Integrated Security=True;Pooling=False");
public add_student_info()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
con.Open();
SqlCommand cmd = con.CreateCommand();
cmd.CommandType = CommandType.Text;
cmd.CommandText = "insert into student_info values('" + textBox1.Text + "','" + textBox2.Text + "','" + textBox3.Text + "','" + textBox4.Text + "'," + textBox5.Text + "," + textBox6.Text + "," + textBox7.Text + ")";
cmd.ExecuteNonQuery();
con.Close();
MessageBox.Show("Student recorc addedd sussfully");
}
}
}
Related
I keep getting this exception over and over. I've tried separating my query into two separate queries, that didn't work. I've checked to make sure the db connection is closed elsewhere before it's opened during this method, it's definitely closed before the function is called and opened before any queries.
Below iss the code for the function. I've set breakpoints and the query itself is fine. The code is the exact same that I used previously for updating a PIN function, with just the query string changed, so I don't know why it's causing issues:
Code:
public void transferMoney(string senderIban, decimal senderBalance, string receiverIban, decimal transferAmount,string messageOptional)
{
//myBankAccount.AccountPin = updatedPin;
DataTable dtUser = new DataTable();
sqlconnConnection.Open();
string strQuery2 = #"UPDATE Accounts SET Balance = Balance + " + Convert.ToDecimal(transferAmount) + " WHERE GUID = '" + receiverIban + "';"
+ "UPDATE Accounts SET Balance = Balance - " + Convert.ToDecimal(transferAmount) + " WHERE GUID = '" + senderIban + "';";
// example of a Paramaterised SQL statement.
SQLiteCommand sqlcomCommand2 = new SQLiteCommand(strQuery2, sqlconnConnection);
SQLiteDataAdapter sqldatadptAdapter = new SQLiteDataAdapter(sqlcomCommand2); // local SQL data Adaptor
try
{
// sqldatadptAdapter.Fill(dtUser);
sqlcomCommand2.ExecuteNonQuery();
}
catch (Exception ex)
{
// Exception will the "thrown" when there was a problem
throw new Exception($"UPDATE WAS unsuccessful:\n{ex.Message}");
}
finally
{
sqlconnConnection.Close();
}
Maybe you have a DB browser opened? Or you have accessed the DB some other way. This error only occurs when DB is modified or used elsewhere. If you can't find it, I'd suggest restarting PC just in case there something hidden :)
P.S. Posting this as answer as I cannot comment under the question for technical reasons :)
I am trying to add an SQL database to my project. I have been successful when using an explicit path, but if I use a relative path |DataDirectory|\Data\Database.mdf the console appears to be be writing data to the database, but looking in the server explorer at the database afterwards shows not data. There are a couple of other questions that get close to answering, but scouring Stack, I have been unable to locate an answer that works or comes close to addressing.
EDIT
Per the suggestions below I have attempted the fixes, however, just to clarify. The program appears to connect and write to the database as expected, but when I look at the database structure, no table is created, no data is inserted, even though the program runs with no errors
<connectionStrings>
<add name="rData"providerName="System.Data.SqlClient"connectionString="Data Source=(LocalDB)\MSSQLLocalDB; Initial Catalog=TestRecipeDatabase;AttachDbFilename=|DataDirectory|\Data\TestRecipeDatabase.mdf;Integrated Security=True" />
</connectionStrings>
public void connectToDB(string action)
{
var connectionString = ConfigurationManager.ConnectionStrings["rData"].ConnectionString;
Console.WriteLine(connectionString);
SqlConnection conn = new SqlConnection(connectionString);
if (action == "firstRun")
{
conn.Open();
// Creates the Database
try
{
using (SqlCommand createDBTable = new SqlCommand("" +
"CREATE TABLE RecipeStorage" +
"(" +
"rname char(50) NOT NULL, " +
"ringredients text, " +
"rdirections text" +
");", conn))
createDBTable.ExecuteNonQuery();
Console.WriteLine("Created Database");
}
catch (SqlException e)
{
Console.WriteLine(e.Message);
System.Diagnostics.Trace.WriteLine(logTime + " " + e.Message);
}
// Sets the primary key to rname
try
{
using (SqlCommand setPrimaryKey = new SqlCommand("ALTER TABLE RecipeStorage ADD PRIMARY KEY (rname);", conn))
setPrimaryKey.ExecuteNonQuery();
Console.WriteLine("Set Primary Key to Recipe Name");
}
catch (SqlException e)
{
Console.WriteLine(e.Message);
System.Diagnostics.Trace.WriteLine(logTime + " " +e.Message);
}
// Adds an initial recipe
try
{
using (SqlCommand firstLine = new SqlCommand("INSERT INTO RecipeStorage (rname, ringredients, rdirections) VALUES ('espresso', 'Hot water, coffee'," +
"'put coffee through espresso machine with hot water into cup, enjoy');", conn))
firstLine.ExecuteNonQuery();
}
catch (SqlException e)
{
Console.WriteLine(e.Message);
System.Diagnostics.Trace.WriteLine(logTime + " " + e.Message);
}
conn.Close();
}
}
As mentioned above, this totally works when using an explicit path for the data connection C:\User\User\Projects\CSharp\RecipeHandler\Data\TestRecipeDatabase.mdf
But does not work using the relative path. Ideally I would want to be able for this to run on any computer which obviously would not have the database in same place
How to restore SQL Server backup using C#?
try
{
string test = "D:\\backupdb\\05012017_130700.Bak";
sqlcmd = new SqlCommand("Restore database EmpolyeeTable from disk='D:\\backupdb\\05012017_130700.Bak'", con);
sqlcmd.ExecuteNonQuery();
Response.Write("restore database successfully");
}
catch (Exception ex)
{
Response.Write("Error During backup database!");
}
Quite weird requerement you have right there. I´ve never heard of someone restoring a database backup from a webpage, and as #Alex K. told, it would be quite rare that the user that uses your web application have the required previleges.
Anyway, supposing that everything told above is OK, the code to restore a backup would be this:
Use this:
using System.Data;
using System.Data.SqlClient;
Code:
private void TakeBackup()
{
var conn = new SqlConnection("Data Source=" + Server + ";Initial Catalog=" + Database + ";User Id=" + Username + ";Password=" + Password + ";");
try
{
conn.Open();
SqlCommand command = conn.CreateCommand();
command.CommandText = "RESTORE DATABASE AdventureWorks FROM DISK = 'C:\AdventureWorks.BAK' WITH REPLACE GO";
command.ExecuteNonQuery();
}
catch (Exception)
{
throw;
}
finally
{
conn.Dispose();
conn.Close();
}
}
This is going to work specifically for the problem you posted. Be sure to set all the parameters of your database server on the connection string, it seems from the comments on your question that you are having communication issues. You have to solve that problems before you do anything. Some tips for that:
Be sure you set all the parameters on connection string the right way
Try to connect using another tool like ODBC so you can test all parameters
Check out SQL Network settings to see if TCP/IP is enabled
I'm trying to backup and restore a SQL Server 2008 database, but I'm getting an error saying
Incorrect Syntax near database name
Here is the code for back up and restore which is written c# asp.net.
Can I get a help regarding this?
private void btnbackup_Click(object sender, EventArgs e)
{
try
{
if (combodatabase.Text.CompareTo("") == 0)
{
MessageBox.Show("Please select a Database");
return;
}
con = new SqlConnection(connectionstring);
con.Open();
sql = "BACKUP DATABASE" + combodatabase.Text + " TO DISK='" + txtbackupfileloc.Text + "\\" + combodatabase.Text + "-" + DateTime.Now.Ticks.ToString() + ".bak'";
cmd = new SqlCommand(sql, con);
cmd.ExecuteNonQuery();
con.Close();
con.Dispose();
MessageBox.Show("Database Backup Successfully Completed.");
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
Restore code:
private void btnrestore_Click(object sender, EventArgs e)
{
try
{
if (combodatabase.Text.CompareTo("") == 0)
{
MessageBox.Show("Please Select a Database");
return;
}
con = new SqlConnection(connectionstring);
con.Open();
sql = "ALTER DATABASE" + combodatabase.Text + "SET SINGLE_USR WITH ROLLBACK IMMEDIATELY ";
sql += "RESTORE DATABASE" + combodatabase.Text + "From DISK='" + txtrestorefileloc.Text + "'With REPLACE;";
cmd = new SqlCommand(sql, con);
cmd.ExecuteNonQuery();
con.Close();
con.Dispose();
MessageBox.Show("Database Successfully Restored");
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
You don't have any whitespace between BACKUP DATABASE and the database name, that will be the first problem, the same goes for the second (restore) code.
You could attach yourself in debug mode to see what is the SQL command after you have built all your sql query string. It seems a lot of whitespaces are missing there. Once you have it, you could post it in SQL Server Management Studio and see tips for errors there, would be easier probably.
Last, but not least, if you can't debug your application easily or pop up the SQL query (which apparently isn't the case since you display the ex.Message), you could maybe run a SQL Server Profiler session to check the queries executed against SQL Server.
You're missing a few spaces in your SQL statements!
Check this out:
sql = "BACKUP DATABASE" + combodatabase.Text + " TO DISK='" + ....
If you select a database called TEST, this becomes:
BACKUP DATABASETEST TO DISK=.....
Or this:
sql = "ALTER DATABASE" + combodatabase.Text + "SET SINGLE_USR WITH ROLLBACK IMMEDIATELY ";
sql += "RESTORE DATABASE" + combodatabase.Text + "From DISK='" + txtrestorefileloc.Text + "'With REPLACE;";
becomes
ALTER DATABASETESTSET SINGLE_USR WITH ROLLBACK IMMEDIATELY
RESTORE DATABASETESTFrom DISK=......
There needs to be at least one space between the BACKUP DATABASE and the name of the database! Some throughout your code - you need to be more careful when stringing together keywords and placeholder - you need spaces between them at times!
Also, if your database name is "special" in any way (e.g. it contains a space itself, starts with a number etc.), you might need to put the database name into square brackets:
BACKUP DATABASE [Test DB] .....
BACKUP DATABASE [7dwarfs] .....
This is my code
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Data.OleDb;
namespace SDD_Single_Project___Michael_Merjane
{
public partial class NewUser : Form
{
private OleDbConnection connection = new OleDbConnection(); //setting up a private connection
public NewUser()
{
InitializeComponent();
connection.ConnectionString = #"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=E:\schoolwork\Year 11\SDD\3 SINGLE TASK\SDD Single Project - Michael Merjane\SDD Single Project - Michael Merjane\bin\Persondata.accdb; //PROBLEM IS HERE
Persist Security Info=False;"; // there is no security for finding the location, this is not very safe but for the circumstances it works. In the line above, it is finding the location of the database. This could change due to computer and cause the whole program to not run
}
private void btnBack_Click(object sender, EventArgs e) //all of these mean when button is clicked
{
this.Hide(); //hides this page
MainScreen frm = new MainScreen(); //finds the next screen (the main screen)
frm.Show(); //shows it
}
private void btnSubmit_Click(object sender, EventArgs e)
{
try {
connection.Open(); // opens the connection
OleDbCommand command = new OleDbCommand(); //names command as a new oledbcommand for further use
command.Connection = connection;
command.CommandText = "insert into Persondata ( FirstName,LastName,Address,Suburb,Email,Mobile,Gender,Age) values ( '" + txtFirst.Text + "' , '" + txtLast.Text + "' , '" + txtAddress.Text + "' , '" + txtSuburb.Text + "' , '" + txtEmail.Text + "' , '" + txtMobile.Text + "' , '" + dropGender.Text + "' , '" + dropAge.Text + "') ";
// finds where its going to, finds the columns it is going to fill, finds the text boxes that is going to fill them
command.ExecuteNonQuery(); //execute the save
MessageBox.Show("Data Saved"); //pretty much shows a box saying everything worked
connection.Close(); // closes the connection
}
catch (Exception ex) //if something has gone wrong a catch will occur
{
MessageBox.Show("Error " + ex); //show the error
} //if there is a error message box will appear informing it
}
}
}
This is code for an assignment I must give in, the problem is I won't be able to hand it because then the absolute path won't find the file. I need a way to use a relative file path that can change due to a change in location. At the moment, the path (as long is it is) goes to the bin folder within the programs files. So if there was a way to change it so it somehow automatically looks in its own program files to the bin or anywhere else in its own program files that would be great.
Put whatever file you want into the folder your current ptoject is. Then
Directory.GetCurrentDirectory()
will give the current folder you are working on. It will give you the release folder of your project. Store it as a string and use it where ever needed.
try :
var currDir = System.Environment.CurrentDirectory;
then concatenate the path from there...
Sure.
That is pretty basic thing - I'd suggest putting database file in DB folder inside bin - or left inside bin as it is.
Then you need to determine location of your binary folder - there are several ways, while two below are most common:
Environment.CurrentDirectory - will work until you are not changing it during run-time (elsewhere)
Assembly.GetEntryAssembly().Location - which is full path to the executable that started current process
I'd suggest then looking onto System.IO.Path class - first to strip only path from Location and then to combine it back but this time with database file-name string.
While this is you assignment I'm going to leave you here to study this class by yourself - this is pretty interesting one :P
http://msdn.microsoft.com/en-us/library/system.io.path(v=vs.110).aspx