【问题标题】:Add or update MySQL添加或更新 MySQL
【发布时间】:2013-09-25 21:07:25
【问题描述】:

我不知道如何在我的特定桌子上继续执行以下操作。

假设我有以下 table param,有 3 列 tcklabelvaluetck 是我的主键。

数据每天来一次。我想更新现有tck的值,如果发送的数据包含新的tck,我想将其添加到表中...

我希望我已经足够清楚了...感谢您的帮助。

我使用的代码如下:

<?php try {
    $bdd = new PDO('mysql:host='.$_ENV['localhost'].';dbname=eip_tasks','root'); } catch(Exception $e) {
    die('Erreur : '.$e->getMessage()); }

$data = $_POST['field1'];

$phpArray = json_decode($data, true); foreach ($phpArray as $u) {  
        //$req = $bdd->prepare('INSERT INTO param (tck, label, value) VALUES(:tck, :label, :value)');
        $req = $bdd->prepare('UPDATE param SET value=:value WHERE tck=:tck');
        $req->execute(array(
            ':tck'=>$u['tck'],
            ':value'=>$u['value']
        )); } ?>

这是我现在使用的代码:

<?php
try
{
    $bdd = new PDO('mysql:host='.$_ENV['localhost'].';dbname=eip_tasks','root');
}
catch(Exception $e)
{
    die('Erreur : '.$e->getMessage());
}

$data = $_POST['field1'];
$phpArray = json_decode($data, true);

$sourceTck = array();
foreach ($phpArray as $u) {array_push($sourceTck, $u['tck']);
    $req = $bdd->prepare("INSERT INTO param (tck, label, value) VALUES (:tck, :label, :value) ON DUPLICATE KEY UPDATE value=:value");
    $req->execute(
        array(
            ':tck'=>$u['tck'],
            ':label'=>$u['label'],
            ':value'=>$u['value']
        )
    );
}

if(count($sourceTck) > 0){
    $sourceTckClause = implode("," , $sourceTck);
    $req = $bdd->prepare("DELETE FROM param WHERE tck NOT IN ($sourceTckClause)");
    $req->execute(); 
}


?>

【问题讨论】:

标签: mysql insert-update


【解决方案1】:

使用ON DUPLICATE KEY 语法来update 行而不是insert(如果存在tck):

$req = $bdd->prepare("
    INSERT INTO param (tck, label, value) 
        VALUES 
    (:tck, :label, :value)
    ON DUPLICATE KEY UPDATE value=:value
");

更新:别忘了绑定:label。作为您的评论,要删除表中而不是源中的数据,您应该将源 tck 值推送到数组,然后运行删除查询 NOT IN 您的数组:

$sourceTck = array();
foreach ($phpArray as $u) {
    array_push($sourceTck, $u['tck']);
    $req = $bdd->prepare("
        INSERT INTO param (tck, label, value)
            VALUES
        (:tck, :label, :value)
        ON DUPLICATE KEY UPDATE value=:value
    ");
    $req->execute(
        array(':tck'=>$u['tck'], ':label'=>$u['label'], ':value'=>$u['value'])
    );
}

我发现this answer 对准备和绑定tck 值很有用,但是对于小型解决方案,您可以将数组值转换为int 以防止这种情况下的sql注入:

if(count($sourceTck) > 0){
    $sourceTckClause = implode("," , array_map('intval', $sourceTck));
    $bdd->query("DELETE FROM param WHERE tck NOT IN ($sourceTckClause)");
}

【讨论】:

  • 它工作得很好,但是我该怎么做才能删除表中而不是源中的数据?我的意思是完全同步...我够清楚了吗?
  • @Henri 我添加了更多信息。
  • 它不工作,我无法确定为什么......?当从源中删除数据时,该行保留在表中...
  • 对不起,没有错误,也没有例外......我将使用我粘贴的代码编辑我的问题
【解决方案2】:

您想要做的称为 upsert 或合并。 MySQL 确实支持它。

INSERT INTO param VALUES (:tck, :label, :value)
ON DUPLICATE KEY UPDATE value = :value
-- change :label as well? , label = :label

【讨论】:

    猜你喜欢
    • 2020-10-19
    • 2014-04-12
    • 2021-11-11
    • 2017-05-28
    • 1970-01-01
    • 1970-01-01
    • 2012-02-06
    • 2018-11-22
    • 1970-01-01
    相关资源
    最近更新 更多