This operation is in a thread, for it must take much time.
Codes below:
- unit CustomSQLThread;
- {----------------------------------------------------------
- - Example for using this unit -
- - procedure BackupDB; -
- - var -
- - BackupThread : TCustomSQLBackupThread; -
- - begin -
- - BackupThread := TCustomSQLBackupThread.Create(true); -
- - with BackupThread do -
- - begin -
- - FreeOnTerminate := true; -
- - DBHost := '127.0.0.1'; -
- - UserID := 'sa'; -
- - UserPwd := ''; -
- - DatabaseName := ''; -
- - BackupFileName := 'C:/MyBackup'; -
- - Execute; -
- - end; -
- - end; -
- ----------------------------------------------------------}
- Interface
- Uses
- Classes, SysUtils, DB, ADODB, Windows, ShellAPI, Registry;
- Type
- { SQL Server operations state }
- TSQLStates = (ssSuccess, ssFail);
- { thread of backup SQL Server database }
- TCustomSQLBackupThread = Class(TThread)
- private
- FDatabaseName: String;
- FUserPwd: String;
- FBackupFileName: String;
- FUserID: String;
- FDBHost: String;
- FBackupState: TSQLStates;
- FErrorMessage: String;
- protected
- { Run thread }
- procedure Execute; override;
- public
- Constructor Create(CreateSuspended: Boolean);
- Property BackupState: TSQLStates read FBackupState;
- Property ErrorMessage: String read FErrorMessage;
- published
- { The host name of SQL Server }
- Property DBHost: String read FDBHost write FDBHost;
- { The user name for login SQL Server }
- Property UserID: String read FUserID write FUserID;
- { The user password for login SQL Server}
- Property UserPwd: String read FUserPwd write FUserPwd;
- { The database's name }
- Property DatabaseName: String read FDatabaseName write FDatabaseName;
- { Where you put the backup file at }
- Property BackupFileName: String read FBackupFileName write FBackupFileName;
- end;
- { thread of restore SQL Server database }
- TCustomSQLRestoreThread = Class(TThread)
- private
- FDatabaseName: String;
- FUserPwd: String;
- FBackupFileName: String;
- FUserID: String;
- FDBHost: String;
- FBackupState: TSQLStates;
- FErrorMessage: String;
- FLogicDatabaseName: String;
- FLogicLogName: String;
- protected
- { Run thread }
- procedure Execute; override;
- public
- Constructor Create(CreateSuspended: Boolean);
- Property BackupState: TSQLStates read FBackupState;
- Property ErrorMessage: String read FErrorMessage;
- published
- { The host name of SQL Server }
- Property DBHost: String read FDBHost write FDBHost;
- { The user name for login SQL Server }
- Property UserID: String read FUserID write FUserID;
- { The user password for login SQL Server}
- Property UserPwd: String read FUserPwd write FUserPwd;
- { The database's name }
- Property DatabaseName: String read FDatabaseName write FDatabaseName;
- { Where you put the backup file at }
- Property BackupFileName: String read FBackupFileName write FBackupFileName;
- { The logic database file name }
- Property LogicDatabaseName: String read FLogicDatabaseName write FLogicDatabaseName;
- { The logic log file name }
- Property LogicLogName: String read FLogicLogName write FLogicLogName;
- end;
- { Global methods }
- { whether SQL Server installed or not }
- function SQLServerInstalled: Boolean;
- { get SQL Server install path if installed }
- function GetSQLServerPath: String;
- { Services operations }
- procedure SQLServicesOperation(CommandStr: String);
- Implementation
- resourcestring
- { connection string }
- ConnStr =
- 'Provider=SQLOLEDB.1;' +
- 'Data Source=%s;' + // Host Name
- 'Persist Security Info=True;' +
- 'User ID=%s;' + // User Name
- 'Password=%s;' + // User Password
- 'Initial Catalog=%s'; // DatabaseName
- { backup database T-SQL codes }
- BackupStr =
- 'BACKUP DATABASE [%s] TO ' + // Database Name
- 'DISK=N'#39'%s'#39' WITH NOINIT,' + // Physics File Name
- 'NOUNLOAD,NOSKIP,STATS=10,NOFORMAT';
- { restore database T-SQL codes }
- RestoreStr =
- 'RESTORE DATABASE [%s] FROM ' + // Database Name
- 'DISK=N'#39'%s'#39' WITH FILE=1,' + // Physics File Name
- 'NOUNLOAD,STATS=10,RECOVERY,' +
- 'MOVE '#39'%s'#39' to '#39'%s'#39',' + // Logic Database Name
- 'MOVE '#39'%s'#39' to '#39'%s'#39; // Logic Log Name
- { restore database without move file T-SQL codes }
- RestoreStr2 =
- 'RESTORE DATABASE [%s] FROM ' + // Database Name
- 'DISK=N'#39'%s'#39' WITH FILE=1,' + // Physics File Name
- 'NOUNLOAD,STATS=10,RECOVERY';
- { Global methods }
- /// <summary>
- /// whether SQL Server installed
- /// </summary>
- /// <returns>installed(true)/not installed(false)</returns>
- function SQLServerInstalled: Boolean;
- Var
- Reg: TRegistry;
- Path: String;
- begin
- Reg := TRegistry.Create;
- Reg.RootKey := HKEY_LOCAL_MACHINE;
- Reg.OpenKey('SOFTWARE/Microsoft/MSSQLServer/Setup', true);
- Path := Reg.ReadString('SQLPath');
- if (Path <> '') and (DirectoryExists(Path)) then
- Result := true
- Else
- Result := false;
- Reg.CloseKey;
- Reg.Free;
- end;
- /// <summary>
- /// get SQL Server installed path
- /// </summary>
- /// <returns>path(if installed)</returns>
- function GetSQLServerPath: String;
- Var
- Reg: TRegistry;
- Path: String;
- begin
- if Not SQLServerInstalled then
- begin
- Result := '';
- Exit;
- end;
- Reg := TRegistry.Create;
- Reg.RootKey := HKEY_LOCAL_MACHINE;
- Reg.OpenKey('SOFTWARE/Microsoft/MSSQLServer/Setup', true);
- Path := Reg.ReadString('SQLPath');
- Result := Path + '/Data/';
- Reg.CloseKey;
- Reg.Free;
- end;
- /// <summary>
- /// do operations order with commandstr
- /// </summary>
- /// <param name="CommandStr">command line</param>
- procedure SQLServicesOperation(CommandStr: String);
- Var
- sCommandLine: String;
- bCreateProcess: Boolean;
- lpStartupInfo: TStartupInfo;
- lpProcessInformation: TProcessInformation;
- begin
- sCommandLine := CommandStr;
- // fill record space
- FillChar(lpStartupInfo, SizeOf(TStartupInfo), #0);
- lpStartupInfo.cb := SizeOf(TStartupInfo);
- lpStartupInfo.dwFlags := STARTF_USESHOWWINDOW;
- lpStartupInfo.wShowWindow := SW_HIDE;
- // create process
- bCreateProcess := CreateProcess(Nil, PChar(sCommandLine), Nil, Nil, true, CREATE_NEW_CONSOLE Or NORMAL_PRIORITY_CLASS, Nil, Nil, lpStartupInfo, lpProcessInformation);
- // wait for process finished
- if bCreateProcess then
- WaitForSingleObject(lpProcessInformation.hProcess, INFINITE);
- end;
- { TCustomDBBackupRestoreThread }
- Constructor TCustomSQLBackupThread.Create(CreateSuspended: Boolean);
- begin
- Inherited Create(CreateSuspended);
- // if you want to get the state when thread finished,
- // add a method of type TNotifyEvent and bind it to:
- // OnTerminate event of this class.
- end;
- procedure TCustomSQLBackupThread.Execute;
- Var
- Qry: TADOQuery;
- begin
- Qry := TADOQuery.Create(Nil);
- With Qry Do
- begin
- ConnectionString := Format(ConnStr,
- [DBHost, UserID, UserPwd, DatabaseName]);
- SQL.Text := Format(BackupStr, [DatabaseName, BackupFileName]);
- Try
- ExecSQL;
- FBackupState := ssSuccess;
- FErrorMessage := '';
- Except
- On E: Exception Do
- begin
- FBackupState := ssFail;
- FErrorMessage := E.Message;
- end;
- end;
- Free;
- end;
- end;
- { TCustomSQLRestoreThread }
- Constructor TCustomSQLRestoreThread.Create(CreateSuspended: Boolean);
- begin
- Inherited Create(CreateSuspended);
- // if you want to get the state when thread finished,
- // add a method of type TNotifyEvent and bind it to:
- // OnTerminate event of this class.
- end;
- procedure TCustomSQLRestoreThread.Execute;
- Var
- Qry: TADOQuery;
- begin
- // Stop SQL Server Services
- // this operation may let all user connects logoff.
- SQLServicesOperation('net stop MSSQLSERVER');
- // restart SQL Server
- SQLServicesOperation('net start MSSQLSERVER');
- // Restore database
- Qry := TADOQuery.Create(Nil);
- With Qry Do
- begin
- // if you want to restore "master"
- // change "master" to other Database's name
- ConnectionString := Format(ConnStr,
- [DBHost, UserID, UserPwd, 'master']);
- SQL.Text := Format(RestoreStr,
- [DatabaseName, BackupFileName, LogicDatabaseName, LogicLogName]);
- Try
- ExecSQL;
- FBackupState := ssSuccess;
- FErrorMessage := '';
- Except
- SQL.Text := Format(RestoreStr2, [DatabaseName, BackupFileName]);
- Try
- ExecSQL;
- FBackupState := ssSuccess;
- FErrorMessage := '';
- Except
- On E: Exception Do
- begin
- FBackupState := ssFail;
- FErrorMessage := E.Message;
- end;
- end;
- end;
- Free;
- end;
- end;
- end.