SQL-如果存在,则将更新插入其他


77

我想要做的就是INSERT在我的数据库的用户,但IF EXISTS它应该UPDATE排,ELSE INSERT INTO一个新行。

Ofcourse我连接到数据库第一和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);

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

任何帮助是极大的赞赏!


2
您的餐桌上有独特的约束吗?
John Woo 2013年

Answers:


196
  1. 如果不存在UNIQUE约束,请在您的subs_email列上创建约束

    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的INSERT部分中的列值。... ON DUPLICATE KEY UPDATE-dev.mysql.com

  1. 请注意,我已经使用参数占位符代替字符串文字,因为实际上应该使用参数化语句来防御SQL注入攻击

你这个家伙!就像魅力一样工作,现在可以找到一种方法来防止这种情况的发生。人们确认订阅了新闻通讯后,我会将数据发送到数据库,并将参数发布在字符串中。任何想法如何确保这一点?Thnx
Laurence Cooper

1
@RehbanKhatri:抱歉,我认为您的意思是该VALUES()条款。该VALUES()函数只是采用VALUES()您希望使用的子句中其值的列名:它只是防止您重复自己的简写;您不必使用它。您可以根据需要直接在SET子句中使用函数,例如SET column = MYFUNCTION()
eggyal

1
嗯,有道理,我刚刚读了一篇有关的文章,也许这篇文章是错误的。percona.com/blog/2010/07/14/...
amdev

1
@amdev:这是一篇有趣的文章,深入研究了我不知道的MySQL存储引擎API的一些非常底层的细节,因此感谢您使我快速入门。但是,我仍然希望尽可能清楚地表达我想要的逻辑,以帮助将来的可维护性:只有当上述其他问题不相关并且造成重大性能影响REPLACE时,我才考虑切换到我真正打算的时候更新。请记住Knuth的格言:“过早的优化是万恶之源”
eggyal

3
@joseph:“使用ON DUPLICATE KEY UPDATE,如果该行作为新行插入,则每行的受影响行值为1;如果更新了现有行,则为2;如果将现有行设置为其当前值
则为0。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.