【问题标题】:PHP, MYSQl copy one database tables to others and replace empty with nullPHP,MYSQl 将一个数据库表复制到其他数据库表并将空替换为空
【发布时间】:2016-07-13 15:08:26
【问题描述】:

我正在将一个完整的数据库复制到另一个数据库。除了一个问题,一切都在工作。假设我的一张桌子具有以下结构

 id -> Integer PK AI
 state_id -> Integer (Default NULL)
 sell_id  -> Integer (Default NULL)

现在这个表的 state_id 和 sell_id 可以有 NULL。因此,我向该表查询 SELECT,针对所有 NULL 值返回一个空字符串。但是当我尝试将这些值插入其他数据库表时,它会生成错误,因为整数列中不能给出空字符串。就像选择查询返回数据一样,比如下面的数组

array(
  'id' => 1,
  'state_id' => '',
  'sell_id' => ''
)

所以我会尝试将此数组插入到新表中,它会产生错误。所以我想用NULL替换所有''。我尝试通过将 NULL 设置为所有空值来跟踪

  $array = array_map(function($v){
                    return $v == '' ? NULL : $v;
                },$array);

但这也会将'' 打印到所有NULL 值。这是我的完整代码

$result = mysqli_query($dbConnection1, "SELECT * FROM $table ORDER BY $sortedBy DESC limit $noOfRecords");

$columns = '';
$values = '';
if($result && mysqli_num_rows($result)) {
    while ($row = mysqli_fetch_array($result, MYSQLI_ASSOC) ) {
        $array = array_values($row);
        $array = array_map(function($v){
            return $v == '' ? NULL : $v;
        },$array);

        $columns = " (".implode(", ",array_keys($row)).") ";
        $values .= " ('".implode("', '",$array)."'),";
    }
    $values = rtrim($values, ",");
    mysqli_query($dbConnection2, "INSERT INTO $table $columns VALUES $values");
}

但此代码不适用于上述情况。插入查询打印为

 INSERT INTO table (id, state_id, sell_id) VALUES (1, '', '') , (2, '', '')

但我希望它像

 INSERT INTO table (id, state_id, sell_id) VALUES (1, NULL, NULL) , (2, NULL, NULL)

任何机构都可以告诉我如何在我的场景中实现这一目标。

【问题讨论】:

    标签: php mysql database


    【解决方案1】:

    这可以通过单个查询轻松完成:

    INSERT INTO newtable (newfield1, newfield2, etc...)
        SELECT oldfield1, IF(oldfield2="", NULL, oldfield2), etc...
        FROM oldtable
    

    select 可以即时更正/调整任何字段值。

    请注意,您的版本容易受到sql injection attacks 的攻击。您正在处理的数据在几毫秒前从数据库中出来并不重要 - 它仍然是未引用/未转义的数据,并且可以/将会破坏您的插入查询。

    【讨论】:

    • 感谢您的回答。它的数据库非常大,我不知道每个表的确切列名。所以我不能为每一列检查IF(oldfield2="", NULL, oldfield2),也不知道列。它是可以在任何数据库上运行的通用脚本。那么还有其他解决方案吗?
    • 我需要为每个表的数百万条记录运行此脚本,并且几乎有 150 到 170 个表,因此从性能角度来看,一百万次插入查询将是灾难。我试图通过值()、()、()对每个表进行一个插入查询来减少时间。所以这不能按照你的建议实现
    【解决方案2】:

    首先,如果我需要移动一些数据,我只通过像@MarcB 提到他的答案这样的 SQL 来执行此操作,但如果你坚持你的方法,我认为你需要更改以下行

    return $v == '' ? NULL : $v;
    

    return $v == '' ? 'NULL' : $v;
    

    通过此更改,您的数组的 null 元素将变为 php 的字符串 'NULL',因此当它们内爆时,它们不会转换为 '' 空字符串,它们仍将保持为字符串 NULL,因此它们将在您的插入 SQL 中显示为 NULL

    【讨论】:

    • 'NULL' 将变成字符串 Dear :)
    • 你能试试这个内爆代码吗:$a = array(1,2,3,"Null","Null");echo implode(",", $a);如果你不在内爆胶中使用',它会修复它
    猜你喜欢
    • 2011-11-07
    • 2012-09-15
    • 2011-04-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-20
    • 2012-11-20
    相关资源
    最近更新 更多