0

我已经对此进行了多次审查,但找不到它不应该起作用的原因,希望有人可以揭示我所缺少的内容,这是我准备好的声明。

在初始化准备好的语句后直接执行var_dumpon时$query,它返回 false。

$query = $link->prepare("IF (EXISTS(SELECT * FROM banned WHERE ipAddr=? OR uid=?)) THEN UPDATE banned SET isBanned='1', ipAddr=?, uid=?, bannedAt=NOW(), reason=? WHERE ipAddr=? OR uid=? ELSE INSERT INTO banned (isBanned, ipAddr, uid, bannedAt, reason) VALUES('1', ?, ?, NOW(), ?) END IF");
$query->bind_param("sisissisis", $details['IP'], $details['uid'], $details['IP'], $details['uid'], $details['reason'], $details['IP'], $details['uid'], $details['IP'], $details['uid'], $details['reason']);

表结构

banned
------
id,  uid, ipAddr, bannedAt, reason, isBanned

注意:如果这不是达到相同结果的最佳方法,请提供建议

4

3 回答 3

1

IFMysql 中的预处理语句不支持该语句。有关受支持语句的完整列表和更多信息,请阅读SQL Syntax for Prepared Statements

恕我直言,您有多种选择

  1. 尝试使用INSERT INTO ... ON DUPLICATE KEY UPDATEREPLACE。你需要有正确的UNIQUE索引(索引)。
  2. 将代码包装到存储过程中

存储过程可能看起来像

DELIMITER $$
CREATE PROCEDURE sp_add_banned(IN aIP VARCHAR(15), IN aId INT, aReason VARCHAR(100))
BEGIN
  IF (EXISTS(SELECT * FROM banned WHERE ipAddr=aIP OR uid=aId)) THEN 
      UPDATE banned 
         SET isBanned='1', ipAddr=aIP, uid=aId, bannedAt=NOW(), reason=aReason 
       WHERE ipAddr=aIP OR uid=aId;
  ELSE 
      INSERT INTO banned (isBanned, ipAddr, uid, bannedAt, reason) 
      VALUES('1', aIP, aId, NOW(), aReason);
  END IF;
END$$
DELIMITER ;

调整表中IN定义的参数的数据类型banned

这是SQLFiddle演示。

你的 php 部分看起来像

$query = $link->prepare('CALL sp_add_banned(?, ?, ?)');
$query->bind_param('sis', $details['IP'], $details['uid'], $details['reason']);
于 2013-05-27T04:25:02.793 回答
1

MySQL

如果存在

语法仅适用于存储过程。

您可以创建一个存储过程,然后从您的代码中调用它以进行验证和插入或更新。

供您参考:mySql If 语法

如果您在 SELECT 查询上使用 'IF' 函数,它有不同的语法。这是链接

于 2013-05-27T04:23:20.983 回答
0

您可以使用ON DUPLICATE语法。

这是文档:http ://dev.mysql.com/doc/refman/5.0/en/insert-on-duplicate.html

于 2013-05-27T04:24:21.250 回答