2012-12-18 84 views
4

我想動態地插入'NULL'到數據庫使用PDO。調試PDO mySql插入NULL到數據庫而不是空

表結構:

CREATE TABLE IF NOT EXISTS `Fixes` (
    `Id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'PK', 
    `CurrencyId` int(11) NOT NULL COMMENT 'FK', 
    `MetalId` int(11) NOT NULL COMMENT 'FK', 
    `FixAM` decimal(10,5) NOT NULL, 
    `FixPM` decimal(10,5) DEFAULT NULL, 
    `TimeStamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, 
    PRIMARY KEY (`Id`), 
    KEY `CurrencyId` (`CurrencyId`), 
    KEY `MetalId` (`MetalId`) 
) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci AUTO_INCREMENT=13 ; 

PHP/PDO QUERY:

$sql = 'UPDATE 
      Fixes 
    SET 
      FixAM = :fixAM, 
     FixPM = :fixPM 
     WHERE 
      MetalId IN (SELECT Id FROM Metals WHERE Name = :metal) AND 
     CurrencyId IN (SELECT Id FROM Currencies Where Id = :currency)'; 

$stmt = $db->prepare($sql); 

for ($i = 0; $i<3; $i++) { 
    $stmt->execute(array(
    ':metal' => 'Silver', 
    ':fixAM' => $fix['FixAM'][$i], 
    ':fixPM' => $fix['FixPM'][$i], 
    ':currency' => ($i+1)) 
    );  
} 

例如有時,$fix['FixPM'][$i]的值爲有時'NULL'。我如何將其插入數據庫?當我運行查詢並查看數據庫中的數據時,此記錄顯示0.0000,而不是空值。

How do I insert NULL values using PDO?提供了一些解決方案。

  • 我不認爲我可以使用$stmt->execute(array(':v1' => null, ':v2' => ...))作爲示例,因爲有時項目爲空,有時不是。因此,我需要參考我創建$fix['FixPM'][$i]變量並作出的,需要提前

感謝時。

+0

是在'Fixed'表架構'FixPM'場可爲空? – luchosrock

+0

你好,我澄清了這個問題。表結構顯示FixPM可以爲空。 – Gravy

+1

變量的值是否實際爲'NULL',或者是_string_''NULL'',當轉換爲數值時將轉換爲'0'? PDO應該正確處理一個真正的NULL,但是該字符串將被轉換。 –

回答

7

這在我看來是PDO的準備語句仿真的(N未報告?)錯誤:

  1. implementationPDOStatement::execute()eventually調用pdo_parse_params();

  2. ,反過來,attempts to quote/escape values基於相關參數的數據類型(由$data_type參數所指示的PDOStatement::bindValue()和提供PDOStatement::bindParam() —所有參數$input_parametersPDOStatement::execute()PDO::PARAM_STR處理,作爲該功能的文檔中所述);

  3. 串類型的值被轉義/由calling相關的數據庫驅動程序的quoter()方法,不論它們是否是null引述:在PDO_MYSQL的情況下,這是mysql_handle_quoter(),該(最終)的值傳遞給任一mysqlnd_cset_escape_quotes()mysql_cset_escape_slashes(),取決於服務器的NO_BACKSLASH_ESCAPES SQL模式;

  4. 給出一個null參數,這兩個函數都返回一個空字符串。

我的觀點是,之前switching on the parameter's type(在上述步驟2),pdo_parse_params()應的類型,如果該值爲null設置爲PDO::PARAM_NULL。然而,有些人可能會爭辯說,這會在適當的情況下阻止null值的類型特定處理,在這種情況下,在繼續調用驅動程序的quoter()方法之前,string case(在上面的步驟3中)肯定應該處理null值。

作爲一個臨時解決辦法,禁用準備語句仿真通常是最好的呢:

$db->setAttribute(PDO::ATTR_EMULATE_PREPARES, FALSE); 
+0

很好。非常詳細和專注的答案! – danihp