Cadangkan database SQL Server menggunakan PHP
Saya mencoba untuk membuat cadangan database MS SQL memanggil Prosedur Tersimpan menggunakan PHP.
Ketika saya mengeksekusi de SP di SSMS, semuanya bekerja dengan baik. Namun, ketika saya memanggilnya dari skrip PHP, saya dapat melihat ".bak" di folder cadangan dan tepat setelah PHP selesai diproses, file BackUp.bak menghilang.
Berikut adalah Prosedur Tersimpan:
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';
Di bawah ini adalah kode PHP yang saya sebut SP:
$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);
Saya menjalankan Apache 2.4.46 dan SQL Server Express 2019.
Tujuan saya adalah membuat file ".bak" menggunakan PHP.
Saya mencoba menggunakan SP karena kode aslinya ditulis dalam ASP Klasik dan bekerja dengan sempurna seperti ini.
Saya terbuka untuk mencoba pendekatan yang berbeda.
Terima kasih.
Jawaban
Penjelasan:
Anda menggunakan Pengandar PHP untuk SQL Server, jadi penjelasan berikut adalah opsi tambahan untuk memecahkan masalah Anda:
- Tampaknya masalah ini mungkin merupakan masalah khusus driver. SQL Server mengisi buffer output koneksi dengan kumpulan hasil yang dibuat oleh batch - informasi tentang jumlah baris yang terpengaruh (dalam kasus
INSERT\DELETE\UPDATEpernyataan misalnya) atau status kemajuan (dikembalikan dariBACKUP\RESTORE DATABADEpernyataan). Kumpulan hasil ini harus diproses oleh skrip PHP. Tampaknya perilaku ini sesuai rancangan dan skrip PHP harus membersihkan semua set hasil yang tertunda. Setelah kumpulan hasil diambil, SQL Server menyelesaikan eksekusi batch. Fungsi \ metode yang sesuai yang perlu Anda gunakan adalahsqlsrv_next_result()(untuk versi SQLSRV driver) danPDOStatement::nextRowset()(untuk versi PDO_SQLSRV driver). - Untuk versi SQLSRV dari driver, Anda perlu mengubah kesalahan dan penanganan peringatan menggunakan
sqlsrv_configure("WarningsReturnAsErrors", 0);.
Contoh:
Saya dapat mereproduksi masalah dari pertanyaan dan contoh berikut adalah solusi yang berfungsi:
Menggunakan versi SQLSRV dari driver:
<?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);
?>
Menggunakan versi PDO_SQLSRV driver:
<?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;
?>