2017-02-17 213 views
1

我一直在建立一个论坛或博客,如果你愿意为我的PHP和MySQL的网络组合。我对PHP相当不错,但MySQL一直是我的问题,因为在此之前我从来没有理由使用MySQL或任何数据库,而不是MySQL错误消息是我看到的最差的错误。这是我试图用来添加新的帖子到论坛/博客的事情的查询。在MySQL中使用Declare

START TRANSACTION; 

DECLARE postKey int; 

INSERT INTO posts(post_subject, post_content, post_date, post_by) 
SELECT ?, ?, NOW(), user_id FROM users WHERE user_name = ? LIMIT 1; 

SET postKey = LAST_INSERT_ID(); 

INSERT INTO juct_tags_posts(post_key, tag_key) 
SELECT postKey, tag_id FROM tags WHERE tag_name = ? LIMIT 1; 
INSERT INTO juct_tags_posts(post_key, tag_key) 
SELECT postKey, tag_id FROM tags WHERE tag_name = ? LIMIT 1; 
INSERT INTO juct_tags_posts(post_key, tag_key) 
SELECT postKey, tag_id FROM tags WHERE tag_name = ? LIMIT 1; 

COMMIT; 

第一插入是post_data。接下来的三个插入到tag_id和post_id的联结表中。问题是这样的。 Prepare failed: (1064) 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 'DECLARE postKey int;INSERT INTO posts(post_subject, post_content, post_date, pos' at line 1我不知道是什么导致了这个问题。此外,如果这有助于查询时将其设置为像这样的字符串。

START TRANSACTION;DECLARE postKey int;INSERT INTO posts(post_subject, post_content, post_date, post_by) SELECT ?, ?, NOW(), user_id FROM users WHERE user_name = ? LIMIT 1;SET postKey = LAST_INSERT_ID();INSERT INTO juct_tags_posts(post_key, tag_key) SELECT postKey, tag_id FROM tags WHERE tag_name = ? LIMIT 1;INSERT INTO juct_tags_posts(post_key, tag_key) SELECT postKey, tag_id FROM tags WHERE tag_name = ? LIMIT 1;INSERT INTO juct_tags_posts(post_key, tag_key) SELECT postKey, tag_id FROM tags WHERE tag_name = ? LIMIT 1;COMMIT; 
+0

查看本问题解答http://stackoverflow.com/q/9974325/1415724和mysql.com网站上的相关链接https://dev.mysql.com/doc/refman/5.7/en/commit.html - - https://dev.mysql.com/doc/refman/5.7/en/declare-handler.html –

+0

非常感谢。我只知道关于declare关键字的更多信息。我虽然只是一个用来在事务中声明变量的关键字,但我离开了,而且还有更多。我一直在看sql全错了,看到它更像dos,更不像编程语言。 –

+0

不客气杰夫。 –

回答

0

我已经厌倦了过去几天,所以我也没有做太多的编码,但我花时间从我的电脑了解更多MySQL和跨解决方案附带的解决了这个问题。使用的主表是:

Posts (post_id int(11), post_subject varchar(255), post_content text, post_date datetime, fk_post_by int(11)) 
Tags (tag_id int(11), tag_name varchar(255)) 
Junction_Posts_Tags(junc_id int(11), fk_post_id int(11), fk_tag_id int(11)) 

我的新解决方案使用2个'存储过程'和一个完成的重做事务。

添加新行发布的表存储过程

addPost(IN msg text, IN sub varchar(255), IN poster varchar(255), OUT post int) 
BEGIN 
INSERT INTO posts(post_content, post_subject, post_date, post_by) 
SELECT msg, sub, NOW(), user_id 
FROM users 
WHERE user_name = poster; 
SET post = LAST_INSERT_ID(); 
END 

的标签表包含预定义的价值,我不希望允许用户添加新的标签。用户可以为一个帖子选择多个标签,因此需要联结表。这是为联结表添加行的存储过程。

addPostTag(IN tag varchar(255), IN post int) 
BEGIN 
INSERT INTO juct_tags_posts(post_key, tag_key) 
SELECT post_id, 
(SELECT tag_id 
FROM tags 
WHERE tag_name = tag) 
FROM posts 
WHERE post_id = post; 
END 

这两个过程都没有做虽然,我还是想加入错误处理,一旦我已经制定了DECLARE action HANDLER condition声明。 我在PHP中使用的SQL语句现在分成三部分。

set AUTOCOMMIT = 0; 
START TRANSACTION; 
CALL addPost(?,?,?, @post_id); 

这将开始交易,并为在内存中邮表中的行。接下来是

CALL addPostTag(?, @post_id); 

我为用户选择的每个标签运行此sql。我尝试将@post_id作为别名存储,但当我在过程调用中使用它时,我一直收到错误。然后,如果没有错误返回,我将这一切都提交。

COMMIT; 

我张贴了这个答案,因为我没有找到任何解决方案,以这种特定情况下,当我提出的问题。希望它能帮助某人,并再次感谢Fred -ii-的帮助。