Backup SQL Server database using PHP

谁说我不能喝 提交于 2021-01-27 18:19:30

问题


I am trying to backup a MS SQL database calling a Stored Procedure using PHP.

When I execute de SP on SSMS, everything works fine. However, when I call it from the PHP script, I can see a ".bak" in the backup folder and right after the PHP finishes processing, the BackUp.bak file disappears.

Here is the Stored Procedure:

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';

Below is the PHP code I call the 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);

I am running Apache 2.4.46 and SQL Server Express 2019.

My goal is to create a ".bak" file using PHP.

I tried using a SP because the original code is written in Classic ASP and it works flawlessly this way.

I am open to try different approaches.

Thank you.


回答1:


Explanations:

You are using PHP Driver for SQL Server, so the following explanations are an additional option for solving your problem:

  • It seems that this issue is probably a driver specific problem. SQL Server fills the output buffer of the connection with the result sets that are created by the batch - information about the count of the affected rows (in a case of INSERT\DELETE\UPDATE statements for example) or progress status (returned from BACKUP\RESTORE DATABADE statements). These result sets must be processed by the PHP script. It seems that this behavior is by design and the PHP script should flush all the pending result sets. After the result sets are fetched, SQL Server completes the execution of the batch. The appropriate functions\methods that you need to use are sqlsrv_next_result() (for SQLSRV version of the driver) and PDOStatement::nextRowset() (for PDO_SQLSRV version of the driver).
  • For the SQLSRV version of the driver you need to change the error and warning handling using sqlsrv_configure("WarningsReturnAsErrors", 0);.

Examples:

I'm able to reproduce the issue from the question and the following examples are working solutions:

Using SQLSRV version of the 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);
?>

Using PDO_SQLSRV version of the 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;
?>


来源:https://stackoverflow.com/questions/64018598/backup-sql-server-database-using-php

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!