2008-12-06 79 views
9

所以我有一個需要使用mysql_query()加載的SQL轉儲文件。不幸的是,用它執行多個查詢是不可能的。PHP:在一個mysql_query語句中執行多個SQL查詢

- >它不能被假定mysql命令行客戶(MySQL的--help)安裝 - 用於裝載SQL文件直接

- >它不能被假定的mysqli擴展安裝

/* contents of dump.sql, including comments */ 
DELETE FROM t3 WHERE body = 'some text; with semicolons; scattered; throughout'; 
DELETE FROM t2 WHERE name = 'hello'; 
DELETE FROM t1 WHERE id = 1; 

的爆炸()以下不會工作,因爲某些轉儲內容的值包含分號。

$sql = explode(';', file_get_contents('dump.sql')); 
foreach ($sql as $key => $val) { 
    mysql_query($val); 
} 

加載SQL而不修改轉儲文件的最佳方式是什麼?

回答

12

您有更多的問題情況下比字符串中只是分號。

  • 腳本不能由mysql_query()執行,像USEbuiltin命令。
  • 不以分號結尾的語句,如DELIMITER
  • 包含分號但不包含在引號內的語句,如CREATE PROCEDURE

我不知道一個簡單的方法來處理這個任務,沒有炮擊到mysql命令行客戶端。我意識到你說過你不能依賴那個客戶端,但如果沒有這個客戶端,你需要大量的PHP代碼來解析腳本並適當地執行語句。

您可以找到phpMyAdmin產品中這樣的代碼。但是,該產品已獲得GPL許可,因此如果您使用任何代碼,則還必須在GPL下授權您自己的項目。


參見我的答案,這些相關的問題:

6

奧卡姆剃刀再次罷工。

上述爆炸()函數是行不通的,因爲有中值分號。但是,我沒有意識到(並提到),分號總是在SQL轉儲文件中的換行符之前。唉,

$sql = explode(";\n", file_get_contents('dump.sql')); 
foreach ($sql as $key => $val) { 
    mysql_query($val); 
} 

另外,感謝您的幫助,比爾。

+0

你做一行的末尾有分號的情況下,但它不是一個聲明,例如結束在過程或觸發器定義的主體內部。像DELIMITER這樣的語句不會以分號結尾。 – 2008-12-06 02:27:44

3

這裏有一個更大的問題。你可能有依賴於其他陳述的陳述。你不能盲目地線性執行它們。

+0

在運行查詢列表之前,總是可以告訴mysql忽略唯一檢查和外鍵檢查,這將解決許多查詢順序問題。 – enobrev 2008-12-08 07:37:59

0
<?php 
//STATIC QUERY 
$sql1 = " 
CREATE TABLE tblTable (
strOne VARCHAR(50) NOT NULL, 
strTwo VARCHAR(50) NOT NULL, 
strThree VARCHAR(50) NOT NULL 
); 
INSERT INTO tblTable 
(strOne, strTwo, strThree) 
VALUES ('String 1', 'String 2', 'String 3'); 
UPDATE tblTable 
SET 
strOne = 'String One', 
strTwo = 'String Two' 
WHERE strThree = 'String 3'; 
"; 
//GET FROM FILE 
$sql2 = file_get_contents('dump.sql'); 
$queries = preg_split("/;+(?=([^'|^\\\']*['|\\\'][^'|^\\\']*['|\\\'])*[^'|^\\\']*[^'|^\\\']$)/", $sql); 
foreach ($queries as $query){ 
    if (strlen(trim($query)) > 0) mysql_query($query); 
} 
?>