Restore database in SQL LocalDB using VB.NET - vb.net

I have a project developed in VB.NET and SQL Server 2012 LocalDB (v11) and I am need backup/restore facility in my application. Backup part is complete but I am stuck at restore part. This is the query I want to be worked (and its working fine in SQL Editor)
ALTER DATABASE [<.MDF File Path>]
SET SINGLE_USER WITH ROLLBACK IMMEDIATE
RESTORE DATABASE [<.MDF File Path] FROM DISK='<.bak File Path'
and here is the code in VB.NET I am trying to execute
Sub Restorequery(ByVal que As String)
MainForm.Conn.Close()
con = New SqlConnection("Data Source=(LocalDB)\v11.0;Database=Master;integrated security=True;")
If Not con.State = ConnectionState.Open Then con.Open()
cmd = New SqlCommand(que, con)
cmd.ExecuteNonQuery()
End Sub
And here are the approaches I tried so far
Using the same query as above
Restorequery("ALTER DATABASE [<.MDF File Path>] SET SINGLE_USER WITH ROLLBACK IMMEDIATE")
Restorequery("restore database [<.MDF File Path>] from disk='<.bak File Path>'")
and this results in an error
Exclusive access could not be obtained because the database is in use. RESTORE DATABASE is terminating abnormally.
After finding reason for above issue (which is nonsense even after using master database while opening connection and closing all the previously opened connections using MainForm.Conn.Close() ), I tried second approach as per some links and references from Stackoverflow. And here are the queries I tried:
Restorequery("use [master] ")
Restorequery("alter database [<.MDF File Name>] set single_user with rollback immediate")
Restorequery("restore database[<.MDF File Name>] from disk='<.bak File Name>'")
Restorequery("alter database [<.MDF File Name>] set multi_user")
Restorequery("use [<.MDF File Name>]")
and here is the error I got while executing second query :
Additional information: User does not have permission to alter database <.MDF File Name with Path>, the database does not exist, or the database is not in a state that allows access checks. ALTER DATABASE statement failed.
Is there any other way to restore a SQL Server LocalDB using VB.NET ?

I have Used this code in one of my project.
Try
With OpenFileDialog1
.Filter = ("DB Backup File|*.bak;")
.FilterIndex = 4
End With
OpenFileDialog1.FileName = ""
If OpenFileDialog1.ShowDialog() = DialogResult.OK Then
Cursor = Cursors.WaitCursor
SqlConnection.ClearAllPools()
con = New SqlConnection(cs)
con.Open()
Dim cb As String = "USE Master ALTER DATABASE [" & System.Windows.Forms.Application.StartupPath & "\BRH.mdf] SET Single_User WITH Rollback Immediate Restore database [" & System.Windows.Forms.Application.StartupPath & "\BRH.mdf] FROM disk='" & OpenFileDialog1.FileName & "' WITH REPLACE ALTER DATABASE [" & System.Windows.Forms.Application.StartupPath & "\BRH.mdf] SET Multi_User "
cmd = New SqlCommand(cb)
cmd.Connection = con
cmd.ExecuteReader()
con.Close()
End If
Catch ex As Exception
MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
End Try

Related

SQL query to backup a database returns error when executed as a SqlCommand from code

The following SQL query was modified from this SO post and it runs properly in SSMS. My objective is to keep an updated database copy that serves as a backup and is readily available in the server to be accessed from code.
USE master;
ALTER DATABASE [conf.HelpDbBu] SET OFFLINE WITH ROLLBACK IMMEDIATE;
ALTER DATABASE [conf.HelpDbBu] SET ONLINE;
DROP DATABASE [conf.HelpDbBu]
USE [conf.HelpDb];
BACKUP DATABASE [conf.HelpDb]
TO DISK = 'C:\tfsCollateral\_projects\conf\dbBackups\conf_HelpDb.Bak'
WITH FORMAT,
MEDIANAME = 'SQLServerBackups',
NAME = 'Full Backup of conf.HelpDb';
USE master
RESTORE VERIFYONLY
FROM DISK = 'C:\tfsCollateral\_projects\conf\dbBackups\conf_HelpDb.Bak';
RESTORE FILELISTONLY
FROM DISK = 'C:\tfsCollateral\_projects\conf\dbBackups\conf_HelpDb.Bak';
RESTORE DATABASE [conf.HelpDbBu]
FROM DISK = 'C:\tfsCollateral\_projects\conf\dbBackups\conf_HelpDb.Bak'
WITH RECOVERY,
MOVE 'conf.HelpDb' TO 'C:\tfsCollateral\_projects\conf\dbBackups\conf.HelpDb.mdf',
MOVE 'conf.HelpDb_log' TO 'C:\tfsCollateral\_projects\conf\dbBackups\conf.HelpDb_log.ldf';
ALTER AUTHORIZATION ON DATABASE::[conf.HelpDbBu] TO SA;
GO
Not being certain of the best way to execute this query from code, I settled on running an SQL command using a SqlConnection. The following code works: (certain parts are currently hard coded that will be changed after the bugs are ironed out)
Public Shared Function ExecuteSQLCommand()
Dim commandText = "USE master;" &
"ALTER DATABASE [conf.HelpDbBu] SET OFFLINE WITH ROLLBACK IMMEDIATE;" &
"ALTER DATABASE [conf.HelpDbBu] SET ONLINE;" &
"DROP DATABASE [conf.HelpDbBu]" &
"USE [conf.HelpDb];" &
"BACKUP DATABASE [conf.HelpDb]" &
"TO DISK = 'C:\tfsCollateral\_projects\conf\dbBackups\conf_HelpDb.Bak'" &
"With Format," &
"MEDIANAME = 'SQLServerBackups'," &
"NAME = 'Full Backup of conf.HelpDb';" &
"RESTORE DATABASE [conf.HelpDbBu]" &
"From DISK = 'C:\tfsCollateral\_projects\conf\dbBackups\conf_HelpDb.Bak'" &
"With RECOVERY," &
"MOVE 'conf.HelpDb' TO 'C:\tfsCollateral\_projects\conf\dbBackups\conf.HelpDb.mdf', " &
"MOVE 'conf.HelpDb_log' TO 'C:\tfsCollateral\_projects\conf\dbBackups\conf.HelpDb_log.ldf';" &
"ALTER AUTHORIZATION ON DATABASE:: [conf.HelpDbBu] TO SA;"
Using connection As SqlConnection = New SqlConnection(ConfigurationManager.ConnectionStrings("HelpDbConnection").ConnectionString)
Dim command As SqlCommand = New SqlCommand(commandText, connection)
command.Connection.Open()
command.ExecuteNonQuery()
End Using
Return 1
End Function
The connection string is:
connectionString="Data Source=<my pcname>\SQLEXPRESS; Initial Catalog=conf.HelpDb;Integrated Security=SSPI" providerName="System.Data.SqlClient" />
But the original query included the following lines:
USE master
RESTORE VERIFYONLY
From DISK = 'C:\tfsCollateral\_projects\conf\dbBackups\conf_HelpDb.Bak';
RESTORE FILELISTONLY
From DISK = 'C:\tfsCollateral\_projects\conf\dbBackups\conf_HelpDb.Bak';
The lines above errored out with the following message:
System.Data.SqlClient.SqlException: 'Database 'masterRESTORE' does not exist. Make sure that the name is entered correctly.'
I added a colon to the first line above making it USE master;. But now I have the following error and I am unable to see the problem.
System.Data.SqlClient.SqlException: 'Incorrect syntax near 'DISK'.'
The purpose of the RESTORE FILELISTONLY wasn't perfectly clear to me, but I presumed it was to find out the exact filenames in the .Bak file to be restored so the subsequent RESTORE DATABASE command could be properly populated.
While the vb.net code shown above runs without the 5 lines of SQL code that created the errors, I am unable to execute the backup verification. I'm not sure if the RESTORE FILELISTONLY is really necessary in this case.
So my question is: How do I fix things so the verification can be performed?

How can I allow multiple users to access/edit a microsoft access database?

Now I know right off the bat that Microsoft access isn't the ideal client for multiple users accessing it but it's the only one I've got right now. I have built a small program as a sort of inventory management system. There are currently three users that will be using it regularly and at the same time. One issue I am running into with this is that sometimes the database will not be accessible and will give an error stating that the file is already in use by "so and so" user. The other issue is that I'm getting a similar error every now and then where it states "The database has been placed in a state by user on machine that prevents it from being opened or locked". I am connecting to the database through an ACE OLEDB connection using the line below
con.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=P:\Tool & Cutter Grinding\Tool Cutter Database.accdb;Persist Security Info = False"
I have also changed some of the settings in the actual access database such as:
Enable all macros
Add the folder the database is in to the trusted locations list
Confirm that the database is set to open in shared mode by default
I don't know if there is something small I've missed or a setting I need to change but as of yet, the problem is still persisting.
Below is an example of how I am using the database. I am using string based SQL commands but am not too familiar with DataSet/DataTable/etc. items, so I may be doing something incorrectly.
'close connection from any previous session
con.Close()
'clear dataset so as not to append data
ds.Clear()
'Select SQL query that selects ALL records from a table
Dim str As String = "SELECT * FROM " & "[" & table & "]" & ""
con.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=P:\Tool & Cutter Grinding\Tool Cutter Database.accdb;Persist Security Info = False"
'use try catch statement to open the connection
Try
con.Open()
Catch ex As Exception
MsgBox(Convert.ToString(ex))
End Try
'use try catch statement to add a table (dt) to the dataset (ds) in order to store values
Try
ds.Tables.Add(dt)
Catch ex As Exception
End Try
'create new dataadapter object using the sql string from above and the connection created above
da = New OleDbDataAdapter(str, con)
'create new command builder in order to excecute the SELECT SQL statement using the dataadapter created (da)
'specify prefix and suffix for cb
Dim cb = New OleDbCommandBuilder(da) With {
.QuotePrefix = "[",
.QuoteSuffix = "]"
}
'use try catch statement to fill the datatable (dt) using the dataadapter (da)
Try
da.Fill(dt)
Catch ex As Exception
MsgBox(Convert.ToString(ex))
End Try
'set the datasource of the datagridview to the datatable
dgv.DataSource = dt.DefaultView
'close the connection to the database
con.Close()
Go to your Back-End Access DB file. File > Options > Client Settings. For your Use Case No Locks should be fine, but Edited record setting will work as well if you need it
but its [sic] the only one I've got right now
Actually, it's not.
Have a look at SQL Server Compact. It's free, it's small and it handles multiple users with aplomb.
You can add all the references you need using NuGet.

VB.NET upload SQL script to create database and tables

I have written a small application. On first run of the application I want to upload an SQL script to the local SQL Server Express Instance.
On my development machine I have created the database and tables and have exported the scripts using SSMS to a sql file. I can import that file into SSMS and execute it, and the database will be created. I do not know how to perform the same process using VB.NET
I added the sql file to my project as a resource and I have included the first few lines below
USE [master]
GO
/****** Object: Database [MyProject] Script Date: 5/04/2016 11:30:42 PM ******/
CREATE DATABASE [MyProject]
CONTAINMENT = NONE
ON PRIMARY
( NAME = N'MyProject', FILENAME = N'C:\Program Files\Microsoft SQL Server\MSSQL11.SQLEXPRESS\MSSQL\DATA\MyProject.mdf' , SIZE = 4160KB , MAXSIZE = UNLIMITED, FILEGROWTH = 1024KB )
LOG ON
( NAME = N'MyProject_log', FILENAME = N'C:\Program Files\Microsoft SQL Server\MSSQL11.SQLEXPRESS\MSSQL\DATA\MyProject_log.ldf' , SIZE = 1040KB , MAXSIZE = 2048GB , FILEGROWTH = 10%)
GO
ALTER DATABASE [MyProject] SET COMPATIBILITY_LEVEL = 110
GO
IF (1 = FULLTEXTSERVICEPROPERTY('IsFullTextInstalled'))
begin
EXEC [MyProject].[dbo].[sp_fulltext_database] #action = 'enable'
end
GO
ALTER DATABASE [MyProject] SET ANSI_NULL_DEFAULT OFF
...
...
USE [MyProject]
GO
/****** Object: Table [dbo].[SomeTable] Script Date: 5/04/2016 11:30:42 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[SomeTable](
[Identifier] [int] IDENTITY(1,1) NOT NULL,
....
I then used the below code to upload the SQL to the database
Private Sub Create_SQL_Database()
Dim connetionString As String = "Data Source=localhost\SQLEXPRESS;Trusted_Connection=YES"
Dim cnn As SqlConnection = New SqlConnection(connetionString)
Dim cmd As SqlCommand = New SqlCommand()
Try
cnn.Open()
Console.Writeline("Connection Open ! Attempting to create database")
cmd.CommandText = My.Resources.CreateDatabaseSQL
cmd.Connection = cnn
Try
cmd.ExecuteNonQuery()
Catch ex As Exception
MessageBox.Show("Error - " & ex.Message)
End Try
This did not work and I received a lot of errors in a messagebox - Incorrect syntax near 'GO' followed by Database 'MyProject' does not exist. Make sure that the name is entered correctly.
I tried removing all of the lines containing GO but was still left with the error - Database 'MyProject' does not exist. Make sure that the name is entered correctly.
I am no expert on this matter but It would seem to me that the GO commands will commit the changes to the database. Because I have been removed the lines with GO on them when the script reaches this line
USE [MyProject]
the database does not exist because the previous steps have not been committed.
What do I need to do in VB.NET to be able to upload this file to the database and create my database and tables?
Thanks.

restore sql localdb with vb.net

I am trying to retrieve a backup copy of the sql localdb through the environment of .net , but I get error .
the error : RESTORE cannot process database 'C:\Users\Emad-VB\Desktop\KizeN\KizeN\bin\Debug\Data\Data\DataStore.mdf' because it is in use by this session. It is recommended that the master database be used when performing this operation. RESTORE DATABASE is terminating abnormally.
the sql Query :
RESTORE DATABASE [C:\Users\Emad-VB\Desktop\KizeN\KizeN\bin\Debug\Data\Data\DataStore.mdf] FROM disk='C:\Users\Emad-VB\Desktop\bac\test.bac'
I tried again to use the database master to make restore but i get this error .
the error :
Incorrect syntax near 'Go'.
the sql Query :
use master
Go
RESTORE DATABASE [C:\Users\Emad-VB\Desktop\KizeN\KizeN\bin\Debug\Data\Data\DataStore.mdf] FROM disk='C:\Users\Emad-VB\Desktop\bac\test.bac'
This is the code that executes sql queries ....
Sub query(ByVal que As String)
'On Error Resume Next
Try
con = New SqlConnection(My.Settings.KConS)
If con.State = ConnectionState.Closed Then
con.Open()
End If
cmd = New SqlCommand
cmd.Connection = con
cmd.CommandType = CommandType.Text
Dim mm As String = " que"
cmd.CommandText = mm
cmd.ExecuteNonQuery()
If con.State = ConnectionState.Open Then
con.Close()
End If
Catch ex As Exception
End Try
End Sub
What is the solution to be able to retrieve the local database and Thanks
I see two problems:
"GO" is not a t-sql command. It is only meanigful to SQL utilities,
such as SQL Server Management Studio, so you shouldn't use it in
code that is being sent directly to the server.
I am not sure that you can change the databse within a connection by using "USE
MASTER". Instead you should create another connection string for
"master" and use it when you inititalize the connection that will perform the restore.

Restoring a backup using SQLCommand in VB.NET

I've got a VB.NET console application I'm creating that will make it easier for people to work with some test databases, and part of this is having a function that restores the database. I thought it was fairly straightforward, and here is the code I have so far:
Sub Restore()
con = New SqlConnection("Data Source=" & utilnamespace.sqlSvr & ";Database=Master;integrated security=SSPI;")
cmd = New SqlCommand("ALTER DATABASE [db] SET OFFLINE WITH ROLLBACK IMMEDIATE RESTORE DATABASE db FROM DISK = 'G:\db.bak' WITH REPLACE, STATS = 10", con)
cmd.Connection.Open()
cmd.ExecuteNonQuery()
Console.WriteLine(cmd.CommandText)
cmd.Connection.Close()
End Sub
The SQL works fine if I run it in SSMS, however it will time out if I try to run it from the app. The problem is that I've read over this and I'm still unsure of what to do.
Should I use BeginExecuteNonQuery and then have it listen for the statement complete message somehow?
Even if I believe that showing a waiting form and waiting for some kind of confirmation would be better for the end user... have you tried changing the timeout in the connection string to solve it in a quick way?
eg (seconds):
string connStr = "Data Source=(local);Initial Catalog=db;
Integrated Security=SSPI;Connection Timeout=30";
Also check these links:
SQL Server Management Objects (SMO)
SQL Server 2008 - Backup and Restore Databases using SMO
If the database is too big you can increase the timeout of the Command, not the connection string
cmd.Connection.Open()
cmd.CommandTimeout = 100
cmd.ExecuteNonQuery()
Console.WriteLine(cmd.CommandText)
cmd.Connection.Close()