繁体   English   中英

如何一次轻松地插入或更新或删除记录

[英]How to insert or update or delete a record easy at once

我创建了一张桌子

CREATE TABLE `pledge` (
  `ID` INT(11) NOT NULL AUTO_INCREMENT,
  `user` VARCHAR(45) NOT NULL,
  `location` VARCHAR(45) NOT NULL,
  `category` VARCHAR(45) NOT NULL,
  `amount` DOUBLE NULL, NOT NULL,
  `p_created` TIMESTAMP NOT NULL,
  PRIMARY KEY (`ID`));

我为用户,位置和类别添加了唯一键作为index2。

我想要

INSERT a new record, if amount is not zero
UPDATE an existing record, if key (column user, location, category) exists
DELETE a record, if key (column user, location, category) exists AND amount is now zero



try {
  $conec = new Connection();
  $con = $conec->Open();
  $p_created = date("Y-m-d H:i:s");
  $sql = "INSERT INTO `pledge`(
    `user`,
    `location`,
    `category`,
    `amount`,
    `p_created`)
    VALUES (
    :user,
    :location,
    :category,
    :amount,
    :p_created)";

  $pre = $con->prepare($sql, array(PDO::ATTR_CURSOR => PDO::CURSOR_FWDONLY));
  if ($pre->execute(array(
    ':user' => $user,
    ':location' => $location,
    ':category' => $category,
    ':amount' => $amount,
    ':p_created' => $p_created,
  ))) {
//      echo "Successful";
    }
  } catch (PDOException $ex) {
    echo $ex->getMessage();
  }
} // try

我发现我可以使用“ ON DUPLICATE KEY UPDATE col3 ='alpha';”之类的东西,但是不知道上面的php代码中的用法。 既然存在,那么如果数量为零,也有可能删除而不是更新。

更新:

谢谢罗比的提示。 不知何故,我仍然会犯错误。 我尝试了很多方法,但是...

首先,我不得不换桌子。 我删除了主键ID,并添加了一个新的主键,其中包含用户,位置,类别列。

为了简化我的原始问题,我仅更新了一列,但实际上更新了两列。

与该改变我能够插入/更新我打算在命令行(工作台)上:INSERT INTO pledgeuserlocationcategorymypercentmybalancep_created )VALUES( '5cdae45bdb5c5', '林茨', 'A14' ,50,300,'2019-05-21 11:12:22')在重复键更新上mypercent = 20, mybalance = 53;

可以正常工作。 第一次将其插入mypercent = 50和mybalance = 300,第二次尝试使用完全相同的命令时,我将记录更新为mypercent = 20和mybalance = 53

但是,我无法在我的PHP程序中使用此语法。 这是最新的尝试:

try {

    $conec = new Connection();
    $con = $conec->Open();

    $p_created = date("Y-m-d H:i:s");
    $sql = "INSERT INTO `pledge`(
            `user`,
            `location`,
            `category`,
            `mypercent`,
            `mybalance`,
            `p_created`)
            VALUES (
            :user,
            :location,
            :category,
            :mypercent,
            :mybalance,
            :p_created)
            ON DUPLICATE KEY UPDATE (`mypercent` = $percent[0], `mybalance` = $balance[0])
            ";
// worked on command line: UPDATE `pledge` SET `mypercent`='10',`mybalance`='10' WHERE `user`='5ce3770041037' and `location`='Linz' and`category`='A14';
// ON DUPLICATE KEY UPDATE `p_mypercent`=20, `mybalance` = 53;

    $pre = $con->prepare($sql, array(PDO::ATTR_CURSOR => PDO::CURSOR_FWDONLY));
    if ($pre->execute(array(
       ':user' => $user,
       ':location' => $locationid,
       ':category' => $category,
       ':mypercent' => $percent[0],
       ':mybalance' => $balance[0],
       ':p_created' => $p_created,
    ))) {
//      echo "Successful";
    } // if ($pre->execute(array(
   } catch (PDOException $ex) {
    echo $ex->getMessage();
} // try

这给了我一个语法错误:SQLSTATE [42000]:语法错误或访问冲突:1064您的SQL语法有错误;请参见语法错误。 检查与您的MariaDB服务器版本相对应的手册,以在第17行的'( mypercent = 10, mybalance = 10) mypercent ,'附近使用正确的语法

有几个选项,每个都有优点和缺点

1)最简单,正如尼克所说的,评论是两个写三个查询。 不要这样做-如果您同时有多个呼叫,那么另一个用户可能会尝试在读取和写入之间更新同一记录。

1b)如果您坚持使用此方法,则可以使用事务。 https://dev.mysql.com/doc/refman/8.0/zh-CN/commit.html但是,您需要处理交易存在风险,并且此操作有点过头。

2)第二个最简单的方法(也是我要做的一个)是按照问题中的建议进行“ ON DUPLICATE KEY”操作,然后执行第二个操作以“如果为零则删除”。 这样,即使两个事件重叠,它们实际上也将阻止彼此删除记录,或者两者都更新同一条记录。

重要说明1:您需要在user上具有UNIQUE索引才能起作用。 或删除“ id”作为字段,并使用“ user”作为主键。

重要说明2:您缺少的是在SQL中进行数学运算:

$sql = "INSERT INTO `pledge`(`user`, `location`, `category`, `amount`, `p_created`)
    VALUES (:user, :location, :category, :amount, :p_created)
    ON DUPLICATE KEY UPDATE `amount`=`amount`-VALUES(amount)";

表示如果不存在,则插入金额,否则,进行匹配并更新记录。

然后一个单独的查询

$sql = "DELETE FROM `pledge` WHERE `user`=:user AND `amount`=0";

(不需要“ user = 0”,但是当您为用户建立索引时,就没有“ amount”上的索引,它将更快。您可以使用$sql = "DELETE FROM pledge WHERE=0";)

3)最理想的方法是在数据库内部使用触发器。 您可以告诉SQL Server“如果数量为零,则删除”。 或将它们全部混合在一个存储过程中,但它们都太过分了。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM