Verify Backup SQL Server database using SMO - vb.net

I'm using Vb.net 2013 and SQL Server 2008 R2.
I have a backup database, and I want to restore with SMO. But before restoring I want to verify if this file that I want to restore is a valid SQL Server database backup and has the identical structure (tables , fields) with the database that my program uses.
I know about the Restore.ReadBackupHeader method, but I don't know what information it holds and how I can use it to test this header with the header of a correct database?
Thank you !

I do it in Powershell with smo and and backupdevise. I scan a directory for certain backupfiles and then check in the header what the name of the database is and where the database is from what server and date and so. Finally I map it to the right database and do a restore.
See microsoft ref: https://msdn.microsoft.com/en-us/library/microsoft.sqlserver.management.smo.backupdevice.readbackupheader(v=sql.105).aspx?cs-save-lang=1&cs-lang=vb#code-snippet-1
found this VB code
'Declaration
Public Function ReadBackupHeader As DataTable
'Usage
Dim instance As BackupDevice
Dim returnValue As DataTable
returnValue = instance.ReadBackupHeader()
here is other code:
https://social.msdn.microsoft.com/Forums/sqlserver/en-US/c8e5b271-f053-4d3e-bd39-3d2a89e55af0/version-of-sql-back-up-file?forum=sqlsmoanddmo
Here is my powershell at github code: https://github.com/patriklindstrom/Powershell-pasen/blob/master/Restore-Sql.ps1
[Microsoft.SqlServer.Management.Smo.BackupDeviceItem]$backupDevice = New-Object ("Microsoft.SqlServer.Management.Smo.BackupDeviceItem") ($f.fullname, "File")
#set param so the PercentComplete notification is updated every 10 sec
$smoRestore.Devices.Add($backupDevice)
$ErrorActionPreference = "SilentlyContinue"
#read db name, original sql server name and date from the backup file's backup header
$smoRestoreDetails = $smoRestore.ReadBackupHeader($server)
$DBNameFromBackup = $smoRestoreDetails.Rows[0]["DatabaseName"]
$DatabaseList += $DBNameFromBackup
$OriginalDBServer = $smoRestoreDetails.Rows[0]["ServerName"]
$OriginalDBBackupDate = $smoRestoreDetails.Rows[0]["BackupFinishDate"]
$smoRestore.Database = $DBNameFromBackup
I would suggesst that you write to the description field version number or key /changeset from code repo when backup is made. Then you check it when you want to restore. You can see Header info with eg RESTORE HEADERONLY FROM DISK = 'E:\SQL\big_DB.bak'. I mean a mean database can contain 1000 tables and 30.000 stored procedures. How should you check them in your restore script?

Related

How to Connect to SQL from R Studio

I use Microsoft SQL Server Management Studio on Windows 10 to connect to the following database and this is what the login screen looks like:
Server Type: Database Engine
Server Name: sqlmiprod.b298745190e.database.windows.net
Authentication: SQL Server Authentication
Login: my_user_id
Password: my_password
This recent R Studio article offers an easy way to connect to SQL Servers from R Studio using the following:
con <- DBI::dbConnect(odbc::odbc(),
Driver = "[your driver's name]",
Server = "[your server's path]",
Database = "[your database's name]",
UID = rstudioapi::askForPassword("Database user"),
PWD = rstudioapi::askForPassword("Database password"),
Port = 1433)
I have two questions
What should I use as "[your driver's name]"?
What should I use as "[your database's name]"?
The server path I'll use is sqlmiprod.b298745190e.database.windows.net (from above) and I'll leave the port at 1433. If that's wrong please let me know.
Driver
From #Zaynul's comment and my own experience, the driver field is a text string with the name of the ODBC driver. This answer contains more details on this.
You probably want someting like:
Driver = 'ODBC Driver 17 for SQL Server' (from #Zaynul's comment)
Driver = 'ODBC Driver 11 for SQL Server' (from my own context)
Database
The default database you want to connect to. Roughly equivalent to starting an SQL script with
USE my_database
GO
If all your work will be within a single database then puts its name here.
In some contexts you should be able to leave this blank, but you then have to use the in_schema command to add the database name every time you connect to a table.
If you are working across multiple databases, I recommend putting the name of one database in, and then using the in_schema command to specify the database at every point of connection.
Example using the in_schema command (more details):
df = tbl(con, from = in_schema('database.schema', 'table'))
Though I have not tried it, if you do not have a schema then
df = tbl(con, from = in_schema('database', 'table'))
Should also work (I've been using this hack without issue for a while).

Cannot restore database as file is being used by another process

I have developed this application for a store owner.I want to allow the owner to backup and restore database by using the application.the backup runs fine but the restore is causing an exception which says that - Operating system error 32( the process cannot access the file because it is being used by another process).Restore database is terminated abnormally.
using(var conn = new SqlConnection(ConnectionString))
{
using(SqlCommand cmd = conn.CreateCommand())
{
string datadirectory = Path.Combine(Environment.CurrentDirectory,#"Data");
string query = #"RESTORE DATABASE""{0}""FROM DISK= '{1}' WITH REPLACE";
string query = String.Format(query,backupfile,datadirectory + "\\Database.mdf");
conn.Open();
SqlCommand command = new SqlCommand(query,conn);
command.ExecuteNonQuery();
}
}
How can I solve this issue ? Thanks in advance.
You have to dispose of every SQLiteConnection, SQLiteCommand and SQLiteDataReader once you are done using it. The second command that you create isn't correctly being disposed off.
That aside, your code sample doesn't really make sense. You create a command that is never used. Then you create a second command that isn't properly disposed off.
Is it the restore-file that is blocking? Or is the database itself still running?
If it is the database that is being used, you can set the database in single-user-mode. Another option is taking the database temporarily offline and bring it online again. That should close all existing connections. Tip; with SSMS you can turn almost every command into an SQL script like the button to brink a database offline. Click on 'Script' and you get something like 'USE MASTER GO ALTER DATABASE [AdventureWorks] SET OFFLINE GO'.
wait, this is good news. it looks like the application is running, the db is online and live, so why do want to restore? backups are something you do daily/hourly... but restores you ONLY do if something goes wrong. of course you got an error. the db is live and sql service is using the files and it's good it didn't let you restore or else you would have lost a lot of data.
if all you want is to test the restore, then you need to shut down the sql service first.BUT, make sure you take a backup just before that so you restore the latest.

How to open the .db paradox file

i want to view the test.db file, i search for it's editor but didn't get any one
So please help to see the it in editor as like sql server.
i found some sqlite editor but it's not an sqlite file on most forum it say that it is an paradox .db file.
So how do i open it
Thanks
To access Paradox tables in .NET you can use ODBC. Here's a small example (in C#):
private static void RunMinimumParadoxTest()
{
const string ConnectionStringFormat =
"Driver={{Microsoft Paradox Driver (*.db )}};Uid={0};UserCommitSync=Yes;Threads=3;SafeTransactions=0;" +
"ParadoxUserName={0};ParadoxNetStyle=4.x;ParadoxNetPath={1};PageTimeout=5;MaxScanRows=8;" +
"MaxBufferSize=65535;DriverID=538;Fil=Paradox 7.X;DefaultDir={2};Dbq={2};CollatingSequence={3}";
DbProviderFactory factory = DbProviderFactories.GetFactory("System.Data.Odbc");
using (DbConnection connection = factory.CreateConnection())
{
string userName = "Tor";
string paradoxNetPath = #"C:\BdeNet";
string databasePath = #"C:\LangloMainSrv\LData\Ordre\LordWin\Database2011";
string collatingSequence = "Norwegian-Danish";
connection.ConnectionString =
String.Format(ConnectionStringFormat, userName, paradoxNetPath, databasePath, collatingSequence);
connection.Open();
using (DbCommand command = connection.CreateCommand())
{
command.CommandText = "select Count(*) from [OrdreDet] where [Ordrenr] = 81699002";
object itemCount = command.ExecuteScalar();
Console.WriteLine("Order items: {0}", itemCount);
Console.ReadKey();
}
}
}
Also see the following link for more details: http://msdn.microsoft.com/en-us/library/ms710922(VS.85).aspx.
A Paradox db file contains just one flat table. The actual structure of the DB file changed over time and different versions. But you can usually open the DB file with MS Excel - of course that changed over different versions too.
As noted above, other database applications, also including Paradox for Dos and Paradox for Windows, will open the file and other features as well. The key, for example is in the PX file with the same table name.
All of this assumes the table is not password protected, which an application database could be - or that you know the password. Beware if you get an error to that effect.
You can open and view Paradox database files using Database Desktop that is shipped with Borland C++Builder. A free alternative is BB's Database Desktop. The software may require administrator privileges to run correctly.
You can use gnumeric spreadsheet, paradox-db-reader or BB database desktop to read db paradox file.
BB database dekstop able to read XG0 file too.
BB's Database Desktop now called JEDI Database Desktop, but project is closed and it couldn't edit my table. I have had to use some hack: open *.db file in MS Excel 2007, edit it, export to *.csv, close file then Open *.db file in Paradox Data Editor 3.2.0, clear all table data and import previosly saved csv-file. And it works (don't know why but this app can't insert row in my file itself)!

Copy SQL Server MDF and LDF files while server is in use

I am using the following code to copy files from one folder to another...
Public Shared Sub CopyFlashScriptFile(ByVal SourceDirectory As String, ByVal DestinationDirectory As String)
Try
Dim f() As String = Directory.GetFiles(SourceDirectory)
For i As Integer = 0 To UBound(f)
File.Copy(f(i), DestinationDirectory & "\" & System.IO.Path.GetFileName(f(i)),True)
Next
Catch ex As Exception
MsgBox(ex.Message)
End Try
End Sub
The files I am copying are database files, .mdf and .ldf. Which are being used by the application. Now the problem is when I try to copy the files it throws an error
file is being used by another process
Can anyone help me with this?
Is there anyway I can programmatically stop SQL Server and copy the files, then start the server again?
To expand on my comment - I would build a .sql file with the T-SQL command to backup the database to another location, and then I can use sqlcmd from the command line in order to run the backup .sql file.
So to build the .sql file I would go through the process of backing up the database via SQL Server Management Studio. Here is a tutorial on how to do this:
http://www.serverintellect.com/support/sqlserver/database-backup-ssmse.aspx
Then, before clicking OK to perform the backup, click on the "Script" button on the backup window and choose "Script Action To New Query Window". This will generate the SQL of your settings from the backup database window. Save that SQL into a file and you're done.
Next is to use sqlcmd.exe to execute the .sql file to backup the database whenver you want. There is a very good example of using sqlcmd.exe from C# code here:
http://geekswithblogs.net/thomasweller/archive/2009/09/08/automating-database-script-execution.aspx
I always prefer doing stuff like this without affecting the running SQL Server (unless it's one running on my dev machine, where I'll happily stop/start the service). You just never what might happen if you stop a production SQL Server service to copy some files. Could be very costly, so better to be safe.
Depending on which version of SQL you are using you could make use of the Microsoft.SqlServer.Management.Smo.Wmi.Service objects to Start and Stop the Service that runs the SQL instance.
After doing this you should be able to simply copy the files as needed.
For SQL Server 2008
{
//Declare and create an instance of the ManagedComputer
//object that represents the WMI Provider services.
ManagedComputer mc;
mc = new ManagedComputer();
//Iterate through each service registered with the WMI Provider.
foreach (Service svc in mc.Services)
{
Console.WriteLine(svc.Name);
}
//Reference the Microsoft SQL Server service.
Service Mysvc = mc.Services["MSSQLSERVER"];
//Stop the service if it is running and report on the status
// continuously until it has stopped.
if (Mysvc.ServiceState == ServiceState.Running) {
Mysvc.Stop();
Console.WriteLine(string.Format("{0} service state is {1}", Mysvc.Name, Mysvc.ServiceState));
while (!(string.Format("{0}", Mysvc.ServiceState) == "Stopped")) {
Console.WriteLine(string.Format("{0}", Mysvc.ServiceState));
Mysvc.Refresh();
}
Console.WriteLine(string.Format("{0} service state is {1}", Mysvc.Name, Mysvc.ServiceState));
//Start the service and report on the status continuously
//until it has started.
Mysvc.Start();
while (!(string.Format("{0}", Mysvc.ServiceState) == "Running")) {
Console.WriteLine(string.Format("{0}", Mysvc.ServiceState));
Mysvc.Refresh();
}
Console.WriteLine(string.Format("{0} service state is {1}", Mysvc.Name, Mysvc.ServiceState));
Console.ReadLine();
}
else {
Console.WriteLine("SQL Server service is not running.");
Console.ReadLine();
}
}
From msdn
I am using the .mdf file in my application...in case of a system crash or format the user is going to loose the data..so if the user copies the data(.mdf) to some other drive ..he/she can replace the new .mdf file with the old one which has all there data...correct me if i am wrong...thanks.
That's exactly what "normal" backups are for.
As you noticed yourself, you can backup a SQL Server database by simply copying the .mdf and .ldf files, but the downside is that you can only do this when the SQL Server service is not running.
And stopping the SQL Server service just to backup the database is not a good idea, because your users can't access the database while the service is stopped.
Taking a "normal" backup (usually a .bak file) can be done while the database is running, so there's no need to stop SQL Server every time you want to make a backup.
There are several ways how to do a backup:
a) Manually in SQL Server Management Studio:
see the first link in Jason Evans' answer
b) If you want to take a backup regularly (say, once a day) you need to use sqlcmd.
Jason Evans described this in his answer as well, but IMO there's an easier way - you need only two files with one line each. See How to create jobs in SQL Server Express edition.
(if you were using a full SQL Server edition and not only Express, you could set up a Maintenance Task in Management Studio instead, but that's not possible in SQL Server Express, so you have to do it manually like described above).

SSMS 2008 not remembering connection login credentials [duplicate]

I've recently used our company's spare laptop (that has a general user set up) while mine was being repaired. I've checked the "Remember password" option in SQL Server Management Studio when logging in to the database.
I need to clear the login and password information that I have used to prevent the next person that will use the laptop from using my login names and passwords. How can I do this?
Another answer here also mentions since 2012 you can remove Remove cached login via How to remove cached server names from the Connect to Server dialog?. Just confirmed this delete in MRU list works fine in 2016 and 2017.
SQL Server Management Studio 2017 delete the file
C:\Users\%username%\AppData\Roaming\Microsoft\SQL Server Management Studio\14.0\SqlStudio.bin
SQL Server Management Studio 2016 delete the file
C:\Users\%username%\AppData\Roaming\Microsoft\SQL Server Management Studio\13.0\SqlStudio.bin
SQL Server Management Studio 2014 delete the file
C:\Users\%username%\AppData\Roaming\Microsoft\SQL Server Management Studio\12.0\SqlStudio.bin
SQL Server Management Studio 2012 delete the file
C:\Users\%username%\AppData\Roaming\Microsoft\SQL Server Management Studio\11.0\SqlStudio.bin
SQL Server Management Studio 2008 delete the file C:\Users\%username%\AppData\Roaming\Microsoft\Microsoft SQL Server\100\Tools\Shell\SqlStudio.bin
SQL Server Management Studio 2005 delete the file – same as above answer but the Vista path.
C:\Users\%username%\AppData\Roaming\Microsoft\Microsoft SQL Server\90\Tools\Shell\mru.dat
These are profile paths for Vista / 7 / 8.
EDIT:
Note, AppData is a hidden folder. You need to show hidden folders in explorer.
EDIT:
You can simply press delete from the Server / User name drop down (confirmed to be working for SSMS v18.0). Original source from https://blog.sqlauthority.com/2013/04/17/sql-server-remove-cached-login-from-ssms-connect-dialog-sql-in-sixty-seconds-049/ which mentioned that this feature is available since 2012!
This works for SQL Server Management Studio v18.0
The file "SqlStudio.bin" doesn't seem to exist any longer. Instead my settings are all stored in this file:
C:\Users\*********\AppData\Roaming\Microsoft\SQL Server Management Studio\18.0\UserSettings.xml
Open it in any Texteditor like Notepad++
ctrl+f for the username to be removed
then delete the entire <Element>.......</Element> block
that surrounds it.
EDIT:
An even easier and working solution for v18.0 (Preview 7) would be:
Go to the "Connect to Server" dialogue window:
Click the down-arrow icon marked green in the screenshot.
Use the arrow-keys on the keyboard to navigate up/down
Press the DEL key on keyboard to delete the entry.
Close the dialogue window and when you reopen it the entry will indeed be removed.
For those looking for the SSMS 2012 solution... see this answer:
Remove cached login 2012
Essentially, in 2012 you can delete the server from the server list dropdown which clears all cached logins for that server.
Works also in v17 (build 14.x).
In my scenario I only wanted to remove a specific username/password from the list which had many other saved connections I didn't want to forget. It turns out the SqlStudio.bin file others are discussing here is a .NET binary serialization of the Microsoft.SqlServer.Management.UserSettings.SqlStudio class, which can be deserialized, modified and reserialized to modify specific settings.
To accomplish removal of the specific login, I created a new C# .Net 4.6.1 console application and added a reference to the namespace which is located in the following dll: C:\Program Files (x86)\Microsoft SQL Server\130\Tools\Binn\ManagementStudio\Microsoft.SqlServer.Management.UserSettings.dll (your path may differ slightly depending on SSMS version)
From there I could easily create and modify the settings as desired:
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using Microsoft.SqlServer.Management.UserSettings;
class Program
{
static void Main(string[] args)
{
var settingsFile = new FileInfo(#"C:\Users\%username%\AppData\Roaming\Microsoft\SQL Server Management Studio\13.0\SqlStudio.bin");
// Backup our original file just in case...
File.Copy(settingsFile.FullName, settingsFile.FullName + ".backup");
BinaryFormatter fmt = new BinaryFormatter();
SqlStudio settings = null;
using(var fs = settingsFile.Open(FileMode.Open))
{
settings = (SqlStudio)fmt.Deserialize(fs);
}
// The structure of server types / servers / connections requires us to loop
// through multiple nested collections to find the connection to be removed.
// We start here with the server types
var serverTypes = settings.SSMS.ConnectionOptions.ServerTypes;
foreach (var serverType in serverTypes)
{
foreach (var server in serverType.Value.Servers)
{
// Will store the connection for the provided server which should be removed
ServerConnectionSettings removeConn = null;
foreach (var conn in server.Connections)
{
if (conn.UserName == "adminUserThatShouldBeRemoved")
{
removeConn = conn;
break;
}
}
if (removeConn != null)
{
server.Connections.RemoveItem(removeConn);
}
}
}
using (var fs = settingsFile.Open(FileMode.Create))
{
fmt.Serialize(fs, settings);
}
}
}
There is a really simple way to do this using a more recent version of SQL Server Management Studio (I'm using 18.4)
Open the "Connect to Server" dialog
Click the "Server Name" dropdown so it opens
Press the down arrow on your keyboard to highlight a server name
Press delete on your keyboard
Login gone! No messing around with dlls or bin files.
Delete entire node "Element" (inside "Connections" tree) from XML file, used by version 18 or higher.
C:\Users\%username%\AppData\Roaming\Microsoft\SQL Server Management Studio\18.0\UserSettings.xml
As gluecks pointed out, no more SqlStudio.bin in Microsoft SQL Server Management Studio 18. I also found this UserSettings.xml in C:\Users\userName\AppData\Roaming\Microsoft\SQL Server Management Studio\18.0. But removing the <Element> containing the credential seems not working, it comes right back on the xml file, if I close and re-open it again.
Turns out, you need to close the SQL Server Management Studio first, then edit the UserSettings.xml file in your favorite editor, e.g. Visual Studio Code. I guess it's cached somewhere in SSMS besides this xml file?! And it's not on Control Panel\All Control Panel Items\Credential Manager\Windows Credentials.
For SQL Server Management Studio 2008
You need to go C:\Documents and Settings\%username%\Application
Data\Microsoft\Microsoft SQL Server\100\Tools\Shell
Delete SqlStudio.bin
Delete:
C:\Documents and Settings\%Your Username%\Application Data\Microsoft\Microsoft SQL Server\90\Tools\Shell\mru.dat"
In XP, the .mru.dat file is in C:\Documents and Settings\Name\Application Data\Microsoft\Microsoft SQL Server\90\Tools\ShellSEM
However, removing it won't do anything.
To remove the list in XP, cut the sqlstudio bin file from C:\Documents and Settings\Name\Application Data\Microsoft\Microsoft SQL Server\100\Tools\Shell and paste it on your desktop.
Try SQL
If it has worked, then delete the sqlstudio bin file from desktop.
Easy :)
Select the Login drop down arrow. Delete the users from the list