2017-06-03 70 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上工作 - 這種行爲沒有記錄。 –