【问题标题】:SQL - IF EXISTS UPDATE ELSE INSERT INTOSQL - 如果存在更新 ELSE INSERT INTO
【发布时间】:2013-03-01 07:14:13
【问题描述】:

我正在尝试做的是INSERT 我的数据库中的订阅者,但IF EXISTS 它应该UPDATE 行,ELSE INSERT INTO 一个新行。

当然我首先连接到数据库,然后GET$name$email$birthday 来自 url 字符串。

$con=mysqli_connect("localhost","---","---","---");
// Check connection
if (mysqli_connect_errno())
  {
  echo "Failed to connect to MySQL: " . mysqli_connect_error();
  }

$name=$_GET['name']; 
$email=$_GET['email'];
$birthday=$_GET['birthday'];

这可行,但只是添加新行;

mysqli_query($con,"INSERT INTO subs (subs_name, subs_email, subs_birthday)
VALUES ('$name', '$email', '$birthday')");

mysqli_close($con);

这是我尝试过的;

mysqli_query($con,"INSERT INTO subs (subs_name, subs_email, subs_birthday)
VALUES '$name', '$email', '$birthday'
ON DUPLICATE KEY UPDATE subs_name = VALUES($name), subs_birthday = VALUES($birthday)");
mysqli_close($con);

mysqli_query($con,"IF EXISTS (SELECT * FROM subs WHERE subs_email='$email')
    UPDATE subs SET subs_name='$name', subs_birthday='$birthday' WHERE subs_email='$email'
ELSE
    INSERT INTO subs (subs_name, subs_email, subs_birthday) VALUES ('$name', '$email', '$birthday')");
mysqli_close($con);

mysqli_query($con,"IF NOT EXISTS(SELECT * FROM subs WHERE subs_email='$email')
Begin
INSERT INTO subs (subs_name, subs_email, subs_birthday)
VALUES ('$name', '$email', '$birthday')
End");
mysqli_close($con);

但是它们都不起作用,我做错了什么?

非常感谢任何帮助!

【问题讨论】:

标签: mysql sql insert exists


【解决方案1】:
  1. 在您的 subs_email 列上创建一个 UNIQUE constraint(如果尚不存在):

    ALTER TABLE subs ADD UNIQUE (subs_email)
    
  2. 使用INSERT ... ON DUPLICATE KEY UPDATE:

    INSERT INTO subs
      (subs_name, subs_email, subs_birthday)
    VALUES
      (?, ?, ?)
    ON DUPLICATE KEY UPDATE
      subs_name     = VALUES(subs_name),
      subs_birthday = VALUES(subs_birthday)
    

您可以在 UPDATE 子句中使用 VALUES(col_name) 函数来 引用来自 INSERT ... ON 的 INSERT 部分的列值 重复密钥更新 - dev.mysql.com

  1. 请注意,我使用参数占位符代替字符串文字,因为一个真的应该使用参数化语句来defend against SQL injection attacks

【讨论】:

  • 你个大男人!就像一个魅力,现在找到一种方法来保护它免受注射。在人们确认订阅时事通讯后,我将数据发送到数据库,并将参数发布在字符串中。知道如何确保这一点吗?谢谢
  • @RehbanKhatri:哦,对不起,我以为你的意思是在VALUES() 子句中。 VALUES() 函数只获取您希望使用的来自VALUES() 子句的值的列的名称:它只是防止您重复自己的简写;你不必使用它。如果需要,您可以直接在 SET 子句中使用您的函数,例如 SET column = MYFUNCTION()
  • 嗯,有道理,我刚读过一篇关于这个的文章,可能文章有误。 percona.com/blog/2010/07/14/…
  • @amdev:那是一篇有趣的文章,深入研究了一些我不知道的 MySQL 存储引擎 API 的非常低级的细节——所以感谢你让我跟上进度。但是,我仍然希望尽可能清楚地表达我想要的逻辑,以帮助未来的可维护性:只有当上面提到的其他问题碰巧不相关并且它会造成重大性能影响时,我才会当我真的打算更新时,考虑切换到REPLACE。记住 Knuth 的格言:“过早的优化是万恶之源”
  • @joseph: "对于ON DUPLICATE KEY UPDATE,如果将行作为新行插入,则每行的受影响行值为 1,如果更新现有行,则为 2,如果更新则为 0现有行设置为其当前值。"
【解决方案2】:

试试这个:

INSERT INTO `center_course_fee` (`fk_course_id`,`fk_center_code`,`course_fee`) VALUES ('69', '4920153', '6000') ON DUPLICATE KEY UPDATE `course_fee` = '6000';

【讨论】:

  • 此 SQL 脚本包含与 OP 架构无关的表/列
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-11-21
  • 2019-02-19
  • 1970-01-01
  • 2023-02-09
  • 2014-04-22
  • 2012-06-01
  • 1970-01-01
相关资源
最近更新 更多