สำรองฐานข้อมูล SQL Server โดยใช้ PHP

Sep 22 2020

ฉันพยายามสำรองฐานข้อมูล MS SQL ที่เรียก Stored Procedure โดยใช้ PHP

เมื่อฉันดำเนินการ de SP บน SSMS ทุกอย่างทำงานได้ดี อย่างไรก็ตามเมื่อฉันเรียกมันจากสคริปต์ PHP ฉันจะเห็น ".bak" ในโฟลเดอร์สำรองและทันทีที่ PHP ประมวลผลเสร็จสิ้นไฟล์ BackUp.bak จะหายไป

นี่คือขั้นตอนการจัดเก็บ:

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

ด้านล่างนี้คือรหัส PHP ที่ฉันเรียกว่า 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);

ฉันใช้ Apache 2.4.46 และ SQL Server Express 2019

เป้าหมายของฉันคือสร้างไฟล์ ".bak" โดยใช้ PHP

ฉันลองใช้ SP เพราะโค้ดดั้งเดิมเขียนด้วย Classic ASP และมันทำงานได้อย่างไม่มีที่ติด้วยวิธีนี้

ฉันเปิดให้ลองใช้แนวทางต่างๆ

ขอขอบคุณ.

คำตอบ

Zhorov Sep 24 2020 at 07:46

คำอธิบาย:

คุณกำลังใช้ PHP Driver สำหรับ SQL Server ดังนั้นคำอธิบายต่อไปนี้จึงเป็นตัวเลือกเพิ่มเติมสำหรับการแก้ปัญหาของคุณ:

  • ดูเหมือนว่าปัญหานี้อาจเป็นปัญหาเฉพาะของไดรเวอร์ SQL Server เติมบัฟเฟอร์เอาต์พุตของการเชื่อมต่อด้วยชุดผลลัพธ์ที่สร้างขึ้นโดยชุดงาน - ข้อมูลเกี่ยวกับจำนวนแถวที่ได้รับผลกระทบ (ในกรณีของINSERT\DELETE\UPDATEคำสั่งเป็นต้น) หรือสถานะความคืบหน้า (ส่งคืนจากBACKUP\RESTORE DATABADEคำสั่ง) ชุดผลลัพธ์เหล่านี้ต้องได้รับการประมวลผลโดยสคริปต์ PHP ดูเหมือนว่าพฤติกรรมนี้เกิดจากการออกแบบและสคริปต์ PHP ควรล้างชุดผลลัพธ์ที่รอดำเนินการทั้งหมด หลังจากดึงชุดผลลัพธ์แล้ว SQL Server จะดำเนินการชุดงานให้เสร็จสมบูรณ์ ฟังก์ชัน \ วิธีการที่เหมาะสมที่คุณต้องใช้คือsqlsrv_next_result()(สำหรับไดรเวอร์เวอร์ชัน SQLSRV) และPDOStatement::nextRowset()(สำหรับไดรเวอร์เวอร์ชัน PDO_SQLSRV)
  • สำหรับไดรเวอร์เวอร์ชัน SQLSRV คุณต้องเปลี่ยนข้อผิดพลาดและการจัดการคำเตือนโดยใช้sqlsrv_configure("WarningsReturnAsErrors", 0);.

ตัวอย่าง:

ฉันสามารถจำลองปัญหาจากคำถามได้และตัวอย่างต่อไปนี้เป็นวิธีแก้ปัญหาที่ใช้งานได้:

การใช้ไดรเวอร์เวอร์ชัน SQLSRV:

<?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);
?>

การใช้ไดรเวอร์เวอร์ชัน PDO_SQLSRV:

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