【问题标题】:MySQL insert only if not exist in two tablesMySQL 仅在两个表中不存在时才插入
【发布时间】:2015-03-15 21:46:13
【问题描述】:

我对 MySQL 查询有一点问题。我正在使用 PDO 查询,现在它只是将值插入到表中(见下文):

$stmt = $dbh -> prepare("INSERT INTO tmp (user_id, test_id, question_id, answer_id) VALUES (?, ?, ?, ?)");
$stmt -> bindParam(1, $_SESSION['UserID']); // binds parameter for user id
$stmt -> bindParam(2, $_GET['start_test']); // binds parameter for test id
$stmt -> bindParam(3, $_POST['question']); // binds parameter for selected answer
$stmt -> bindParam(4, $_POST['select_answer']); // binds parameter for selected answer
$stmt -> execute();

tmp表结构如下:

CREATE TABLE IF NOT EXISTS `tmp` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `test_id` int(11) NOT NULL,
  `user_id` int(11) NOT NULL,
  `question_id` int(11) NOT NULL,
  `answer_id` int(11) NOT NULL,
  PRIMARY KEY (`id`)
)

如果answer_id 值不存在,我想插入它并同时检查 user_id 是否存在,否则只需更新,例如:

我有两个 user_id=1 和 user_id=2 的用户,他们分别回答每个学生商店的问题和每个答案。 User_id=1 选择 answer_id = 3 和 user_id=2 选择 answer_id = 3。但是,一个用户意识到这是一个错误的答案并想要将其更改为另一个(假设 answer_id=2),我希望查询更新当前answer_id=3 WHERE user_id=1 到 answer_id=2

【问题讨论】:

    标签: php jquery mysql sql mysqli


    【解决方案1】:

    您可以为相同的内容创建一个INSERT IGNORE,这看起来更简单,并且在某些问题上是原子性的。

    步子像

    1. 在 (user_id,question_id, answer_id) 上创建唯一索引

      ALTER TABLE tmp 添加索引 user_qn_ans_idx(user_id,question_id, answer_id);

    2. 现在只需执行插入操作,可能还会更新重复键

      插入到 tmp (user_id,question_id, answer_id) 值 (, , ) 重复键更新 answer_id = VALUES(answer_id)

    【讨论】:

      【解决方案2】:

      添加一个选择计数并执行以下条件:

      $stmt = $dbh->prepare("SELECT count( 1 ) FROM tmp WHERE user_id = :user_id AND question_id = :question_id and answer_id = :answer_id");
      $stmt->bindValue( 'user_id', 1 );
      $stmt->bindValue( 'question_id', 1 );
      $stmt->bindValue( 'answer', 1 );
      $stmt->execute();
      $oExists = $stmt ->fetch();
      if( !empty( $oExists ) )
      {
      // Run update sql...
      }
      else
      {
      // Run insert sql...
      

      【讨论】:

      • 在这里我做了一些更改看看我将代码更改为您建议的方式,但现在它总是更新并且由于某种原因没有插入新行..
      【解决方案3】:

      $stmt = $dbh->prepare("SELECT count( 1 ) FROM tmp WHERE user_id = :user_id AND question_id = :question_id AND answer_id = :answer_id");
      $stmt->bindValue( 'user_id', 1 );
      $stmt->bindValue( 'question_id', 1 );
      $stmt->bindValue( 'answer_id', 1 );
      $stmt->execute();
      $oExists = $stmt ->fetch();
      	if( !empty( $oExists ) ) {
      	 echo "update";
      	$stmt = $dbh->prepare("UPDATE tmp SET answer_id = :answer_id WHERE user_id = {$_SESSION['UserID']} AND question_id = {$_POST['question']}"); //updates the counter each time test created                                 
      	$stmt -> bindParam(':answer_id', $_POST['select_answer'], PDO::PARAM_INT);
      	$stmt -> execute();
      	} else {
      	echo "insert";	
      	$stmt = $dbh -> prepare("INSERT INTO tmp (user_id, test_id, question_id, answer_id) VALUES (?, ?, ?, ?)");
      	$stmt -> bindParam(1, $_SESSION['UserID']); // binds parameter for user id
      	$stmt -> bindParam(2, $_GET['start_test']); // binds parameter for test id
      	$stmt -> bindParam(3, $_POST['question']); // binds parameter for selected answer
      	$stmt -> bindParam(4, $_POST['select_answer']); // binds parameter for selected answer
      	$stmt -> execute();
      	}

      这里总是更新,但不是插入..

      【讨论】:

      • 那是因为它总是选择 user_id 为 1、question_id 为 1 和 answer_id 为 1。您需要每次传递这些值以使其动态 $stmt->bindValue('user_id' , $_SESSION['UserID'] ); $stmt->bindValue('question_id', $_POST['question']); $stmt->bindValue('answer_id', $_POST['select_answer'] );
      猜你喜欢
      • 1970-01-01
      • 2013-04-28
      • 1970-01-01
      • 2011-03-25
      • 1970-01-01
      • 1970-01-01
      • 2018-01-17
      • 1970-01-01
      相关资源
      最近更新 更多