I want to restore a SQL Server .bak backup file in InnoSetup.
Here is the code I use:
try
ExtractTemporaryFile ('mydb.bak');
ADOConnection := CreateOleObject('ADODB.Connection');
ADOConnection.ConnectionString :=
'Provider=SQLOLEDB;' + // provider
'Data Source=DESKTOP-UE6ST1P\RMPRO;' + // server name
'Initial Catalog=master ;' + // default database
'User Id=sa;' + // user name
'Password=mypass;'; // password
ADOConnection.Open;
try
ADOCommand := CreateOleObject('ADODB.Command');
ADOCommand.ActiveConnection := ADOConnection;
ADOCommand.CommandText := 'RESTORE DataBase mydb FROM DISK = ' + QuotedStr(ExpandConstant('{tmp}\mydb.bak'));
ADOCommand.CommandType := adCmdText;
ADOCommand.Execute(NULL, NULL, adCmdText or adExecuteNoRecords);
finally
ADOConnection.Close;
end;
except
MsgBox('Error', mbError, MB_OK);
end;
end;
When I run this code get this error
Exception: Microsoft OLE DB Provider for SQL Server: Cannot open backup device 'C:\Users\sina\AppData\Local\Temp\is-QADA6.tmp\mydb.bak'. Operating system error 5 (Access is denied).
How I can handle access denied in InnoSetup? I run the setup in "Run as Administrator" and turn UAC off, but I still have this problem.
Related
Am trying to restore the database from python 3.7 in Windows using below script.
Drop database functions correctly as expected.
The restore database doesn't work as expected, database always shows "Restoring...." and never completes.
Database files are there in the specified path, but database is not usable.
How to fix this?
import pyodbc
try:
pyconn = pyodbc.connect('DRIVER={ODBC Driver 17 for SQL Server};SERVER=MY-LAPTOP\\SQLEXPRESS;DATABASE=master;UID=sa;PWD=sa123')
cursor = pyconn.cursor()
pyconn.autocommit = True
sql = "IF EXISTS (SELECT 0 FROM sys.databases WHERE name = 'data_test') BEGIN DROP DATABASE data_test END"
pyconn.cursor().execute(sql)
sql = """RESTORE DATABASE data_test FROM DISK='G:\\dbbak\\feb-20-2020\\data_test_backup_2020_02_20_210010_3644975.bak' WITH RECOVERY,
MOVE N'Omnibus_Data' TO N'd:\\db\\data_test.mdf',
MOVE N'Omnibus_Log' TO N'd:\\db\\data_test_1.ldf';"""
print(sql)
pyconn.cursor().execute(sql)
while pyconn.cursor().nextset():
pass
pyconn.cursor().close()
except Exception as e:
print(str(e))
You're not using a single cursor, and so your program is exiting before the restore is complete, aborting it in the middle.
Should be something like:
conn = pyodbc.connect(' . . .')
conn.autocommit = True
cursor = conn.cursor()
cursor.execute(sql)
while cursor.nextset():
pass
cursor.close()
0
After hours I found solution. It must be performed no MASTER, other sessions must be terminated, DB must be set to OFFLINE, then RESTORE and then set to ONLINE again.
def backup_and_restore():
server = 'localhost,1433'
database = 'myDB'
username = 'SA'
password = 'password'
cnxn = pyodbc.connect('DRIVER={ODBC Driver 17 for SQL Server};SERVER='+server+';DATABASE=MASTER;UID='+username+';PWD='+ password)
cnxn.autocommit = True
def execute(cmd):
cursor = cnxn.cursor()
cursor.execute(cmd)
while cursor.nextset():
pass
cursor.close()
execute("BACKUP DATABASE [myDB] TO DISK = N'/usr/src/app/myDB.bak'")
execute("ALTER DATABASE [myDB] SET SINGLE_USER WITH ROLLBACK IMMEDIATE;")
execute("ALTER DATABASE [myDB] SET OFFLINE;")
execute("RESTORE DATABASE [myDB] FROM DISK = N'/usr/src/app/myDB.bak' WITH REPLACE")
execute("ALTER DATABASE [myDB] SET ONLINE;")
execute("ALTER DATABASE [myDB] SET MULTI_USER;")
I am working on an application on Delphi 10.2, And it connects to a SQL Server 2014 database. What can I do to test the connection with the database having the connection string before the application starts?
I have used ADoconnection as an interface to connect to the aforementioned database, did some coding with try-catch or try-except to rule out the unwanted SQL Server errors, and using a gauge Bar to indicate the advancement of my start procedure (which progresses with query activation and form creation).
So when the connection string is not ok, I will get an error of
Login failed for user 'admin98'
(admin98 is the name of the SQL Server user); and when the connection string is ok, the gauge bar progresses and in the halfway through I have again the same error.
NOTE: I used freeInstance or NewInstance or other things like that but it didn't work.
This is the function that connects to the database and catches errors if encounters
function DBConnect: Boolean;
var
conStr : string;
begin
conStr:= 'Provider=SQLOLEDB.1;Persist Security Info=False;User ID=admin'+Fstart_.year_combobox.Text+';PassWord=000;Initial Catalog=student'+Fstart_.year_combobox.Text+';Data Source='+Fstart_.StringTemp+';';
DataModule1.ADOConnection1.Close;
DataModule1.ADOConnection1.ConnectionString:= conStr;
DataModule1.ADOConnection1.LoginPrompt:= False;
if (NOT DataModule1.ADOConnection1.Connected) then
begin
try
DataModule1.ADOConnection1.Open;
Result:= True;
Except on E:Exception do
begin
if e.Message = 'Login failed for user '+chr(39)+'admin'+Fstart_.year_combobox.Text+chr(39) then
//showmessage
if e.Message = '[DBNETLIB][ConnectionOpen (Connect()).]SQL Server does not exist or access denied' then
//showmessage
DataModule1.ADOConnection1.Close;
DataModule1.ADOConnection1.ConnectionString:= '';
Result:= False;
end;
end;
end;
end;
The thing is that it has to work and I shouldn't restart the application so I need to either test before connection or reset the whole connection.
I expect the successful connection but I get the error again even when I change the combo box value and I know that the user exists in SQL Server
This Answer worked for me and I found out that I need 5 seconds of sleep
to get the thread out of RAM
function DBConnect: Boolean;
var
conStr : string;
begin
ini:= TMemIniFile.Create(GetCurrentDir + '\Settings.ini');
Fstart_.StringTemp:= ini.ReadString('Server Directory', 'Server Name', KeyFileString);
Application.CreateForm(TDataModule1, DataModule1);
DataModule1.ADOConnection1.Close;
conStr:= 'Provider=SQLOLEDB.1;Persist Security Info=False;User ID=admin'+Fstart_.year_combobox.Text+';PassWord=123;Initial Catalog=darman'+Fstart_.year_combobox.Text+';Data Source='+Fstart_.StringTemp+';';
DataModule1.ADOConnection1.ConnectionString:= conStr;
DataModule1.ADOConnection1.LoginPrompt:= False;
try
DataModule1.ADOConnection1.Open;
Result:= True;
Except on E:Exception do
begin
if e.Message = 'Login failed for user '+chr(39)+'admin'+Fstart_.year_combobox.Text+chr(39) then
// Showmessage
[mbOK],0);
if e.Message = '[DBNETLIB][ConnectionOpen (Connect()).]SQL Server does not exist or access denied' then
// ShowMessage
DataModule1.ADOConnection1.Close;
DataModule1.Destroy;
Sleep(5000);
end;
end;
end;
I am trying to do a full backup for an MSSQL database using go.
However, I tested the connection to the MSSQL server and it works like charm!
By executing also a query into the code SELECT ##VERSION
It gives me the version and that has been connected to mssql using the credentials in the code below.
By running a query BACKUP DATABASE name_db TO DISK = '/tmp/database.bak' it fails with the following error
Error with Backing up the DBmssql: BACKUP DATABASE is terminating abnormally
I am sure that I am missing something, any ideas/thoughts would be much appreciated.
BTW, I am on Ubuntu 16.04 and the mssql is installed there, I am using go version 1.9.
This is my code:
package main
import (
_ "github.com/denisenkom/go-mssqldb"
"database/sql"
"context"
"log"
"fmt" )
var server = "server_url"
var port = 1433
var user = "user"
var password = "pass"
var db *sql.DB
func main() {
var err error
// Create connection string
connString := fmt.Sprintf("server=%s;user id=%s;password=%s;
port=%d", server, user, password, port)
// Create connection pool
db, err = sql.Open("sqlserver", connString)
if err != nil {
log.Fatal("Error creating connection pool: "
+ err.Error())
}
log.Printf("Connected!\n")
defer db.Close()
Backup()
//Restore()
}
func Backup(){
ctx := context.Background()
err := db.PingContext(ctx)
if err != nil {
log.Fatal("Error pinging database :( " + err.Error())
}
var result string
err = db.QueryRowContext(ctx, "BACKUP DATABASE tempdb
TO DISK= '/tmp/Backup.bak' WITH NOFORMAT, NOINIT,
SKIP, NOREWIND, NOUNLOAD, STATS = 10;").Scan(&result)
//err = db.QueryRowContext(ctx, "select ##version").Scan(&result)
if err != nil {
log.Fatal("Error with Backing up the DB", err.Error())
}
fmt.Printf("%s\n",result)
}
I have found the solution which is very silly.. You can find it in the 1st reply.
That was obvious though, the code is clean and working as expected.
The only issue was from MSSQL, where it have a specific value set for the timeout queries.
That's why I succeeded executing other SQL queries like: SELECT ##VERSION from the example above in the Q.
Though, I set the value of the timeout for remote queries to 0 this SQL query:
EXEC SP_CONFIGURE 'remote query timeout', 0
reconfigure
EXEC sp_configure
The 0 in remote query timeout means that the timeout is unlimited.
The issue was from MSSQL and os , try query first on SQL Server Management Studio to explane where problem come from.
now, change this :
(
err = db.QueryRowContext(ctx, "BACKUP DATABASE tempdb
TO DISK= '/tmp/Backup.bak' WITH NOFORMAT, NOINIT,
SKIP, NOREWIND, NOUNLOAD, STATS = 10;").Scan(&result)
)
to
(
err = db.QueryRowContext(ctx, "BACKUP DATABASE tempdb
TO DISK= '/tmp/Backup.bak' WITH NOFORMAT, NOINIT,
SKIP, NOREWIND, NOUNLOAD, STATS = 10;").Err()
)
becouse db.QueryRowContext expected to return at most one row
and backup Query dont return any row
I am using the below code to backup a Database on my local SqlExpress database.
procedure RestoreScoreDb(DBName,OldName,BackName : String);
var
cmd : WideString;
SqlBackupDir : String;
SqlDataDir : String;
begin
Try
ConnectionMaster.Connected := False;
ConnectionMaster.Close;
ConnectionMaster.ConnectionString := 'Provider=SQLNCLI11.1;Integrated Security="";Persist Security Info=False;User ID=SA;Password=Tccc1234;OLE DB Services=-2;Initial Catalog="master";Data Source=\SQLEXPRESS;Initial File Name="";Packet Size=4096;Auto Translate=True;Server SPN=""';
SqlBackupDir := ReadIniStr(IniCfg,'Dir','SqlBackup');
SqlDataDir := ReadIniStr(IniCfg,'Dir','SqlData');
cmd := 'RESTORE DATABASE '+DBName;
cmd := Cmd + ' FROM DISK = N'''+SqlBackupDir+'\'+BackName+'''';
cmd := Cmd + ' WITH FILE = 1';
cmd := cmd + ' , MOVE N'''+OldName+''' TO N'''+SqlDataDir+'\'+DBName+'.mdf''';
cmd := cmd + ' , MOVE N'''+OldName+'_log'' TO N'''+SqlDataDir+'\'+DBName+'.ldf''';
cmd := cmd + ' , NOUNLOAD, REPLACE, STATS = 10';
CmdRestore.CommandText := cmd;
CmdRestore.Connection := ConnectionMaster;
CmdRestore.Execute;
except
on E: Exception do
writeln(LogFile,'RestoreScoreDb = '+E.Message);
end;
end;
The Restore command is
cmd ='RESTORE DATABASE score_import FROM DISK =
N''C:\Program Files\Microsoft SQL Server\MSSQL11.SQLEXPRESS\MSSQL\Backup\score_import.bak''
WITH FILE = 1 , MOVE N''score_import'' TO
N''C:\Program Files\Microsoft SQL Server\MSSQL11.SQLEXPRESS\MSSQL\DATA\score_import.mdf'' ,
MOVE N''score_import_log'' TO N''C:\Program Files\Microsoft SQL Server\MSSQL11.SQLEXPRESS\MSSQL\DATA\score_import.ldf'' ,
NOUNLOAD, REPLACE, STATS = 10'
When I copy and paste into management studio it restore the table without trouble. but when I run this code I get an Error:
User does not have permission to RESTORE database "score_import"
SA has full permission. Any idea what I am missing? Delphi XE6, Windows 10 Sql 2012.
Thanks to Embarcadero support. They could reproduce my problem and resolved it by removing Integrated Security="" from the connection string. If you are interested in why, do a Google search for "ADO Integrated Security".
I have 4 pc's. 2 have full setup SQ Server 2012 setup, 1 as all but the data base setup, and 1 does not have SQL setup at all. The 3 with SQL setup connects to the one I call the subserver that has the data base setup on. The one without SQL installed on it at all does not connect throws an exception.
Here is my connection string.
Provider=SQLNCLI11;Integrated Security="";Persist Security Info=False;User ID=sa;password=Xxxx1234;OLE DB Services=-2;Initial Catalog=score_data;Data Source=192.168.9.25,1433;Initial File Name="";Packet Size=4096;Auto Translate=True;Server SPN="";
Here is my Delphi code used to create this string and connect
function TFrmTb2.ConnectToSqlDB(Var DataBase : TADOConnection; Catalog : String; Var Msg : ShortString) : Boolean;
var
cntStr : String;
begin
msg := '';
CntStr := DataBase.Name;
if not DataBase.Connected then
begin
if Not DataBase.Connected then
begin
with FrmTb2 do
begin //Edit ConfigHdwe2016Nw.Ini in tne Score2016NW Directory section SQL
CntStr := 'Provider='+ReadIniStr(IniHdwe,'SQL','Provider')+';';//SQLNCLI11.1';//SQLNCLI10.1;';
CntStr := CntStr + 'Integrated Security='+ReadIniStr(IniHdwe,'SQL','Integrated Security')+';';//"";';
CntStr := CntStr + 'Persist Security Info='+ReadIniStr(IniHdwe,'SQL','Persist Security Info')+';';//False;';
CntStr := CntStr + 'User ID='+ReadIniStr(IniHdwe,'SQL','User ID')+';';//shithead;';
CntStr := CntStr + 'password='+ReadIniStr(IniHdwe,'SQL','password')+';';//shithead;';
CntStr := CntStr + 'OLE DB Services='+ReadIniStr(IniHdwe,'SQL','OLE DB Services')+';';// -2;';
CntStr := CntStr + 'Initial Catalog='+Catalog+';';
CntStr := CntStr + 'Data Source='+ReadIniStr(IniHdwe,'SQL','Data Source')+';';//\SQLEXPRESS;';
CntStr := CntStr + 'Initial File Name='+ReadIniStr(IniHdwe,'SQL','Initial File Name')+';';//"";';
CntStr := CntStr + 'Packet Size='+ReadIniStr(IniHdwe,'SQL','Packet Size')+';';//4096;';
CntStr := CntStr + 'Auto Translate='+ReadIniStr(IniHdwe,'SQL','Auto Translate')+';';//True;';
CntStr := CntStr + 'Server SPN='+ReadIniStr(IniHdwe,'SQL','Server SPN')+';';//""';
end;
// ShowMessage(CntStr);
DataBase.ConnectionString := CntStr;
try
DataBase.Connected := True;
if DataBase.Connected then
begin
// ShowMessage('After Conection');
result := True;
end
else
begin
result := False;
ShowMessage('Unable to Connect to Score2016Nw Database Bad Ip or Connection Missing1');
end;
except
result := False;
ShowMessage('Unable to Connect to Score2016Nw Database Bad Ip or Connection Missing2');
end;
end
else
result := True;
end
else
result := True; // we are still conected to the sql database
end;
My network person tells me that the fire fall port 1433 is open ( it is a hardware wirewall and I don't have access). I have checked and rechecked that on the subserver that the ip2 is Active = Yes; Enabled = Yes; IP Address = 255.255.255.0 (Sub net Mask); TCP Port = 1433 and IPALL Dynamic Ports = ''(Blank) and TCP Port = 1433. I have read just about every post I can find and nothing short of Installing SQL Server Express 2012 on the clients will make it work to talk to the subserver and connect to the database. Is there any tools I could use to find the problem or am I going to need to Install SQL Server on all clients (what a pain)
Your connection string includes SQLNCLI11 as its provider. This means, you need to install SQL Native Client 11 on this machine, as that's the provider it's looking for. When you install SQL Server, it also installs SQL Native Client for you by default. But on a machine which SQL has never been installed on, you will have to install it yourself.
Or, as an alternative, you could use the OLE DB drivers which come pre-installed in Windows, by using SQLOLEDB.1 for the provider instead.