2016-02-26 63 views
3

我有一個數據庫升級腳本,它採用當前的數據庫版本,將它傳遞給一個巨大的switch語句,其中沒有任何中斷因此所有隨後的查詢運行,然後將數據庫編號更新爲最新版本。免責聲明:我知道有可能有更好的方法來做到這一點(就像一堆if($version>1507)檢查,所以我不必爲「空」版本),但我沒有時間重構並進行測試。我會,最終,但我真的不認爲這個問題是相關的。PHP行執行(MySQL命令)兩次(或根本沒有註釋掉)

這裏是升級腳本的樣本,包括那些給我的問題的線(S):

case 1508: 
    addNotification("Updating 1508: Adding feature specific tables for wake-up calls, virtual dispatcher and screen pop, to allow better usage and billing tracking", "success"); 
    dbQuery("CREATE TABLE IF NOT EXISTS `feature_wakeup_calls` (`feature_wakeup_call_id` int(12) NOT NULL AUTO_INCREMENT, `employee_id` int(12) NOT NULL, `date` date NOT NULL, `confirmed` datetime DEFAULT NULL, `employee_sms_id` int(12) DEFAULT NULL, `employee_call_id` int(12) DEFAULT NULL, `authority_call_id` int(12) DEFAULT NULL COMMENT 'call record to the authority', `balance_id` int(12) NOT NULL COMMENT 'references balance table', PRIMARY KEY (`feature_wakeup_call_id`)) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;"); 
    dbQuery("CREATE TABLE IF NOT EXISTS `feature_virtual_dispatcher` (`feature_virtual_dispatcher_id` int(12) NOT NULL AUTO_INCREMENT, `inbound_call_id` int(12) NOT NULL, `outbound_call_id` int(12) DEFAULT NULL, `balance_id` int(12) NOT NULL, PRIMARY KEY (`feature_virtual_dispatcher_id`)) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;"); 
    dbQuery("CREATE TABLE IF NOT EXISTS `feature_screen_pop_endpoints` (`feature_screen_pop_endpoint_id` int(12) NOT NULL AUTO_INCREMENT, `mac_address` varchar(50) NOT NULL, `created_by` int(12) DEFAULT NULL, `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (`feature_screen_pop_endpoint_id`)) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;"); 
    dbQuery("CREATE TABLE IF NOT EXISTS `feature_screen_pop` (`feature_screen_pop_id` int(12) NOT NULL AUTO_INCREMENT, `mac` varchar(200) DEFAULT NULL, `phone_number` int(12) NOT NULL, `format` varchar(200) DEFAULT NULL COMMENT 'ex: xml, html, etc', `when` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (`feature_screen_pop_id`)) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;"); 
case 1509: 
case 1510: 
case 1511: 
    addNotification("Updating 1511: New columns to the phone companion endpoints table", "success"); 
    dbQuery("ALTER TABLE `feature_screen_pop_endpoints` ADD `name` VARCHAR(200) NULL AFTER `feature_screen_pop_endpoint_id`;"); 
    dbQuery("ALTER TABLE `feature_screen_pop_endpoints` ADD `extension` VARCHAR(50) NULL DEFAULT NULL AFTER `mac_address`, ADD `manufacturer` ENUM('Polycom','Astra','Mitel/YeaLink','Grandstream') NULL DEFAULT NULL AFTER `extension`, ADD `model` VARCHAR(50) NULL DEFAULT NULL AFTER `manufacturer`;"); 

我遇到的問題是,dbQuery立即呼叫失敗,1511後。如果我評論一下,下一個失敗。以下是dbQuery函數:

function dbQuery($query, $returnId = false, $connection = null) { 
    $close = true; // by default, close the connection once done 
    if($connection == null) $connection = connect(); 
    else $close = false; // don't close the connection if it was passed to us 
    if($returnId == false) { 
     $result = mysqli_query($connection, $query); 
     if($result == false && !stringContains($query, "notification_log")) { // prevent infinite loops 
      addNotification("Query Failed: ".$query." with error: ".mysqli_error($connection)); 
     } 
     if($close) mysqli_close($connection); 
     return $result; 
    } 
    else { 
     $result = mysqli_query($connection, $query); 
     if($result == false) { 
      if($close) mysqli_close($connection); 
      return $result; 
     } 
     else { 
      $result = mysqli_insert_id($connection); 
      if($close) mysqli_close($connection); 
      return $result; 
     } 
    } 
} 

請注意Query Failed部分。我的日誌說:

Query Failed: ALTER TABLE `feature_screen_pop_endpoints` ADD `name` VARCHAR(200) NULL AFTER `feature_screen_pop_endpoint_id` with error: Duplicate column name 'name' 

如果我註釋掉只是一條線,並開始徹底結束了(新的數據庫和一切),我得到下一行類似的錯誤:

Query Failed: ALTER TABLE `feature_screen_pop_endpoints` ADD `extension` VARCHAR(50) NULL DEFAULT NULL AFTER `mac_address`, ADD `manufacturer` ENUM('Polycom','Astra','Mitel/YeaLink','Grandstream') NULL DEFAULT NULL AFTER `extension`, ADD `model` VARCHAR(50) NULL DEFAULT NULL AFTER `manufacturer` with error: Duplicate column name 'extension' 

當然我檢查看看是否有其他地方創建了這些表(他們沒有,如果我在1508年註釋掉它們從不存在的行),並且有類似的dbQuery調用正在完美地執行ALTER TABLE table_name ADD操作。例如,只有幾行上面有這樣的:

case 1502: 
    addNotification("Updating 1502: More data for the balance table", "success"); 
    dbQuery("ALTER TABLE `balance` ADD `extra` VARCHAR(500) NULL AFTER `method`, ADD `unique` VARCHAR(200) NULL AFTER `extra`;"); 

我已經反覆測試,所以我知道這是一些關於這些線(1511套),但我已經遇到這個問題前,我不得不重新設置整個數據庫的基線,繞過交換機中的前1300個案例。雖然這會在這裏起作用,但它正在治療一種症狀並且不會縮放。

任何人有任何線索可能是錯誤的?

+0

你是否完全確定你在這裏顯示的代碼只運行一次?調試步驟:考慮在case語句之後添加一個'die()'或'echo'來查看它是否真的在整個案例中運行兩次。 – CollinD

+0

有一個'notification_log'表,這些'addNotification'函數調用命中。我逐步完成查詢並確認每個dbQuery調用只有一個條目。一旦發生錯誤,它是致命的,腳本完全停止。 – Bing

+0

1511是上述任何情況的重複嗎?你有沒有這個查詢'ALTER TABLE feature_screen_pop_endpoints ADD name' ...你switch語句中的任何其他地方? –

回答

-2

我有同樣的問題。 enter image description here

我發現瀏覽器總是在我的php腳本後請求'favicon.ico'。它的請求URL是{my_domain}/favicon.ico

所以很明顯'favicon.ico'請求導致再次運行腳本。

+0

我甚至沒有從瀏覽器訪問中運行腳本。 – Bing