我有一张包含很多列的表格。我有一个函数将我的记录复制到一个新行,并带有更新的自动递增ID。
该函数完美地工作,但是在我的一些INT列上,有时我将NULL作为默认值。当记录重复时,它会将我的NULL位置转换为0。
我假设它是因为我正在做'" . value . "'
有没有人可以帮我弄清楚如何将NULL值插入" . NULL . "
并将其他值保持为'" . value . "'
?
编辑我在区分空值和空值时遇到问题。我尝试过empty()和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();
}
答案 0 :(得分:1)
您不需要将数据提取到PHP中然后再将其发送回MySQL:INSERT ... SELECT
是一个单独的SQL命令,可以使整个shebang本地发生在数据库中。
但是,您需要从操作中排除$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扩展已被弃用,并且多年来一直不鼓励在新代码中使用它。您应该认真考虑切换到MySQLi或PDO。
答案 1 :(得分:0)
你的MySQL版本是什么?某些版本的MySQL(5.5及更早版本,如果我没有记错的话)将空值转换为空字符串字段和0转换为int字段。
您必须强制空值或更新到MySQL 5.6
答案 2 :(得分: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();
}