简体   繁体   English

MySQL程序返回错误的值(INSERT SELECT面对)

[英]MySQL procedure returning wrong value (INSERT SELECT confronting)

I'm completely new to MySQL, and have been bumping with some errors, but always I do find solutions, except for this one I can't understand how to get around it. 我是MySQL的新手,并且遇到了一些错误,但我总能找到解决方案,除了这个我无法理解如何绕过它。

The following MySQL Procedure returns me a value if variable "ue" is 1 or 0 (a bunch of exists validation). 如果变量“ue”为1或0(一堆存在的验证),则以下MySQL Procedure返回一个值。 The validation part (SET ue = EXISTS...) works without the rest of the code, as it should, the problem is not there. 验证部分(SET ue = EXISTS ...)在没有其余代码的情况下工作,因为它应该没有问题。 But when I do execute the command INSERT INTO SELECT, it does not work, it always return 0 as response, when it should be 1. These two lines are getting in confrontation with each other. 但是当我执行命令INSERT INTO SELECT时,它不起作用,它总是返回0作为响应,当它应该是1.这两行正在相互对抗。

INSERT INTO meetup_participation SELECT user_id, event_id FROM DUAL WHERE ue=1; INSERT INTO meetup_participation SELECT user_id,event_id FROM DUAL WHERE ue = 1;

SELECT ue AS response; SELECT ue AS响应;

The procedure should add 'user id' and 'event id' into meetup_participation, and then update the row at 'users' corresponding to the user with that 'user id' to increment the 'events participated'. 该过程应将“用户ID”和“事件ID”添加到meetup_participation中,然后使用该“用户ID”更新对应于该用户的“用户”行以增加“参与的事件”。 And it also UPDATE to increment the participation in the event with this 'event id'. 并且还使用此“事件ID”更新以增加参与事件。

I am using the SET ue to validate things like, if user exists, if event does exists, if date of event is still valid, and if user is not already in this table. 我正在使用SET ue验证诸如用户是否存在,事件是否存在,事件日期是否仍然有效以及用户是否已在此表中的情况。 So I am passing this value as a boolean to INSERT INTO meetup_participation [...] WHERE ue = 1. After that, I do SELECT ue to inform validation returned true and procedure executed without problems. 所以我将此值作为布尔值传递给INSERT INTO meetup_participation [...] WHERE ue = 1.之后,我执行SELECT ue通知验证返回true并且程序执行没有问题。

Here is the full procedure. 这是完整的程序。

CREATE DEFINER=`user`@`localhost` PROCEDURE `join_event`(IN `user_id` BIGINT(64), IN `event_id` INT) NOT DETERMINISTIC MODIFIES SQL DATA SQL SECURITY DEFINER

begin 

DECLARE ue INT;
SET ue = EXISTS(SELECT 1 FROM users WHERE fb_uid=user_id) AND EXISTS(SELECT 1 FROM meetup WHERE meet_id=event_id) AND EXISTS(SELECT 1 FROM meetup WHERE date > NOW() AND meet_id = event_id) AND EXISTS(SELECT 1 FROM meetup WHERE meet_id = event_id AND participants <= max_participants) AND NOT EXISTS(SELECT 1 FROM meetup_participation WHERE fb_uid = user_id AND meet_id = event_id);

INSERT INTO meetup_participation SELECT user_id, event_id FROM DUAL WHERE ue=1; 

UPDATE users SET events_participated = events_participated + 1 WHERE fb_uid=user_id AND ue=1; 
UPDATE meetup SET participants = participants + 1 WHERE meet_id=event_id AND ue=1; 
SELECT ue AS response; 

end

Thanks in advance. 提前致谢。

The INSERT statement is executed separately from the SET ue =... statement. INSERT语句与SET ue = ...语句分开执行。 I'm not sure what you are trying to accomplish, but the code makes no sense. 我不确定你要完成什么,但代码没有意义。

If you want to add records to meetup_participation based on the EXISTS tests applied to each record in the users table, you would need to apply the tests to each record in your SELECT statement as part of the INSERT. 如果要根据应用于users表中每条记录的EXISTS测试向meetup_participation添加记录,则需要将测试应用于SELECT语句中的每条记录,作为INSERT的一部分。

There are also numerous syntax/grammar issues in the code as shown. 如图所示,代码中还存在许多语法/语法问题。

If you could provide an explanation of what you are trying to accomplish with the procedure, that might allow someone to suggest the right way to code the procedure. 如果您可以提供有关您尝试使用该过程完成的内容的说明,则可能允许某人建议正确的方法来编写该过程。

Selecting ue will not tell you if the procedure completed without error. 选择ue不会告诉您程序是否完成且没有错误。 You should research mysql transactions and mysql error handling. 你应该研究mysql事务和mysql错误处理。 http://www.mysqltutorial.org/mysql-error-handling-in-stored-procedures/ is a good starting point. http://www.mysqltutorial.org/mysql-error-handling-in-stored-procedures/是一个很好的起点。

You might end up with something like this 你可能会得到这样的东西

drop procedure if exists p;
delimiter //

CREATE DEFINER=`root`@`localhost` PROCEDURE `p`(
    IN `inue` int,
    IN `user_id` BIGINT(64),
    IN `event_id` INT
)
LANGUAGE SQL
NOT DETERMINISTIC
MODIFIES SQL DATA
SQL SECURITY DEFINER
COMMENT ''
begin 

DECLARE ue INT;
declare exit handler for sqlexception
begin
    rollback;
    insert into errors (msg) select concat('error ' ,inue,',',user_id,',',event_id);
end;

set autocommit = 0;
#set ue = inue;
 SET ue = EXISTS(SELECT 1 FROM users WHERE fb_uid=user_id) 
    AND EXISTS(SELECT 1 FROM meetup WHERE meet_id=event_id) 
    #AND EXISTS(SELECT 1 FROM meetup WHERE dt > NOW() AND meet_id = event_id) 
    AND EXISTS(SELECT 1 FROM meetup WHERE meet_id = event_id AND ifnull(participants,0) <= max_participants) 
    AND NOT EXISTS(SELECT 1 FROM meetup_participation WHERE fb_uid = user_id AND meet_id = event_id)
    ;
select ue;

if ue = 1 then

start transaction;

INSERT INTO meetup_participation SELECT user_id, event_id,user_id, event_id; 
UPDATE users SET events_participated = ifnull(events_participated,0) + 1 WHERE fb_uid=user_id = user_id; 
UPDATE meetup SET participants = ifnull(participants,0) + 1 WHERE meet_id = event_id ; 

commit;

end if;

SELECT ue AS response; 

end //

The error table looks like this 错误表看起来像这样

CREATE TABLE `errors` (
  `msg` varchar(2000) DEFAULT NULL,
  `id` int(11) NOT NULL AUTO_INCREMENT,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=latin1

Note I am not suggesting this is a solution appropriate to your site , you need to do the research and figure out what is best for you. 注意我并不是说这是一个适合您网站的解决方案,您需要进行研究并找出最适合您的方案。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM