高级MySQL查询,选择,计数,插入或更新

时间:2014-08-01 09:53:46

标签: mysql

所以,我有一个查询,它需要做的是什么;

  • 检查会话表中是否存在令牌
  • 如果没有在表中插入令牌
  • 否则请更新表格中的令牌

SELECT COUNT(token) AS founds FROM sessions WHERE token = '" . $_SESSION['prevToken'] . "'
CASE WHEN founds == 0 THEN
    INSERT INTO sessions(token, cookie, expire)
    VALUES('" . $token . "', '', NOW() + INTERVAL 1 HOUR))
ELSE 
    UPDATE sessions SET token = '" . $token . "', expire = NOW() + INTERVAL 1 HOUR)
    WHERE  token = '" . $_SESSION['prevToken'] . "'
END CASE

但是我收到了这个错误:

You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'CASE WHEN founds == 0 THEN INSE' at line 2

我不知道什么是错的? CASE语法应该是正确的,但它不是<?p?

4 个答案:

答案 0 :(得分:1)

您正在使用CASE WHEN..,就像它是一个控制结构一样。事实并非如此。它用于查询。除此之外,您不能在查询中使用ifwhile等控制结构,这些只能在存储过程或函数中使用。

select查询后,您也没有分隔符。

ClémentMalet的回答是正确的,==在MySQL中没有使用。

最好的解决方案确实是在LHristov的回答中使用INSERT ... ON DUPLICATE KEY UPDATE

除此之外,只是为了完整性,以下是正确的存储过程的样子:

DELIMITER $$
CREATE PROCEDURE insert_or_update(IN p_prev_token varchar(255), IN p_token varchar(255))
BEGIN
  IF EXISTS( SELECT 1 FROM sessions WHERE token = p_prev_token ) THEN
    UPDATE sessions SET token = p_token, expire = NOW() + INTERVAL 1 HOUR)
    WHERE  token = p_prev_token;
  ELSE
    INSERT INTO sessions(token, cookie, expire)
    VALUES(p_token, '', NOW() + INTERVAL 1 HOUR));
  END IF;
END $$
DELIMITER ;

然后你会用这样的东西调用它(我不是PHP程序员,因此我不知道如何逃避变量或其他):

CALL insert_or_update($_SESSION['prevToken'], $token);

P.S。:一般情况下,当您需要知道的时候,COUNT()是否有条目。一旦找到第一个条目,EXISTS()就会停止,而COUNT()会继续扫描该表。

答案 1 :(得分:0)

所以你需要INSERT ... ON DUPLICATE KEY UPDATE。从documentation

获取一些信息

答案 2 :(得分:0)

您无法使用&#39; ==&#39;在MySQL中。

WHEN founds == 0替换为WHEN founds = 0

答案 3 :(得分:0)

您也可以使用

ON DUPLICATE KEY UPDATE

而不是用例。例如:

INSERT INTO table (a,b,c) VALUES (1,2,3)
  ON DUPLICATE KEY UPDATE c=c+1;