2017-06-03 105 views
0

我写此查询,但我得到了以下错误:为什么这个SQL查询不起作用?

Fatal error: Uncaught exception 'PDOException' with message 'SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'BEGIN INSERT INTO forum_topics_track (userid , topic_id , `c' at line 3

我想这是自我解释,但我的目标是检查记录存在,如果没有,将其插入。

IF NOT EXISTS 
       (SELECT * FROM `forum_topics_track` WHERE `userid` = '{$userid}' AND `topic_id` = '{$topic_id}') 
      BEGIN 
       INSERT INTO `forum_topics_track` (`userid`, `topic_id`, `category_id`) 
       VALUES ('{$topic_id}', '{$category_id}', '{$userid}') 
      END; 
+1

没有必要先检查任何东西。事实上,这完全适得其反。 – Strawberry

回答

1

更快的替代方案将是对useridtopic_id唯一索引。

CREATE UNIQUE INDEX forum_topics_track_ndx ON forum_topics_track(userid, topic_id); 

那么你可以做

INSERT IGNORE INTO `forum_topics_track` (`userid`, `topic_id`, `category_id`) 
      VALUES ('{$topic_id}', '{$category_id}', '{$userid}'); 

这将总是成功(可能什么都不做,如果数据已经存在)。

或者你可以看看ON DUPLICATE KEY UPDATE的诡计。

+0

是的,这是我尝试的第一件事,它的工作。谢谢你,并回答我的问题。 – user3628807

1

这是实施逻辑的错误方法。如果您希望每个用户和主题都出现在forum_topics_track中,那么请让数据库强制执行约束。这是很容易具有唯一索引或约束:

create unique index unq_forum_topics_track_user_topic on forum_topics_track(user_id, topic_id); 

然后,你可以做一个插入,而忽略或处理错误:

INSERT INTO `forum_topics_track` (`userid`, `topic_id`, `category_id`) 
    VALUES ('{$topic_id}', '{$category_id}', '{$userid}') 
    ON DUPLICATE KEY UPDATE userid = VALUES(userid); 

没有IF需要在逻辑。事实上,使用IF只是由于竞争条件而引发问题,并不能保证数据库中的任何内容。

0

IF NOT EXISTS是一个可用于MS-SQL但不在MySQL中的子句。请尝试以下查询。

INSERT INTO `forum_topics_track` (`userid`, `topic_id`, `category_id`) 
SELECT '{$topic_id}', '{$category_id}', '{$userid}' 
WHERE NOT EXISTS(
    SELECT * FROM `forum_topics_track` WHERE `userid` = '{$userid}' AND `topic_id` = '{$topic_id}' 
) 
+0

如果没有FROM子句,则不能使用WHERE子句。但是你可以在FROM子句中用子查询修复它。 –

+0

嗨保罗,我测试了这个查询,它工作正常。 FROM子句将仅在我尝试运行以下部分查询时才需要。 SELECT'{$ topic_id}','{$ category_id}','{$ userid}' WHERE NOT EXISTS( SELECT * FROM'forum_topics_track' where'userid' ='{$ userid}'AND'topic_id' ='{$ topic_id}' ) –

+0

我在http://rextester.com(它正在运行MySQL 5.7)上测试它,令我惊讶的是它工作。然而,它不适用于我的本地MariaDB 10.0.19。我很确定它在MySQL 5.6上也不起作用,但我没有安装在这里测试。如果你看看[documentation](https://dev.mysql.com/doc/refman/5.7/en/select.html),你会发现,没有'FROM'就没有'WHERE':'* * [** FROM table_references [PARTITION partition_list] [WHERE where_condition] ... **] **“。所以,虽然它在MySQL 5.7上工作 - 这种行为没有记录。 –