I am trying to write an application that will create a local database if it's not found in the application's folder. I run this query after deleting the .mdf
IF EXISTS (SELECT * FROM sys.databases WHERE name = N'Test_db')
BEGIN
DROP DATABASE Test_db
END
CREATE DATABASE Test_db
ON PRIMARY (NAME=Test_db, FILENAME='...\Test_db.mdf')
My command.ExecuteNonQuery() throws an exception, even though it drops the database and creates a new one. The error comes from the DROP DATABASE part of the command.
Additional information: Unable to open the physical file
"...\Test_db.mdf". Operating system error 2: "2 (The system cannot
find the file specified.)".
File activation failure. The physical file name
"...\Test_db_log.ldf" may be incorrect.
I found this question, but it has no solution to the problem.
The solution to the problem was to sp_detach_db because it removes the database from the server without deleting files from the file system
EXEC sp_detach_db 'Test_db'
If you are worried about the file being deleted, try File.Exists
if (File.Exists(pathname))
{
// Execute your SQL
}
else
{
// Error processing
}
Related
I have a simple data entry Windows Form with a datagridview display that links to a local database. When I run the program and try to add data on another computer, I get this message:
Unhandled exception has occurred in your application. If you click Continue, the application will ignore this error and attempt to continue. If you click Quit, the application will close immediately.
An attempt to attach an auto-named database for file C:\Users\roberto.yepez\Documents\Visual Studio\2010\Projects\Financial Aid Calculator\Financial Aid Calculator\StudentInfo1.mdf failed. A database with the same name exists, or specified file cannot be opened, or it is located on UNC share."
The file path is to the path on the computer where I coded the program.
Here is my code:
SqlConnection conn = new SqlConnection(#"Data Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename='C:\Users\roberto.yepez\Documents\Visual Studio 2010\Projects\Financial Aid Calculator\Financial Aid Calculator\StudentInfo1.mdf';Integrated Security=True".ToString());
I am a self-taught coder, please help! :)
I believe you're running into a problem because your local sql server to which your code is trying to attach the StudentInfo1.mdf (whose path is in the connection string) already contains a database called StudentInfo1 - it decided to try and create a database of this name based on the name of the mdf file. I'm guessing that you can pick your own name by specifying Initial Catalog in your connection string but this would mean there are two databases with possibly the same set of tables and a potential for confusion
Per the comment I posted I would instead advocate that you use SQL Server Management Studio to permanently attach your db (you make have already done this) and then adjust your connection string so that it refers to the permanently attached db. This reduces the chances that your next question will be "my code says it's updating my db but I cannot see any changes!?"
Please move this connection string
"Data Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename='C:\Users\roberto.yepez\Documents\Visual Studio 2010\Projects\Financial Aid Calculator\Financial Aid Calculator\StudentInfo1.mdf';Integrated Security=True"
to app.config file. When you deploy to production, change the paths in that app.config, according to the production machine settings.
You can even apply transformations on the app.config to deploy in various machines/scenarios.
Can we access a database file with non-.MDF extension using C#?
We are creating a setup project. We don't want the user to know the database details which is installed in the installation folder. So, I have tried renaming the database data file and log file with a random name without any extension.
When I have tried accessing the file from c# we are getting an error like:
An attempt to attach an auto-named database to file D:\SQLExpress\DB\abc123tmp failed. A database of the same name exists, or specified file cannot be opened, or it is located at UNC share.
Can anyone help me solve the issue?
Start SSMS, connect to (localDb)\MSSQLLOCALDB and look at the Databases attached ... I guess the File you want to attach is already attached under a different name. Detach that instance first and then your Connection should work. It's not possible to attach the same File using different Database names. The File Extension does not matter.
My development environment is C#, SQL Server 2014 LocalDB, SQL Server 2012 Express, Windows 10, Visual Studio 2015.
When users of my application need to move their localDB (.mdf) file to another place, another computer (LocalDB server), detaching from computer A and attaching to computer B and then, we can run BACKUP database command successfully.
However, in case users mistakenly detached or users changed their mind to use continuously in computer A, my application has to be able to re-attach the detached LocalDB database file (.mdf) to the same computer (same LocalDB server).
When I run BACKUP DATABASE command after my application re-attached the database file to same computer successfully, error message shows as,
Unable to open physical file, The process cannot access the dbfile because the dbfile is in use by another process
BACKUP DATABASE terminated abnormally
So, I entered Microsoft Server Management Studio and can see 2 dbfile with specific name as first is greendb.mdf (only name), second is c:\users\kay\appdata\greendb.mdf (with full path).
I think the c:\users\kay\appdata\greendb.mdf (with full path) is created when the database is detached. And when I click it through security-login-kay-user mapping, unlike other databases show their permissions inside, the detached database with full path doesn't show their permissions and show error message like,
Unable to cast 'System.DBNull' object to 'System.String' (Microsoft.SqlServer.Smo)
It seems Microsoft LocalDB Server still recognizes the detached database with full path and is confused with newly attached database (only name without full path).
Any excellent ideas will be highly appreciated !
Thank you so much !
In detaching localDB,
we have to run ALTER DATABASE ROLLBACK IMMEDIATE command first to terminate all the incomplete transactions.
Just to explain easily, Before we close a Restaurant, we have to announce to the customers in the Restaurant, 'This Restaurant will be closed very soon, please complete your eating and get outside before closing of Restaurant'
If you're needed to re-attach the localDB to same computer(same localDB Server),
Some activities like these have to be avoided to prevent the ghost(bug?).
1) Trial to open the localDB in code programmatically
2) It seems counting with the name of detached localDB also reminds the existence of localDB to the localDB Server.(SELECT COUNT dbname command in master database)
Strange thing which has to be fixed as a bug is,
if we detach a localDB from master DB, I think it has to be not able to open the detached localDB in code programmatically. However, code like SqlConnection.Open(); runs and pass by without any exception(error) and immediately the fullpath ghost is created.
It seems the name of detached localDB is deleted on master DB but the Server connects the detached localDB through the physical path in the provided connectionstring.
And to decide some localDB is needed to attached or to check it's detached or not, I've developed my own solution(simple code) to do this.
Hope my experience helps someone else.
Well, I worked a lot using attach and detach operation and finally I figured out that the best practice for us as a developers is working with scripts.
So, if you want to (detach) your db to re (attach) again either with a new name or the same name. I suggest you to generate scripts for your database and script it again.
if you run the script directly you will get an error because you have to delete the old data (the old / new have the same name) and script by default is using the db name which is written in the first line, sure you can remove this line and use the new database you want to use.
for scripting database including data, make sure to set preference from the wizard (Advanced settings => schema only / data only / schema and data.) choose schema and data
By default the choice is schema only.
choose a destination for your sql file, after running the script and deleting the old data. your backing up process should go with no problems.
I'm developing Windows Desktop appication(C# WPF) with Microsoft localdb(.mdf) and I want that users of my software can carry their localdb (.mdf) file when they move to other places(computers). The localdb (.mdf) file is created on the first computer.
To test my application, I copied my localdb file from computer A to computer B and attached with below code successfully.
string attach_greendbnameQuery = string.Format(#"EXEC sp_attach_db #dbname = N'greendb_{0}', #filename1 = N'{1}\greendb_{0}.mdf'", textBoxGreenLogin.Text, Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData).ToString());
SqlCommand attach_greendbnamecomm = new SqlCommand(attach_greendbnameQuery, check_datadbinmasterConn);
attach_greendbnamecomm.ExecuteNonQuery();
And I could read and write data into the moved localdb file.
However, when I run backup command on this database, exception occurs like,
'Unable to open physical file, Operating system error 32, process cannot open the file because the file is in use by another process'
If I enter Server Management Studio- Security-KayLee-PC\KayLee- User Mapping,
the users of all other localdb are 'dbo' but only the user of manually moved database is KayLee-PC\KayLee and only 'public' is checked and all other database roles are not checked including db_owner. (I always start(login) Windows(O/S) with KayLee-PC\Kaylee account)
I tried to make all roles checked to database roles even to server roles but failed.
Even, I tried to drop the user KayLee-PC\KayLee through below code but the exception message show as,
'User 'KayLee-PC\KayLee' does not exist in current database'
If I click the database in Server Management Studio, the current database status is not changed to clicked database and subtree nodes(like Table, Security and so on) are not displayed with message 'cannot access to the database' eventhough if I click other databases, the current database status is changed to clicked database.
Also, I tried to change the owner of the localdb(database) through below code but it seems the execution failed with result '-1' with 'sa' and when trying with 'KayLee-PC\KayLee' which I always login to Windows O/S, error message is like 'KayLee-PC\KayLee is already an owner(exist) of this database'
SqlConnection dbownerchange_Conn = new SqlConnection();
dbownerchange_Conn.ConnectionString = dbownerchange_ConnectionString;
dbownerchange_Conn.Open();
SqlCommand dbownerchange_comm = new SqlCommand();
dbownerchange_comm.Connection = dbownerchange_Conn;
dbownerchange_comm.CommandText = "EXEC sp_changedbowner 'sa'";
dbownerchange_comm.ExecuteNonQuery();
dbownerchange_Conn.Close();
Simply, If we need to move(copy) Microsoft localdb file to another place(computer), how can I do this successfully?
Must we detach before move the localdb file? If so, I'm worried there're always people who don't follow guideline by running detach function.
I've tried several scenarios to understand how SQL server is working. The conclusion is we need to detach first and re-attach to same or different machine(computer). Then, I could have been successful to move to another computer.
However, a single process of backup and restoring localdb to another machine(computer) doesn't work. Furthermore, if we detach localdb(database file .mdf) first, SQL server no more recognizes the localdb database and we cannot run backup command for the localdb.
Conclusively and simply, if we want to move localdb (microsoft database .mdf file) to other local server(computer, machine), we're needed to just detach the localdb from master database in computer A and copy the files and re-attach to another master database of computer B.
Hope this helps someone else..
I have recently installed SQL Server 2012 on my machine. When I try to create a database in SSMS by right clicking on Databases and selecting New Database, it prompts me for various items in order to create the database. After entering the name of the database and clicking OK, I get an exception:
"Create failed for Database 'aaaa'. (Microsoft.SqlServer.Smo)
ADDITIONAL INFORMATION:
An exception occurred while executing a Transact-SQL statement or batch. (Microsoft.SqlServer.ConnectionInfo)
A file activation error occurred. The physical file name 'aaaa.mdf' may be incorrect. Diagnose and correct additional errors, and retry the operation. CREATE DATABASE failed. Some file names listed could not be created. Check related errors. (Microsoft SQL Server, Error: 5105)"
It seems the problem is only with the wizard because when I execute Create Database query it successfully creates the database.
I figured it out that when Database is created from wizard, a file path is to be provided in Path column. If it is blank by default then it means there is no path specified in Database settings.
In Object Explorer, right-click a server and click Properties.
In the left panel, click the Database settings page.
In Database default locations, view the current default locations for new data files and new log files. To change a default location, enter a new default path name in the Data or Log field, or click the browse button to find and select a path name.
We can change the file path while creating Database.
The actual database file permissions were set to read_only,please try unchecked the read_only checkbox on the file permissions.
I also had this problem and I can in this link where I've created any string values (DefaultData and DefaultLog) in regedit in this path: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSSQLServer\MSSQLServer.
In this "string values" you must put the path where your SQL data and log must stay.
As you realized there is a Path column in the grid view for each file (.mdf and .ldf).
This is set to <default>.
At the first usage of the server this default path may not be set, so the full-path of the new database cannot be computed.
Solution:
Based on this article you can set it via the interface of SSMS. You just need to:
right click on your server name (e.g.: (LocalDB)\v11.0),
select Properties,
select Database Settings,
Fill up all 3 entry of Database default locations with valid directory paths. (Defining top 2 paths: Data and Log is enough to create databases.)
This will create the right registry entries for you, without touching regedit.exe.
What path to choose?
Either the location that is proposed along installation:
C:\Program Files\Microsoft SQL Server\MSSQL11.MSSQLSERVER\MSSQL\Data
Or the location of system databases:
C:\Users\[UserName]\AppData\Local\Microsoft\Microsoft SQL Server Local DB\Instances\v11.0
Or better choices for non-system databases are:
C:\Users\[UserName]\My Documents\Databases
C:\Users\[UserName]\My Documents\SQL Server Management Studio\Databases
Note 1: [UserName] can be "Public" to make it common data (please correct me if this causes multiple copy of the database, but I think it won't).
Note 2: I don't know whether latter is deleted along uninstallation of SSMS.