【问题标题】:MySQL procedure returning wrong value (INSERT SELECT confronting)MySQL 程序返回错误值(INSERT SELECT 面临)
【发布时间】:2017-02-15 05:16:55
【问题描述】:

我是 MySQL 的新手,遇到了一些错误,但我总能找到解决方案,除了这个我无法理解如何解决它。

如果变量“ue”是 1 或 0(一堆存在验证),则以下 MySQL 过程会返回一个值。验证部分(SET ue = EXISTS...)在没有其余代码的情况下工作,正如它应该的那样,问题不存在。但是当我执行命令 INSERT INTO SELECT 时,它不起作用,它总是返回 0 作为响应,而应该是 1。这两行正在相互对抗。

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

选择 ue 作为响应;

该过程应将“用户 id”和“事件 id”添加到 meetup_participation 中,然后更新与具有该“用户 id”的用户对应的“用户”行以增加“参与的事件”。它还更新以使用此“事件 id”增加对事件的参与。

我正在使用 SET ue 来验证诸如用户是否存在、事件是否存在、事件日期是否仍然有效以及用户是否不在此表中等内容。所以我将此值作为布尔值传递给 INSERT INTO meetup_participation [...] WHERE ue = 1。之后,我执行 SELECT ue 以通知验证返回 true 并且过程执行没有问题。

这是完整的过程。

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

提前致谢。

【问题讨论】:

  • 很难从代码段中理解哪些字段来自数据库表,哪些是传递给过程的参数。如果您可以提供带有变量声明的 create procedure 语句并将来自 db 的列名设置为别名,那将会有所帮助。如果程序不是太长,请编辑问题以包含完整的程序。另外我不知道这两条线对峙是什么意思,你能找到另一种方式来描述你的意思吗?
  • @P.Salmon 我已经编辑了代码以便更好地理解,面对我的意思是,如果没有'INSERT INTO SELECT',它确实会返回它应该返回的正确值......面对可能不是正确的用英语怎么说。
  • 您的程序确实有效 - SET events_participated = events_participated + 1 和 SET参与者 = 参与者 + 1 可能的例外情况需要有资格满足 null 的起始值 - SET events_participated = ifnull( events_participated,0) + 1 和 SET 参与者 = ifnull(participants,0) + 1。
  • @P.Salmon 此字段设置为以默认值 0 开头,但感谢您的提示!它确实有效,更新所有字段并正确插入行,但我的问题是返回值,它总是从 'ue' 变量返回 0 而不是 1。当更新问题时,我丢失了最后一部分,当它执行“SELECT ue AS response”时,它确实失败了。
  • 我无法重现您的问题 - 如果 select ue 始终返回值 0,那么您的 set ue 必须始终返回值 0 - ue 的值在 set 和 select 之间不会改变。

标签: mysql sql sql-insert procedure


【解决方案1】:

INSERT 语句与 SET ue =... 语句分开执行。我不确定您要完成什么,但代码没有意义。

如果您想根据应用于 users 表中每条记录的 EXISTS 测试将记录添加到 meetup_participation,则需要将测试应用于 SELECT 语句中的每条记录,作为 INSERT 的一部分。

如图所示,代码中还有许多语法/语法问题。

如果您可以解释您试图通过该过程完成的工作,这可能会让某人建议正确的方法来编写该过程。

【讨论】:

  • 对不起,我不知道为什么它没有意义......我已经编辑了这个问题,也许它更好......代码确实(插入,更新...... ) 工作除了返回选定的值,并且选择代码在没有 INSERT 命令的情况下工作。什么是语法/句法问题? PMA 不会提醒我任何...
  • 每个语句都是独立的。如果在集合之后,ue = 1,则对于插入的选择部分中的所有记录,它将等于 1。 IOW,它将所有记录从双重插入到meetup_participation。它不会从一个记录更改为另一个记录。两个选择相同。您正在使用返回的值,而不是 set 语句中的“公式”。
【解决方案2】:

选择 ue 不会告诉您程序是否完成且没有错误。你应该研究 mysql 事务和 mysql 错误处理。 http://www.mysqltutorial.org/mysql-error-handling-in-stored-procedures/ 是一个很好的起点。

你可能会得到这样的结果

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 //

错误表如下所示

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

请注意,我并不是说这是适合您网站的解决方案,您需要进行研究并找出最适合您的解决方案。

【讨论】:

    猜你喜欢
    • 2018-09-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-20
    相关资源
    最近更新 更多