Sau nửa ngày loay hoay với cái này, phát hiện ra rằng PDO có một lỗi ở ...
-
//This would run as expected:
$pdo->exec("valid-stmt1; valid-stmt2;");
-
//This would error out, as expected:
$pdo->exec("non-sense; valid-stmt1;");
-
//Here is the bug:
$pdo->exec("valid-stmt1; non-sense; valid-stmt3;");
Nó sẽ thực thi "valid-stmt1;"
, dừng lại "non-sense;"
và không bao giờ báo lỗi. Sẽ không chạy "valid-stmt3;"
, trả lại sự thật và nói dối rằng mọi thứ chạy tốt.
Tôi hy vọng nó sẽ xảy ra lỗi "non-sense;"
nhưng nó không.
Đây là nơi tôi tìm thấy thông tin này:
Truy vấn PDO không hợp lệ không trả lại lỗi
Đây là lỗi:
https://bugs.php.net/bug.php?id=61613
Vì vậy, tôi đã thử làm điều này với mysqli và chưa thực sự tìm thấy bất kỳ câu trả lời chắc chắn nào về cách hoạt động của nó vì vậy tôi nghĩ rằng tôi chỉ để nó ở đây cho những người muốn sử dụng nó ..
try{
// db connection
$mysqli = new mysqli("host", "user" , "password", "database");
if($mysqli->connect_errno){
throw new Exception("Connection Failed: [".$mysqli->connect_errno. "] : ".$mysqli->connect_error );
exit();
}
// read file.
// This file has multiple sql statements.
$file_sql = file_get_contents("filename.sql");
if($file_sql == "null" || empty($file_sql) || strlen($file_sql) <= 0){
throw new Exception("File is empty. I wont run it..");
}
//run the sql file contents through the mysqli's multi_query function.
// here is where it gets complicated...
// if the first query has errors, here is where you get it.
$sqlFileResult = $mysqli->multi_query($file_sql);
// this returns false only if there are errros on first sql statement, it doesn't care about the rest of the sql statements.
$sqlCount = 1;
if( $sqlFileResult == false ){
throw new Exception("File: '".$fullpath."' , Query#[".$sqlCount."], [".$mysqli->errno."]: '".$mysqli->error."' }");
}
// so handle the errors on the subsequent statements like this.
// while I have more results. This will start from the second sql statement. The first statement errors are thrown above on the $mysqli->multi_query("SQL"); line
while($mysqli->more_results()){
$sqlCount++;
// load the next result set into mysqli's active buffer. if this fails the $mysqli->error, $mysqli->errno will have appropriate error info.
if($mysqli->next_result() == false){
throw new Exception("File: '".$fullpath."' , Query#[".$sqlCount."], Error No: [".$mysqli->errno."]: '".$mysqli->error."' }");
}
}
}
catch(Exception $e){
echo $e->getMessage(). " <pre>".$e->getTraceAsString()."</pre>";
}