Data addition and updation in SQL tables - c#

Iam fairly new to SQLClient and all, and iam having a problem with my SQL tables..when ever i run my code, the data, rather than getting updated, attaches itself to the already existing records in the tables..here's my code
SqlConnection conneciones = new SqlConnection(connectionString);
SqlCommand cmd;
conneciones.Open();
//put values into SQL DATABASE Table 1
for (int ok = 0; ok < CleanedURLlist.Length; ok++)
{
cmd = new SqlCommand("insert into URL_Entries values('" + CleanedURLlist[ok] + "' , '" + DateTime.Now + "' , '" + leak + "' )", conneciones);
cmd.ExecuteNonQuery();
}
conneciones.Dispose();

Take a look at these functions, i hope you understand better on update , insert and delete functions..
Code snippets for reading, inserting, updating and deleting a records using asp.net and c# and sql server database
static void Read()
{
try
{
string connectionString =
"server=.;" +
"initial catalog=employee;" +
"user id=sa;" +
"password=sa123";
using (SqlConnection conn =new SqlConnection(connectionString))
{
conn.Open();
using (SqlCommand cmd = new SqlCommand("SELECT * FROM EmployeeDetails", conn))
{
SqlDataReader reader = cmd.ExecuteReader();
if (reader.HasRows)
{
while (reader.Read())
{
Console.WriteLine("Id = ", reader["Id"]);
Console.WriteLine("Name = ", reader["Name"]);
Console.WriteLine("Address = ", reader["Address"]);
}
}
reader.Close();
}
}
}
catch (SqlException ex)
{
//Log exception
//Display Error message
}
}
static void Insert()
{
try
{
string connectionString =
"server=.;" +
"initial catalog=employee;" +
"user id=sa;" +
"password=sa123";
using (SqlConnection conn =new SqlConnection(connectionString))
{
conn.Open();
using (SqlCommand cmd = new SqlCommand("INSERT INTO EmployeeDetails VALUES(" +
"#Id, #Name, #Address)", conn))
{
cmd.Parameters.AddWithValue("#Id", 1);
cmd.Parameters.AddWithValue("#Name", "Amal Hashim");
cmd.Parameters.AddWithValue("#Address", "Bangalore");
int rows = cmd.ExecuteNonQuery();
//rows number of record got inserted
}
}
}
catch (SqlException ex)
{
//Log exception
//Display Error message
}
}
static void Update()
{
try
{
string connectionString =
"server=.;" +
"initial catalog=employee;" +
"user id=sa;" +
"password=sa123";
using (SqlConnection conn = ew SqlConnection(connectionString))
{
conn.Open();
using (SqlCommand cmd =
new SqlCommand("UPDATE EmployeeDetails SET Name=#NewName, Address=#NewAddress WHERE Id=#Id", conn))
{
cmd.Parameters.AddWithValue("#Id", 1);
cmd.Parameters.AddWithValue("#Name", "Munna Hussain");
cmd.Parameters.AddWithValue("#Address", "Kerala");
int rows = cmd.ExecuteNonQuery();
//rows number of record got updated
}
}
}
catch (SqlException ex)
{
//Log exception
//Display Error message
}
}
static void Delete()
{
try
{
string connectionString =
"server=.;" +
"initial catalog=employee;" +
"user id=sa;" +
"password=sa123";
using (SqlConnection conn = ew SqlConnection(connectionString))
{
conn.Open();
using (SqlCommand cmd =
new SqlCommand("DELETE FROM EmployeeDetails " +
"WHERE Id=#Id", conn))
{
cmd.Parameters.AddWithValue("#Id", 1);
int rows = cmd.ExecuteNonQuery();
//rows number of record got deleted
}
}
}
catch (SqlException ex)
{
//Log exception
//Display Error message
}
}

Your code should be inserting new records, but I'm not clear on whether it is not doing that, or you mean to update existing records.
Aside from that, understanding that you are new to working with SQL Server, there are a couple of things you should be aware of.
You should use using to automatically dispose resources. This will also close your connection for you so you don't have open connections hanging around.
You should use parameters to protect against sql injection attacks. Another benefit of using parameters in your case is that you don't need to create new commands for every statement.
For example:
using (var connection = new SqlConnection(connectionString)
using (var command = connection.CreateCommand())
{
command.CommandText = "insert into URL_Entries values(#url, #now, #leak)";
command.Parameters.AddWithValue("#now", DateTime.Now);
command.Parameters.AddWithValue("#lead", leak);
// update to correspond to your definition of the table column
var urlParameter = command.Parameters.Add(new SqlParameter("#url", SqlDbType.VarChar, 100));
connection.Open();
for (int ok = 0; ok < CleanedURLlist.Length; ok++)
{
urlParameter.Value = CleanedURLlist[ok];
command.ExecuteNonQuery();
}
}
Per your comment, if you want to do an update, you'll need to include the parameter(s) that identify the rows to update. If this is a single row, use the primary key value:
command.CommandText = "update URL_Entries set UrlColumn = #url, ModifiedDate = #now where ID = #id";

You're using an INSERT function, that is 'ADD NEW RECORDS'
If you want an update, you'll want an UPDATE function
UPDATE tablename
SET column1 = 'x', column2 = 'y'
WHERE id = z

Related

How do you read a database table and display it in a textbox

I am creating a basic app for adding and displaying customer information using windows forms in visual studio. i have set it up so i am able to display the contents of the database in a gridview and also add to the database which you can see the code for below. what i am stuck on at the moment is updating the customers information. I want to search the database by customerID which will be entered by the user in a textbox, and display that specific customers details into their relevent textboxes which i can then edit and save.
using (SQLiteCommand cmd = conn.CreateCommand())
{
// adds customers details to the database
cmd.CommandText = #"INSERT INTO customer (title, " + "firstname, " + "lastname, " + "dob, " + "nicode, " + "email, " + "password, " + "allowance) VALUES (#setTitle, #setFirstname, #setLastname, #setDOB, #setNICode, #setEmail, #setPassword, #setAllowance)";
cmd.Parameters.AddWithValue("setTitle", cb_title.Text);
cmd.Parameters.AddWithValue("setFirstname", txtFirst_Name.Text);
cmd.Parameters.AddWithValue("setLastname", txtSurname.Text);
cmd.Parameters.AddWithValue("setDOB", dtp_DOB.Text);
cmd.Parameters.AddWithValue("setNICode", txtNI_Code.Text);
cmd.Parameters.AddWithValue("setEmail", txtEmail.Text);
cmd.Parameters.AddWithValue("setPassword", txtPassword.Text);
cmd.Parameters.AddWithValue("setAllowance", txtAllowance.Text);
int recordsChanged = cmd.ExecuteNonQuery();
MessageBox.Show("Customer Added");
conn.Close();
Customers customers = new Customers();
customers.Show();
this.Hide();
}
That's what I have for adding a new customer which works fine
using (SQLiteCommand cmd = conn.CreateCommand())
{
// adds customers details to the database
cmd.CommandText = #"UPDATE customer SET (title, " + "firstname, " + "lastname, " + "dob, " + "nicode, " + "email, " + "password, " + "allowance) VALUES (#setTitle, #setFirstname, #setLastname, #setDOB, #setNICode, #setEmail, #setPassword, #setAllowance) WHERE custid = #recd";
cmd.Parameters.AddWithValue("title", cb_title_update.Text);
cmd.Parameters.AddWithValue("firstname", txtFirst_Name_update.Text);
cmd.Parameters.AddWithValue("lastname", txtSurname_update.Text);
cmd.Parameters.AddWithValue("dob", dtp_DOB_update.Text);
cmd.Parameters.AddWithValue("nicode", txtNI_Code_update.Text);
cmd.Parameters.AddWithValue("email", txtEmail_update.Text);
cmd.Parameters.AddWithValue("password", txtPassword_update.Text);
cmd.Parameters.AddWithValue("allowance", txtAllowance_update.Text);
cmd.Parameters.AddWithValue("recd", Convert.ToInt32(txtSearch.Text));
int recordsChanged = cmd.ExecuteNonQuery();
MessageBox.Show("Customer Updated");
conn.Close();
Customers customers = new Customers();
customers.Show();
this.Hide();
}
And that's the code I have so far for updating the database, but I can not figure out how to retrieve the customer data and display it into the textboxes, any help or guidance would be appreciated
Your Update statement is not correct. Try the following.
cmd.CommandText =#"UPDATE customer
SET title = #setTitle,
firstname = #setFirstname,
lastname = #setLastname
dob = #setDOB,
nicode = #setNICode,
email = #setEmail,
password = #setPassword,
allowance = #setAllowance
WHERE custid = #recd";
It is a bit different from an Insert. Each field is set to a new value. You don't need all that concatenation. This is a literal string.
Of course, in a real application you would NEVER store passwords as plain text.
To get the value of a certain column from a certain row, you can try to call method SqlCommand.ExecuteReader.
Here assume you want to get the the customer password.
string connectionstring = #"connectin string";
private void btnSearch_Click(object sender, EventArgs e)
{
using (SqlConnection conn = new SqlConnection(connectionstring))
{
SqlCommand cmd = new SqlCommand();
cmd.Connection = conn;
cmd.CommandText = "Select * from customer where customerID = #cusID";
cmd.Parameters.AddWithValue("#cusID", textBoxID.Text);
conn.Open();
try
{
SqlDataReader reader = cmd.ExecuteReader(CommandBehavior.SingleRow);
if (reader.HasRows)
{
if (reader.Read())
{
// get password column value
textBoxPWD.Text = reader["password"].ToString();
}
}
else
{
Console.WriteLine("no such record");
}
}
catch (Exception ex)
{
Console.WriteLine("\nError:\n{0}", ex.Message);
}
}
}
As to update the record,
private void btnUpdate_Click(object sender, EventArgs e)
{
using (SqlConnection conn = new SqlConnection(connectionstring))
{
SqlCommand cmd = new SqlCommand();
cmd.Connection = conn;
cmd.CommandText = "UPDATE customer SET password = #cusPWD WHERE customerID = #cusID";
cmd.Parameters.AddWithValue("#cusID", textBoxID.Text);
cmd.Parameters.AddWithValue("#cusPWD", textBoxPWD.Text);
conn.Open();
cmd.ExecuteNonQuery();
}
}

Insert text file data into SQL Server database table of specific column

I have attached my code in which I tried to read a .txt file with many records.
The same text file data I need to insert into the SQL Server database table in specific columns. Here is the code I wrote by taking reference from some where.
protected void BtnUpload_Click(object sender, EventArgs e)
{
FileUpload(x);
}
private void FileUpload(List<string> x)
{
SqlConnection con = new SqlConnection(conStr);
SqlCommand cmd = new SqlCommand();
string fileName = Path.Combine(#"C:\Users\user\Desktop\SBS", FileUpload1.FileName);
if(FileUpload1.HasFile)
{
try
{
con.Open();
List<string> x;
for (int i = 0; i <= x.Count - 9; i += 9)
{
SqlCommand myCommand = new SqlCommand("INSERT INTO SBSFile (SBSBranchCode, BranchName, FinYear, BrChallanNo, TransDate, MajorHead, ReceiptPayment, Amount, PlanNonPlan) " +
string.Format("Values('{0}', '{1}', '{2}', '{3}', '{4}', '{5}', '{6}', '{7}', '{8}', '{9}')", x[i], x[i + 1], x[i + 2], x[i + 3], x[i + 4], x[i + 5], x[i + 6], x[i + 7], x[i + 8], x[i + 9]), con);
myCommand.ExecuteNonQuery();
}
catch (Exception ex)
{
}
}
}
example of my file :
1 |abc| |bcd| |101|
here | denoted separator of column and yes every line should be inserted in the table where in specific column is available
Can anyone help me to insert file data into the SQL Server table?
Please help me to solve the issue
I wouldn't use a program at all... I'd use the "Import" feature in SQL server to import a pipe-delimited file. For example How to import pipe delimited text file data to SQLServer table
Here is an example of working code that will read data from a Text file, where that data is delimited by |. Multiple insert statements will be executed within a single transaction, in case of failure using an All Or Nothing principle.
[TestMethod]
public void TestInsertDataFromFile()
{
String fileName = #"D:\SampleData.txt";
String connectionString = #"Server=MyTestDBServer; Database=TestingDatabase; Trusted_Connection=True;";
using (SqlConnection conn = new SqlConnection(connectionString))
{
conn.Open();
using (SqlTransaction transaction = conn.BeginTransaction())
{
String insertCommand = #"INSERT INTO SBSFile (SBSBranchCode, BranchName, FinYear, BrChallanNo, TransDate, MajorHead, ReceiptPayment, Amount, PlanNonPlan) ";
insertCommand += #"VALUES (#sbsBranchCode, #branchName, #finYear, #brChallanNo, #transDate, #majorHead, #receiptPayment, #amount, #planNonPlan)";
String[] fileContent = File.ReadAllLines(fileName);
using (SqlCommand command = conn.CreateCommand())
{
command.CommandText = insertCommand;
command.CommandType = CommandType.Text;
command.Transaction = transaction;
foreach (String dataLine in fileContent)
{
String[] columns = dataLine.Split('|');
command.Parameters.Clear();
command.Parameters.Add("sbsBranchCode", SqlDbType.VarChar).Value = columns[0];
command.Parameters.Add("branchName", SqlDbType.VarChar).Value = columns[1];
command.Parameters.Add("finYear", SqlDbType.VarChar).Value = columns[2];
command.Parameters.Add("brChallanNo", SqlDbType.VarChar).Value = columns[3];
command.Parameters.Add("transDate", SqlDbType.VarChar).Value = columns[4];
command.Parameters.Add("majorHead", SqlDbType.VarChar).Value = columns[5];
command.Parameters.Add("receiptPayment", SqlDbType.VarChar).Value = columns[6];
command.Parameters.Add("amount", SqlDbType.VarChar).Value = columns[7];
command.Parameters.Add("planNonPlan", SqlDbType.VarChar).Value = columns[8];
command.ExecuteNonQuery();
}
}
transaction.Commit();
}
}
}
Important things to note
NEVER have an empty catch {} handler as you will never know if there are problems.
When talking to the database using externally specified values, ALWAYS use parameters to prevent SQL Injection attacks.
Make use of Transactions if you are doing multiple inserts from a single source. It will make recovery possible without having to unpick the data manually.
Where possible (when classes implement IDisposable) use a using(...) block to ensure resources are released and not blocking/locking.
use this code:
SqlConnection con = new SqlConnection(conStr);
SqlCommand cmd = new SqlCommand();
string fileName = Path.Combine(#"C:\Users\user\Desktop\SBS", FileUpload1.FileName);
if (FileUpload1.HasFile)
{
var lines = File.ReadAllLines(fileName);
try
{
con.Open();
foreach (var line in lines)
{
var columns = line.Split('|');
SqlCommand myCommand = new SqlCommand("INSERT INTO SBSFile (SBSBranchCode, BranchName, FinYear, BrChallanNo, TransDate, MajorHead, ReceiptPayment, Amount, PlanNonPlan) " +
$"Values('{columns[0]}', '{columns[1]}','{columns[2]}','{columns[3]}','{columns[4]}','{columns[5]}','{columns[6]}','{columns[7]}','{columns[8]}''{columns[9]}')");
myCommand.ExecuteNonQuery();
}
con.Close();
}
catch (Exception ex)
{
}
}

AVG QUERY in c#

Good morning, I'm developing a code that can get me out of my database in sql, the AVG of a certain column.
The problem is that I'm not getting it, I think the problem is the query but I do not know how to solve it.
I need help, thank you.
Here is the code:
String connectionString =
"Data Source=localhost;" +
"Initial Catalog=DB_SACC;" +
"User id=sa;" +
"Password=1234;";
SqlConnection connection = new SqlConnection(connectionString);
SqlCommand cmd = new SqlCommand();
string textt = " USE [DB_SACC] SELECT AVG (Total_Divida) FROM t_pagamentos";
cmd.CommandText = textt;
connection.Open();
cmd.Connection = connection;
cmd.CommandType = CommandType.Text;
cmd.ExecuteNonQuery();
if (textt == null)
{
MessageBox.Show("nothing");
}
else
{
TextBox3.Text = textt;
}
use ExecuteScalar if you request a single value from your database - ExecuteNonQuery returns just the number of affected rows which is used in update / insert statements
USE [DB_SACC] is not required in your query since you define the "Initial Catalog=DB_SACC;"
add using to avoid open connections
Code:
string connectionString = "Data Source=localhost;Initial Catalog=DB_SACC;User id=sa;Password=1234;";
using (SqlConnection connection = new SqlConnection(connectionString))
{
string textt = "SELECT AVG (Total_Divida) FROM t_pagamentos";
using (SqlCommand cmd = new SqlCommand(textt, connection))
{
connection.Open();
var result = cmd.ExecuteScalar(); //write the result into a variable
if (result == null)
{
MessageBox.Show("nothing");
}
else
{
TextBox3.Text = result.ToString();
}
}
}
Use cmd.ExecuteScalar() method instead:
decimal average = (decimal) cmd.ExecuteScalar();
cmd.ExecuteNonQuery(); only returns the number of rows effected where as what you want is to read the result set of SELECT statement.
I would also get rid of USE [DB_SACC] from your SELECT statement since you are defining the database name in your connection string.
EDIT
Your code should look like this:
string textt = "SELECT AVG (Total_Divida) FROM t_pagamentos";
cmd.CommandText = textt;
connection.Open();
cmd.Connection = connection;
cmd.CommandType = CommandType.Text;
decimal average = (decimal) cmd.ExecuteScalar();
if (textt == null)
{
MessageBox.Show("nothing");
}
else
{
TextBox3.Text = average.ToString();
}
EDIT 2:
try
{
string textt = "SELECT AVG (Total_Divida) FROM t_pagamentos";
cmd.CommandText = textt;
connection.Open();
cmd.Connection = connection;
cmd.CommandType = CommandType.Text;
decimal average = (decimal)cmd.ExecuteScalar();
TextBox3.Text = average.ToString();
}
catch(Exception ex)
{
// log your exception here...
MessageBox.Show("nothing");
}
EDIT 3:
In the light of your recent comments try this
string connectionString = "Data Source=localhost; Initial Catalog=DB_SACC; User id=sa Password=1234;";
decimal? average;
try
{
using (SqlConnection connection = new SqlConnection(connectionString))
{
using (SqlCommand cmd = new SqlCommand())
{
string textt = "SELECT AVG (Total_Divida) AS 'AVG_DIVIDA' FROM t_pagamentos";
cmd.CommandText = textt;
connection.Open();
cmd.Connection = connection;
cmd.CommandType = CommandType.Text;
using (DataReader reader = cmd.ExecuteReader())
{
while (reader.Read())
{
average = decimal.parse(reader["AVG_DIVIDA"].ToString());
break;
}
}
}
}
TextBox3.Text = average.HasValue ? average.ToString() : "Unknown error occurred";
}
catch (Exception ex)
{
MessageBox.Show("Unable to retrieve the average, reason: " + ex.Message);
}
Note: Using DataReader to get just single value from database is not preferred. I am proposing this because of the error you mentioned in the comments.
If you are getting any SQL Exception then try to run this statement on SQL Server as stand alone test.
USE DB_SACC
GO
SELECT AVG (Total_Divida) AS 'AVG_DIVIDA' FROM t_pagamentos
GO
If you still encounter any error while executing T-SQL Statement then please post that as another question.

Updating multiple tables using SqlDataAdapter

I've been trawling through pages and pages on the internet for days now trying different approaches and I'm still not sure how I should be doing this.
On my third InsertCommand, I'd like to reference a column on the other 2 tables.
// Populate a DataSet from multiple Tables... Works fine
sqlDA = new SqlDataAdapter();
sqlDA.SelectCommand = new SqlCommand("SELECT * FROM hardware", sqlConn);
sqlDA.Fill(ds, "Hardware");
sqlDA.SelectCommand.CommandText = "SELECT * FROM software";
sqlDA.Fill(ds, "Software");
sqlDA.SelectCommand.CommandText = "SELECT * FROM join_hardware_software";
sqlDA.Fill(ds, "HS Join");
// After DataSet has been changed, perform an Insert on relevant tables...
updatedDs = ds.GetChanges();
SqlCommand DAInsertCommand = new SqlCommand();
DAInsertCommand.CommandText = "INSERT INTO hardware (host, model, serial) VALUES (#host, #model, #serial)";
DAInsertCommand.Parameters.AddWithValue("#host", null).SourceColumn = "host";
DAInsertCommand.Parameters.AddWithValue("#model", null).SourceColumn = "model";
DAInsertCommand.Parameters.AddWithValue("#serial", null).SourceColumn = "serial";
sqlDA.InsertCommand = DAInsertCommand;
sqlDA.Update(updatedDs, "Hardware"); // Works Fine
DAInsertCommand.Parameters.Clear(); // Clear parameters set above
DAInsertCommand.CommandText = "INSERT INTO software (description) VALUES (#software)";
DAInsertCommand.Parameters.AddWithValue("#software", null).SourceColumn = "description";
sqlDA.InsertCommand = DAInsertCommand;
sqlDA.Update(updatedDs, "Software"); // Works Fine
DAInsertCommand.Parameters.Clear(); // Clear parameters set above
DAInsertCommand.CommandText = "INSERT INTO join_hardware_software (hardware_id, software_id) VALUES (#hardware_id, #software_id)";
// *****
DAInsertCommand.Parameters.AddWithValue("#hardware_id", null).SourceColumn = "?"; // I want to set this to be set to my 'hardware' table to the 'id' column.
DAInsertCommand.Parameters.AddWithValue("#software_id", null).SourceColumn = "?"; // I want to set this to be set to my 'software' table to the 'id' column.
// *****
sqlDA.InsertCommand = DAInsertCommand;
sqlDA.Update(updatedDs, "HS Join");
Could somebody please tell me where I am going wrong and how I could potentially overcome this? Many thanks! :)
With regards to your comments this seems to be one of those occasions where if you and I were sat next to each other we'd get this sorted but it's a bit tricky.
This is code I've used when working with SqlConnection and SqlCommand. There might be stuff here that would help you.
public static void RunSqlCommandText(string connectionString, string commandText) {
SqlConnection conn = new SqlConnection(connectionString);
SqlCommand comm = conn.CreateCommand();
try {
comm.CommandType = CommandType.Text;
comm.CommandText = commandText;
comm.Connection = conn;
conn.Open();
comm.ExecuteNonQuery();
} catch (Exception ex) {
System.Diagnostics.EventLog el = new System.Diagnostics.EventLog();
el.Source = "data access class";
el.WriteEntry(ex.Message + ex.StackTrace + " SQL '" + commandText + "'");
} finally {
conn.Close();
comm.Dispose();
}
}
public static int RunSqlAndReturnId(string connectionString, string commandText) {
SqlConnection conn = new SqlConnection(connectionString);
SqlCommand comm = conn.CreateCommand();
int id = -1;
try {
comm.CommandType = CommandType.Text;
comm.CommandText = commandText;
comm.Connection = conn;
conn.Open();
var returnvalue = comm.ExecuteScalar();
if (returnvalue != null) {
id = (int)returnvalue;
}
} catch (Exception ex) {
System.Diagnostics.EventLog el = new System.Diagnostics.EventLog();
el.Source = "data access class";
el.WriteEntry(ex.Message + ex.StackTrace + " SQL '" + commandText + "'");
} finally {
conn.Close();
comm.Dispose();
}
return id;
}

How to restore SQL Server database through C# code

I try to restore the database like this:
SQL = #"RESTORE DATABASE MyDataBase TO DISK='d:\MyDATA.BAK'";
Cmd = new SqlCommand(SQL, Conn);
Cmd.ExecuteNonQuery();
Cmd.Dispose();
but I always get error:
Msg 3102, Level 16, State 1, Line 7
RESTORE cannot process database 'MyDataBase ' because it is in use
by this session. It is recommended that the master database be used
when performing this operation.
Msg 3013, Level 16, State 1, Line 7
RESTORE DATABASE is terminating abnormally.
I prefer to use SMO to restore a backup:
Microsoft.SqlServer.Management.Smo.Server smoServer =
new Server(new ServerConnection(server));
Database db = smoServer.Databases['MyDataBase'];
string dbPath = Path.Combine(db.PrimaryFilePath, 'MyDataBase.mdf');
string logPath = Path.Combine(db.PrimaryFilePath, 'MyDataBase_Log.ldf');
Restore restore = new Restore();
BackupDeviceItem deviceItem =
new BackupDeviceItem('d:\MyDATA.BAK', DeviceType.File);
restore.Devices.Add(deviceItem);
restore.Database = backupDatabaseTo;
restore.FileNumber = restoreFileNumber;
restore.Action = RestoreActionType.Database;
restore.ReplaceDatabase = true;
restore.SqlRestore(smoServer);
db = smoServer.Databases['MyDataBase'];
db.SetOnline();
smoServer.Refresh();
db.Refresh();
You'll need references to Microsoft.SqlServer.Smo, Microsoft.SqlServer.SmoExtended, and Microsoft.SqlServer.Management.Sdk.Sfc
Your DB connection is most likely to the database you're trying to restore. So there is a DB shared lock which prevents the restore of your db
Try this
SQL = #"USE master BACKUP DATABASE MyDataBase TO DISK='d:\MyDATA.BAK'";
Or change the connection details to use master DB
public void Restore(string Filepath)
{
try
{
if(con.State == ConnectionState.Closed)
{
con.Open();
}
SqlCommand cmd1 = new SqlCommand("ALTER DATABASE [" + Database + "] SET SINGLE_USER WITH ROLLBACK IMMEDIATE ", con);
cmd1.ExecuteNonQuery();
SqlCommand cmd2 = new SqlCommand("USE MASTER RESTORE DATABASE [" + Database + "] FROM DISK='" + Filepath + "' WITH REPLACE", con);
cmd2.ExecuteNonQuery();
SqlCommand cmd3 = new SqlCommand("ALTER DATABASE [" + Database + "] SET MULTI_USER", con);
cmd3.ExecuteNonQuery();
con.Close();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
con.Close();
}
You must connect to the database server via a different database.
So your connection string should take you to say "Master" or another database on the server, then you can complete the task at hand.
Your connection string should have a master database as default catalog to connect to.
I've ended with this solution. Name of my database was Stats This will work without installed MSSQL management studio
public void BackUpDB(string fname)
{
using (SqlConnection cn = new SqlConnection(_cstr))
{
cn.Open();
string cmd = "BACKUP DATABASE [Stats] TO DISK='" + fname + "'";
using (var command = new SqlCommand(cmd, cn))
{
command.ExecuteNonQuery();
}
}
}
public void RestoreDB(string fname)
{
using (SqlConnection cn = new SqlConnection(_cstr))
{
cn.Open();
#region step 1 SET SINGLE_USER WITH ROLLBACK
string sql = "IF DB_ID('Stats') IS NOT NULL ALTER DATABASE [Stats] SET SINGLE_USER WITH ROLLBACK IMMEDIATE";
using (var command = new SqlCommand(sql, cn))
{
command.ExecuteNonQuery();
}
#endregion
#region step 2 InstanceDefaultDataPath
sql = "SELECT ServerProperty(N'InstanceDefaultDataPath') AS default_file";
string default_file = "NONE";
using (var command = new SqlCommand(sql, cn))
{
using (var reader = command.ExecuteReader())
{
if (reader.Read())
{
default_file = reader.GetString(reader.GetOrdinal("default_file"));
}
}
}
sql = "SELECT ServerProperty(N'InstanceDefaultLogPath') AS default_log";
string default_log = "NONE";
using (var command = new SqlCommand(sql, cn))
{
using (var reader = command.ExecuteReader())
{
if (reader.Read())
{
default_log = reader.GetString(reader.GetOrdinal("default_log"));
}
}
}
#endregion
#region step 3 Restore
sql = "USE MASTER RESTORE DATABASE [Stats] FROM DISK='" + fname + "' WITH FILE = 1, MOVE N'Stats' TO '" + default_file + "Stats.mdf', MOVE N'Stats_Log' TO '"+ default_log+ "Stats_Log.ldf', NOUNLOAD, REPLACE, STATS = 1;";
using (var command = new SqlCommand(sql, cn))
{
command.ExecuteNonQuery();
}
#endregion
#region step 4 SET MULTI_USER
sql = "ALTER DATABASE [Stats] SET MULTI_USER";
using (var command = new SqlCommand(sql, cn))
{
command.ExecuteNonQuery();
}
#endregion
}
}

Categories

Resources