Sichern Sie die SQL Server-Datenbank mit PHP

Sep 22 2020

Ich versuche, eine MS SQL-Datenbank zu sichern, die eine gespeicherte Prozedur mit PHP aufruft.

Wenn ich de SP auf SSMS ausführe, funktioniert alles einwandfrei. Wenn ich es jedoch über das PHP-Skript aufrufe, wird im Sicherungsordner eine ".bak" angezeigt, und direkt nach Abschluss der Verarbeitung von PHP verschwindet die Datei "BackUp.bak".

Hier ist die gespeicherte Prozedur:

DECLARE @date VARCHAR(10)
SET @date = (SELECT date FROM tbl_date)

Declare @fileName VARCHAR(100)
SET @fileName = ('C:\db_backup\BackUp_' + @date + '.bak')

BACKUP DATABASE DbName
TO DISK = @fileName
   WITH FORMAT,
      MEDIANAME = 'SQLServerBackups',
      NAME = 'Full Backup of DbName';

Unten ist der PHP-Code, den ich SP nenne:

$serverName = "server"; $connectionInfo = array( "Database"=>"DbName", "UID"=>"UserName", "PWD"=>"P@ssword", "CharacterSet"=>"UTF-8", "ReturnDatesAsStrings" => "false");
$conn = sqlsrv_connect( $serverName, $connectionInfo); $BackupDB = "Exec DBBackup";
sqlsrv_query($conn, $BackupDB);

Ich verwende Apache 2.4.46 und SQL Server Express 2019.

Mein Ziel ist es, eine ".bak" -Datei mit PHP zu erstellen.

Ich habe versucht, einen SP zu verwenden, da der Originalcode in Classic ASP geschrieben ist und auf diese Weise einwandfrei funktioniert.

Ich bin offen für verschiedene Ansätze.

Vielen Dank.

Antworten

Zhorov Sep 24 2020 at 07:46

Erklärungen:

Sie verwenden den PHP-Treiber für SQL Server. Die folgenden Erläuterungen sind daher eine zusätzliche Option zur Lösung Ihres Problems:

  • Es scheint, dass dieses Problem wahrscheinlich ein treiberspezifisches Problem ist. SQL Server füllt den Ausgabepuffer der Verbindung mit den Ergebnismengen, die vom Stapel erstellt werden - Informationen über die Anzahl der betroffenen Zeilen ( INSERT\DELETE\UPDATEz. B. bei Anweisungen) oder den Fortschrittsstatus (von BACKUP\RESTORE DATABADEAnweisungen zurückgegeben). Diese Ergebnismengen müssen vom PHP-Skript verarbeitet werden. Es scheint, dass dieses Verhalten beabsichtigt ist und das PHP-Skript alle ausstehenden Ergebnismengen löschen sollte. Nachdem die Ergebnismengen abgerufen wurden, schließt SQL Server die Ausführung des Stapels ab. Die entsprechenden Funktionen \ Methoden, die Sie verwenden müssen, sind sqlsrv_next_result()(für die SQLSRV-Version des Treibers) und PDOStatement::nextRowset()(für die PDO_SQLSRV-Version des Treibers).
  • Für die SQLSRV-Version des Treibers müssen Sie die Fehler- und Warnbehandlung mit ändern sqlsrv_configure("WarningsReturnAsErrors", 0);.

Beispiele:

Ich kann das Problem anhand der Frage reproduzieren, und die folgenden Beispiele sind funktionierende Lösungen:

Verwenden der SQLSRV-Version des Treibers:

<?php
// Server information
$server = "server\instance,port"; $database = "database";
$uid = "username"; $pwd      = "password";

// Configuration
sqlsrv_configure("WarningsReturnAsErrors", 0);

// Connection
$cinfo = array( "UID" => $uid,
    "PWD" => $pwd, "Database" => $database
);
$conn = sqlsrv_connect($server, $cinfo); if ($conn === false) {
    echo "Unable to connect.";
    die( print_r( sqlsrv_errors(), true));
}

// Statement
$sql = " DECLARE @date VARCHAR(19) SET @date = CONVERT(VARCHAR(19), GETDATE(), 126) SET @date = REPLACE(@date, ':', '-') SET @date = REPLACE(@date, 'T', '-') DECLARE @fileName VARCHAR(100) SET @fileName = ('d:\backup\BackUp_' + @date + '.bak') BACKUP DATABASE dbname TO DISK = @fileName WITH FORMAT, STATS = 1, MEDIANAME = 'SQLServerBackups', NAME = 'Full Backup of dbname'; "; $stmt = sqlsrv_query($conn, $sql);
if ($stmt === false) { echo "Unable to execute query."; die( print_r( sqlsrv_errors(), true)); } // Clear buffer while (sqlsrv_next_result($stmt) != null){};
echo "Success";

// End
sqlsrv_free_stmt($stmt); sqlsrv_close($conn);
?>

Verwenden der PDO_SQLSRV-Version des Treibers:

<?php
// Server information
$server = "server\instance,port"; $database = "database";
$uid = "username"; $pwd      = "password";

// Connection
try {
    $conn = new PDO("sqlsrv:server=$server;Database=$database", $uid, $pwd); $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch( PDOException $e ) { die( "Error connecting to SQL Server".$e->getMessage());
}

// Statement
$sql = " DECLARE @date VARCHAR(19) SET @date = CONVERT(VARCHAR(19), GETDATE(), 126) SET @date = REPLACE(@date, ':', '-') SET @date = REPLACE(@date, 'T', '-') DECLARE @fileName VARCHAR(100) SET @fileName = ('d:\backup\BackUp_' + @date + '.bak') BACKUP DATABASE dbname TO DISK = @fileName WITH FORMAT, STATS = 1, MEDIANAME = 'SQLServerBackups', NAME = 'Full Backup of dbname'; "; try { $stmt = $conn->prepare($sql);
    $stmt->execute(); } catch (PDOException $e) {
    die ("Error executing query. ".$e->getMessage()); } // Clear buffer try { while ($stmt->nextRowset() != null){};
    echo "Success";
} catch (PDOException $e) { die ("Error executing query. ".$e->getMessage());
}

// End
$stmt = null; $conn = null;
?>