2014-04-23 27 views
1

我有一個包含大量列的表。我有一個函數將我的記錄複製到具有更新的自動遞增ID的新行中。使用空變量複製mysql行

該函數完美工作,但是,在我的一些INT列,有時我有一個NULL作爲默認值。當記錄被複制,就會使我空放置到0

我猜想那是因爲我在做'" . value . "'

誰能幫我找出我怎麼能讓NULL值插入爲" . NULL . "和保持其他值爲'" . value . "'

編輯我無法區分空值和空值。我試過空()和is_null()和沒有價值的varchar和一個NULL值的INT沒有顯示

一個區別:我明白,我使用的是過時的MySQL擴展。現在,我只是想正確處理我的空變量。

function duplicateRow($table, $id_field, $id_value) 
{ 
    // copy content of the record you wish to clone 
    $entity = mysql_fetch_array(mysql_query("SELECT * FROM {$table} WHERE {$id_field}={$id_value}"), MYSQL_ASSOC) or die("Could not select original record"); 

    // set the auto-incremented id's value to blank. If you forget this step, nothing will work because we can't have two records with the same id 
    $entity[$id_field] = ""; 

    // insert cloned copy of the original record 
    mysql_query("INSERT INTO {$table} (".implode(", ",array_keys($entity)).") VALUES ('".implode("', '",array_values($entity))."')") or die(mysql_error()); 

    //returns the new id 
    return mysql_insert_id(); 
} 
+1

你有這裏的一切都非常有活力的,並且那是偉大的,但是當你要開始爲特定的使用值是如何在你的領域處理,你必須放棄一些動態性的。指定字段並將它們合併爲一個'NULL'字符串,或更改'。價值。「來處理空值。 – paqogomez

+0

我沒有寫這個函數,所以我很難分解發生了什麼@paqogomez – user3566265

+0

爲什麼不使用['INSERT ... SELECT'](http://dev.mysql.com/doc /en/insert-select.html)? – eggyal

回答

0

什麼是您的MySQL版本?一些版本的MySQL(5.5和更早版本,如果我沒有弄錯)將空值轉換爲空的字符串字段和0到int字段。

您必須強制空值或更新到MySQL 5.6

+0

有沒有強制null的選項,還是我需要在我的代碼中指定?我正在使用5.5 – user3566265

+0

更好的方法是在您的代碼中指定,以避免將來的MySQL升級錯誤使用默認值。 – Junior

+0

我在區分空值和空值時遇到問題。我已經嘗試了empty()和is_null()和一個沒有值的varchar,而一個帶有NULL值的INT沒有顯示出差異 – user3566265

1

你並不需要獲取數據到PHP只有把它送回來到MySQL:INSERT ... SELECT是一個SQL命令,使整個事情在數據庫中本地發生。

但是,您需要從操作中排除$id_field,因此您不能使用*通配符,而必須明確列出列名稱。這增加了一些複雜性,特別是在安全,注射證明的方式進行操作:

function duplicateRow($table, $id_field, $id_value) 
{ 
    // prevent SQL injection 
    $enc_map = array(
     'utf8' => 'UTF-8', 
     'latin1' => 'Windows-1252' // etc. 
    ); 
    mb_regex_encoding($enc_map[mysql_client_encoding()]); 
    $table_safe = '`'.mb_ereg_replace('`', '``', $table ).'`'; 
    $id_field_safe = '`'.mb_ereg_replace('`', '``', $id_field).'`'; 
    $id_value_safe = mysql_real_escape_string($id_value); 

    // fetch column names 
    $fields = array(); 
    $qry = mysql_query("SHOW COLUMNS FROM $table_safe"); 
    while ($row = mysql_fetch_assoc($qry)) 
     if ($row['field'] != $id_field) 
     $fields[] = '`'.mb_ereg_replace('`', '``', $row['field']).'`'; 

    $fields_safe = implode(',', $fields); 

    // duplicate the record 
    mysql_query(" 
     INSERT INTO $table_safe 
     ($fields_safe) 
     SELECT $fields_safe 
     FROM $table_safe 
     WHERE $id_field_safe = '$id_value_safe' 
    "); 

    //returns the new id 
    return mysql_insert_id(); 
} 

注意,古代EXT/mysql擴展已被棄用,其在新代碼中使用已氣餒多年。您應該認真考慮切換到MySQLiPDO

+0

您是否知道我將如何使用PDO中的「prepare」語句使此查詢比僅執行它更安全? ''INSERT INTO {$ table}(「.implode(」,「,array_keys($ entity))。」)VALUES('「.implode(」','「,array_values($ entity))。」')「 '@eggyal – user3566265

+0

@ user3566265:準備好的語句只能參數化文字值(例如本例中的'$ id_value') - 它們不能參數化對象標識符,如表或字段名稱。 – eggyal

0

我最終制作了一個foreach語句,該語句用於檢查我的值是否爲null並且稍微改變了查詢。這可能不是最好的,正確的或實際的方式來做到這一點,但它的工作原理。如果有人有任何建議,他們100%讚賞!

我讓我的功能大致相同的原因是我需要將它用於多個大型表格。所以我不知道這些田地究竟是什麼。

function duplicateRow($table, $id_field, $id_value) 
{ 
    // copy content of the record you wish to clone 
    $entity = mysql_fetch_array(mysql_query("SELECT * FROM {$table} WHERE {$id_field}={$id_value} AND snapshot=0"), MYSQL_ASSOC) or die("Could not select original record"); 

    foreach ($entity as &$value) { if(is_null($value) == true) { $value = "NULL"; } else { $value = "'$value'"; } } 

    // set the auto-incremented id's value to blank. If you forget this step, nothing will work because we can't have two records with the same id 
    $entity[$id_field] = "'"; 

    // insert cloned copy of the original record 
    $query = "INSERT INTO {$table} (".implode(", ",array_keys($entity)).") VALUES ('".implode(", ",array_values($entity)).")"; 
    mysql_query($query) or die(mysql_error()); 

    //returns the new id 
    return mysql_insert_id(); 
} 
+0

我的版本應該是這個功能的替代品... – eggyal