2012-12-12 47 views
0

有沒有辦法使用$wpdb->update();將列設置爲NULL

當我嘗試時,WordPress試圖將該列的類型轉換爲浮點數,該浮點數將NULL轉換爲0

我檢查了核心代碼,在$wpdb->update()裏面,$format參數只是期待%s,%f和%d。我甚至將$wpdb->field_types['myCol']設置爲'NULL',但兩者僅用於突破$wpdb->update()的查詢(有趣的是,它將NULL之後的每列值都移除了)。

這裏有一個相關的問題,但這個答案只處理INSERT,不是UPDATE

從數據完整性角度來看,NULL對於本專欄非常重要,所以我必須能夠在必要時對其進行設置。

+0

此問題的可能重複:http://stackoverflow.com/questions/2596962/wordpress-database-insert-and-update-using-null-values –

+1

@Set Sail Media這是隻引用'INSERT' 。 – Nick

回答

1

如您所知,$format參數僅爲%s,%f%d。整個事情將通過prepare,它也不會採取null格式說明符,因爲它基本上接受(v)(s)printf接受相同的格式說明符,但沒有參數交換。您無法通過NULLupdate。你有與the post suggested as a possible duplicate中提到的相同的選擇,實際上它是。

  1. 只是不要使用update函數。編寫你自己的SQL,並與$wpdb->query一起使用。如果你正在處理你自己的表,那應該沒問題。
  2. 創建你自己的數據庫類做你想做的。這是一個有點知道的事實,你可以取代WordPress'$wpdbdrop-in
0

下面是修改從WordPress的最新版本的WPDB,爲了讓使用insert()和update()插入和更新空值的SQL表的解決方案:

/* 
* Fix wpdb to allow inserting/updating of null values into tables 
*/ 
class wpdbfixed extends wpdb 
{ 
    function insert($table, $data, $format = null) { 
     $type = 'INSERT'; 
     if (! in_array(strtoupper($type), array('REPLACE', 'INSERT'))) 
      return false; 
     $this->insert_id = 0; 
     $formats = $format = (array) $format; 
     $fields = array_keys($data); 
     $formatted_fields = array(); 
     foreach ($fields as $field) { 
      if (!empty($format)) 
       $form = ($form = array_shift($formats)) ? $form : $format[0]; 
      elseif (isset($this->field_types[$field])) 
       $form = $this->field_types[$field]; 
      else 
       $form = '%s'; 

      //***edit begin here*** 
      if ($data[$field]===null) { 
       unset($data[$field]); //Remove this element from array, so we don't try to insert its value into the %s/%d/%f parts during prepare(). Without this, array would become shifted. 
       $formatted_fields[] = 'NULL'; 
      } else { 
       $formatted_fields[] = $form; //Original line of code 
      } 
      //***edit ends here*** 
     } 
     $sql = "{$type} INTO `$table` (`" . implode('`,`', $fields) . "`) VALUES (" . implode(",", $formatted_fields) . ")"; 
     return $this->query($this->prepare($sql, $data)); 
    } 

    function update($table, $data, $where, $format = null, $where_format = null) 
    { 
     if (! is_array($data) || ! is_array($where)) 
      return false; 

     $formats = $format = (array) $format; 
     $bits = $wheres = array(); 
     foreach ((array) array_keys($data) as $field) { 
      if (!empty($format)) 
       $form = ($form = array_shift($formats)) ? $form : $format[0]; 
      elseif (isset($this->field_types[$field])) 
       $form = $this->field_types[$field]; 
      else 
       $form = '%s'; 

      //***edit begin here*** 
      if ($data[$field]===null) 
      { 
       unset($data[$field]); //Remove this element from array, so we don't try to insert its value into the %s/%d/%f parts during prepare(). Without this, array would become shifted. 
       $bits[] = "`$field` = NULL"; 
      } else { 
       $bits[] = "`$field` = {$form}"; //Original line of code 
      } 
      //***edit ends here*** 
     } 

     $where_formats = $where_format = (array) $where_format; 
     foreach ((array) array_keys($where) as $field) { 
      if (!empty($where_format)) 
       $form = ($form = array_shift($where_formats)) ? $form : $where_format[0]; 
      elseif (isset($this->field_types[$field])) 
       $form = $this->field_types[$field]; 
      else 
       $form = '%s'; 
      $wheres[] = "`$field` = {$form}"; 
     } 

     $sql = "UPDATE `$table` SET " . implode(', ', $bits) . ' WHERE ' . implode(' AND ', $wheres); 
     return $this->query($this->prepare($sql, array_merge(array_values($data), array_values($where)))); 
    } 

} 
global $wpdb_allow_null; 
$wpdb_allow_null = new wpdbfixed(DB_USER, DB_PASSWORD, DB_NAME, DB_HOST); 

插入將這段代碼放到總是運行的地方,比如你的functions.php,然後像正常一樣使用新的全局$ wpdb_allowed_null-> insert()和 - > update()。

我喜歡這樣做,而不是重寫默認的$ wpdb,以便保留其他Wordpress和其他插件所期望的數據庫行爲。