I got an issue and learned something at the same time....
I created a DBML from an existing server database.
From the DBML I wanted to create local database (an .mdf file). I created the database using DataContext.CreateDatabase("C:\xxxx.mdf") .
Then I decided to delete it (MANUALLY, which is a bad thing evidentally) because when I try to recreate the database with the same name (eventhough the files are deleted), I get the error Database already exist. Choose a Different Name using CreateDatabase()
I tried looking through the registry, no luck... I tried searching the whole hard drive for the file.. no luck.
After googling, I found that you delete a database that was created with CreateDatabase() with DeleteDatabase().... Then you can recreate the database again.
Well problem is, now I still can't recreate the old database because the system thinks the name already exists.
Is there a way to get rid of the reminents of the old databse file the "does not exist"
You need to open master database via server explorer in Visual Studio (Add New Connection + Select master database) then add a New query, type Drop Database xxxx and execute it. You can also use Sql Server Management Studio.
A solution (via here) is to use SSEUtil to detach the existing db:
try
{
// open a connection to the database for test
}
catch (SystemException ex) // Change exception type based on your underlying data provider
{
if (ex.Message.ToLower().Contains("already exists. choose a different database name"))
{
var match = Regex.Match(ex.Message, "database '(.*)' already exists.",
RegexOptions.IgnoreCase);
if (match.Success)
{
String dbFileName = match.Groups[1].Value;
Process p = new Process();
p.StartInfo.UseShellExecute = true;
p.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
p.StartInfo.FileName = String.Format("{0}/Tools/SSEUtil.exe",
Environment.CurrentDirectory);
p.StartInfo.WorkingDirectory = Environment.CurrentDirectory;
p.StartInfo.Arguments = String.Format("-d \"{0}\"", dbFileName);
p.Start();
}
}
}
Here's a quick fix for a localDB mess. Just connect to (localdb)\MSSQLLocalDB in SQL Mgmt. Studio/Visual Studio.
Then delete the offender, checking "Close existing connections"
I also actually had this same problem. Previously, I deleted
(cut) the database in mysqlserver2012 and copied it to my application folder. After I made my app I got this error, and solved it by removing the Initial Catalog part of my Connection String.
Your final connection string should look something like this:
Data Source=<your server name>;AttachDbFileName=database path\databaseName.mdf;Integrated Security=True" + ";User Instance=True" + ";Context Connection=False;
Related
I have a program where on a click event SQL will open and connect to a server instance and database however. I am wanting to make to program a bit more dynamic and allow user input but I am struggling to get this to work as wanted.
The old code is as follows and this works:
Process.Start("ssms.exe", "-S .\\SQLEXPRESS -d master -E ");
I tried the following but this just opens SQL but states will not use the details enterd to connect to a database.
Process.Start("ssms.exe", DataBaseNameInput.Text);
Edit
The error SQl shows is The following files where specified on the command line: These files could not be found and will not be loaded.
For this you would need to use SqlConnectionStringBuilder(), this allows you to build a string whitch can then be passed.
var Connection = new SqlConnectionStringBuilder();
Connection.DataSource = ServerNameTextBox.Text;
Connection.InitialCatalog = DatabaseTextbox.Text;
Connection.UserID = UserNameTextBox.Text;
Connection.Password = PasswordTextBox.Text;
var connString = Connection.ConnectionString;
This was done by the following information
Ssms Utility
I created a backup form with this code:
private void btnBackUp_Click(object sender, EventArgs e) //Backup will work only when we place |DataDirectory| in our appconfig file
{
try
{
progressBar1.Visible = true;
progressBar1.Value = 15;
bool bBackUpStatus = true;
Cursor.Current = Cursors.WaitCursor;
if (Directory.Exists(#"D:\Backup_MAConvent"))
{
if (File.Exists(#"D:\Backup_MAConvent\MAConvent_Backup.bak"))
{
if (MessageBox.Show(#"Do you want to replace it?", "Back", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
{
File.Delete(#"D:\Backup_MAConvent\MAConvent_Backup.bak");
}
else
bBackUpStatus = false;
}
}
else
Directory.CreateDirectory(#"D:\Backup_MAConvent");
if (bBackUpStatus)
{
con.Open();
progressBar1.Value = 25;
string path1 = System.IO.Path.GetFullPath(#"SchoolDatabase.mdf");
SqlCommand cmd2 = new SqlCommand("backup database [" + path1 + #"] to disk ='D:\Backup_MAConvent\MAConvent_Backup.bak' with init,stats=10", con);
cmd2.ExecuteNonQuery();
progressBar1.Value = 35;
con.Close();
timer1.Start();
MessageBox.Show("Backup of the Database saved Successfully", "Back", MessageBoxButtons.OK, MessageBoxIcon.Information);
timer1.Stop();
progressBar1.Value = 10;
progressBar1.Visible = false;
}
}
catch
{
MessageBox.Show(#"Backup Error, Please close the software & restart and then try again to backup", "Backup", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
}
This code was not working with the connection string of \bin database. So, I changed my connection string in app.config to |DataDirectory|
<connectionStrings>
<add name="SchoolManagement.Properties.Settings.SchoolDatabaseConnectionString"
connectionString="Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|\SchoolDatabase.mdf;Integrated Security=True;User Instance=True"
providerName="System.Data.SqlClient" />
</connectionStrings>
After that, when I was inserting new values to the database, the values were temporary showing in my search form having search query. But after stopping debugging the data was not in the database.
And then I changed Copy To output directory to copy if newer . so, now the data is showing on form's search gridview every time but it is not showing in the server explorer's database(show table data).
I know this problem is occurred due to the |Data directory| database and \bin database. Please suggest what to do? If I changed my connection string to the \bin database, all works well but backup code does not work. Please help if somebody knows the way to sort out this. Thank you
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. SchoolDatabase)
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=SchoolDatabase;Integrated Security=True
and everything else is exactly the same as before...
Also see Aaron Bertrand's excellent blog post Bad habits to kick: using AttachDbFileName for more background info.
I'm developing a Windows Forms App with VS2012. The data is stored in a SQL Server LocalDB. I'm also using EF6.
At some point I want to zip and send the .mdf file to a server for backup.
The problem is I'm getting the following error 'The process cannot access the file '[filepath]' because it is being used by another process'.
Now I understand that it's my app that is locking the file, but is there any way to unlock it? Or maybe kill the sqlserver client engine?
I'm even considering backing up the localDB File. Is this possible in a winform app?
I can't test it now, but I suggest to execute a standard T-SQL BACKUP command, then take the BAK file, zip it and store/send it.
string backupDB = #"FullPathToYourBackupFile.bak";
string databaseName = "YourDBName"; // This is not the MDF file, but the logical database name
using (var db = new DbContext())
{
var cmd = string.Format("BACKUP DATABASE {0} TO DISK='{1}' WITH FORMAT;",
databaseName, backupDB);
db.Database.ExecuteSqlCommand(cmd, null);
}
Thanks to you all I got this working.
I used Steve's answer but with some modifications.
string backupDB = String.Format(#"{0}\{1}", Constants.Paths.CompressedProjects, Constants.DataBase.FileNameBackup);
string databaseName = Constants.DataBase.LogicalName; // This is not the MDF file, but the logical database name
using (var db = new DBContext())
{
string[] parms = new string[2];
parms[0] = databaseName;
parms[1] = backupDB;
var cmd = "BACKUP DATABASE " + databaseName + " TO DISK='" + backupDB + "' WITH FORMAT;";
db.Database.ExecuteSqlCommand(TransactionalBehavior.DoNotEnsureTransaction, cmd, parms);
}
params in ExecuteSqlCommand cannot be null and I had to add a TransactionalBehavior.DoNotEnsureTransaction because I was getting this error
Cannot perform a backup or restore operation within a transaction
Uploading the LocalDB is now working.
Thank you so much for your help.
Hugo MaurĂcio
just found out a new solution
System.Data.SqlClient.SqlConnection.ClearAllPools()
I tested it and it works
Hugo
I am doing a SETUP project for a C# winforms, sqlite application.
Connection string seems to a bit of a problem. The user will put the Database he wants to work with at a location(which v will tell him). In this example it is "C:\\Program Files(x86)\\DefaultCompany\\RSetup"; The user can work his own copy of the DB.
So I am setting the data directory to this path in the Program.cs Main
This is the only way I can think of. If there is a better way thats grt!!.
App.config
<add name="ConnString" connectionString="|DataDirectory|\MySQlite.db;Compress=True;Version=3"
providerName="System.Data.Sqlite" />
Program.cs
Setting the datadirectory to the path of the executable. Currently hard coded the path of the executable
static void Main()
{
AppDomain.CurrentDomain.SetData("DataDirectory","C:\\Program Files(x86)\\DefaultCompany\\RSetup");
This doesn't seem to be working. It doesn't give any error except the data is not blank. Doesn't seem to be working in both set up and the regular project
Thank you
JC
You could ask the user where the database is located, store that path somewhere (such as User Settings) and then you can retrieve it at any time. This would give the user more flexibility of where to put it and multiple users on the same machine could have their own database if desired.
Here is some pseudocode...
string dbLocation = Properties.Settings.Default.DatabaseLocation;
if (string.IsNullOrWhiteSpace(dbLocation)
{
dbLocation = AskUserForLocation();
Properties.Settings.Default.DatabaseLocation = dbLocation;
Properties.Settings.Default.Save();
}
AppDomain.CurrentDomain.SetData("DataDirectory",dbLocation);
Using this approach you could also add a menu option to allow the user to change the location if desired.
It also gives you the ability to retrieve the value anywhere, including where you create a connection, you can append the path to the location between where you read the connection string and you create a new connection.
SQLiteConnection myConnection = new SQLiteConnection;();
myConnection.ConnectionString = Path.Combine(Properties.Settings.Default.DatabaseLocation, myConnectionString);
myConnection.Open();
I am inserting a SQL Database Backup and Recovery section into my program. I have been using MSDN Examples (tryed another and it wouldnt work).
MSDN Page - http://msdn.microsoft.com/en-us/library/ms162133.aspx
I have got the Backup file working, and have tested the file in Management Studio.
But I am having trouble with the Recovery of the file.
The code seems to be working, but the database in SQL Server is stuck in "Restoring..."
if (openFile.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
Server sqlServer = new Server();
Restore sqlRestore = new Restore();
sqlRestore.NoRecovery = true;
sqlRestore.Action = RestoreActionType.Database;
BackupDeviceItem deviceItem = new BackupDeviceItem(openFile.FileName, DeviceType.File);
sqlRestore.Devices.Add(deviceItem);
sqlRestore.Database = "firstRecoverTest";
sqlRestore.SqlRestore(sqlServer);
//Add the recovered database into the Entity Table
SqlCommand intoEntity = new SqlCommand("IF NOT EXISTS(SELECT entityName FROM Entitys WHERE entityName = 'firstRecoveryTest') INSERT INTO Entitys VALUES ('firstRecoveryTest');", sqlConnection);
sqlConnection.Open();
intoEntity.ExecuteNonQuery();
Database db = default(Database);
db = sqlServer.Databases["firstRecoverTest"];
db.RecoveryModel = (RecoveryModel)1;
db.AutoClose = true;
//db.Alter();
}
In the example there is a db.Alter(); function, but that throws an error that says "Alter failed for Database 'firstRecoverTest'".
Please let me know your thoughts
Thanks in advance
UPDATE
After inserting the "ReplaceDatabase = true;" there was no change in the end result.
Also stepping though the code line by line, shows that it is making it through.
The "db.Alter();" is just that placed at the end of the code (shown as comment). It is used in the creation of the backup and works without error.
InnerError shows this information when using db.Alter();
"ALTER DATABASE is not permitted while a database is in the Restoring state"
The interesting part is the SQL Log files. I am getting 3 Logs:
"Starting up database 'firstRecoverTest'."
"The database 'firstRecoverTest' is marked RESTORING and is in a state that does not allow recovery to be run."
"Database was restored: Database: firstRecoverTest, creation date(time): 2011/09/20(15:44:48), first LSN: 37:159:37, last LSN: 37:175:1, number of dump devices: 1, device information: (FILE=1, TYPE=DISK: {'C:\Users\Administrator\Desktop\installer_backup'}). Informational message. No user action required."
However, when I do a normal recover using SQL Management Studio there is 2 more log entrys saying
"Starting up database '[databaseName]'."
"Restore is complete on database '[databaseName]'. The database is now available"
I don't have enough reputation to post a small image of how it is in SQL Management Studio unfortunatly.
You should try either dropping the database or using sqlRestore.ReplaceDatabase = true;.
http://msdn.microsoft.com/en-us/library/microsoft.sqlserver.management.smo.restore.replacedatabase.aspx
If it looks like nothing is happening you can start the process in a seperate thread and wire up the events for notification of progress changes by using these.
sqlRestore.Complete += new ServerMessageEventHandler(completionEvent);
sqlRestore.PercentCompleteNotification = 10; // Call progress event every x percent change.
sqlRestore.PercentComplete += new PercentCompleteEventHandler(progressEvent);
If that doesn't work can you please post the Alter code that wasn't working. Also check SQL server logs and permissions.
UPDATED
Ok that update makes more sense. The reason is because you are setting sqlRestore.NoRecovery = true;. This has the effect that after the restore is done the DB is kept in a recovery state so you can restore an additional differential backup in addition to the full you just restored.
While it is in this state you will not be able to do anything more to the database. I would suggest that unless you require it you leave the default which is NoRecovery = false.
See http://msdn.microsoft.com/en-us/library/microsoft.sqlserver.management.smo.backuprestorebase.norecovery.aspx
Hope that helps.