mysql存储过程问题: insert runs first and always whatever If condition I put

标签 mysql sql database stored-procedures

需要快速帮助,在下面的 SQL 插入中首先触发,然后其他选择查询被触发。无论我输入什么 If 条件,都会执行插入语句。 我正在 phpMyAdmin 中对此进行测试。 我尝试将插入语句转换为单独的存储过程,但结果也是相同的。 提前致谢..

    DELIMITER $$
DROP PROCEDURE IF EXISTS get_top$$
CREATE PROCEDURE get_top(
IN tolerance INT,
IN cred INT,
IN cgreen INT,
IN cblue INT,
IN userID INT,
IN mapID BIGINT
)

BEGIN
DECLARE topList VARCHAR(255) DEFAULT NULL;
DECLARE top1 VARCHAR(255) DEFAULT NULL;
DECLARE top2 VARCHAR(255) DEFAULT NULL;
DECLARE top3 VARCHAR(255) DEFAULT NULL;
DECLARE get_result VARCHAR(255) DEFAULT NULL;
DECLARE dev_notes VARCHAR(255) DEFAULT NULL;

SET sql_mode = 'NO_UNSIGNED_SUBTRACTION';

SELECT CONCAT(top_1, ';', top_2, ';', top_3) INTO topList
FROM Tops
WHERE red = cred AND green = cgreen AND  blue = cblue
ORDER BY top_ID asc
LIMIT 0 , 1 ;

SELECT topList,cred,cgreen,cblue;

IF topList IS NULL THEN BEGIN
    SELECT  top_1, top_2, top_3 
    INTO top1, top2, top3
    FROM Tops 
    WHERE top_1>0
    LIMIT 0 , 1 ;

    SELECT "in IF",top1,CHAR_LENGTH(top1);

    IF (top1 IS NULL) THEN 
        SET  get_result:= 'None';
    ELSE
        SET  get_result:= 'Nearest';
    END IF;

    SET topList=top1+ ','+ top2+ ','+ top3;

    SET dev_notes='result:'+get_result+' mapID:'+mapID+' User ID:'+userID+' date/time:'+NOW();
    SELECT topList,get_result;

    INSERT INTO Tops (red,green,blue,top_1,top_2,top_3,notes) VALUES (cred,cgreen,cblue,top1,top2,top3,dev_notes);
END;
ELSE BEGIN
    SET  get_result:= 'Exact';
    SELECT "in else",topList,get_result,dev_notes;
END; END IF;

IF CHAR_LENGTH(mapID)>0 THEN
    UPDATE Map SET toponym=toponymList, toponym_conf=get_result WHERE map_ID=mapID;
END IF;

END$$
DELIMITER ;

最佳答案

我修改了您的代码以将调试消息写入表中,以便我可以说明正在发生的情况。

DELIMITER $$
DROP PROCEDURE IF EXISTS get_top$$
CREATE PROCEDURE get_top(
IN tolerance INT,
IN cred INT,
IN cgreen INT,
IN cblue INT,
IN userID INT,
IN mapID BIGINT
)

BEGIN
DECLARE topList VARCHAR(255) DEFAULT NULL;
declare topsid int;
DECLARE top1 VARCHAR(255) DEFAULT null;
DECLARE top2 VARCHAR(255) DEFAULT null;
DECLARE top3 VARCHAR(255) DEFAULT null;
DECLARE get_result VARCHAR(255) DEFAULT NULL;
DECLARE dev_notes VARCHAR(255) DEFAULT NULL;

SET sql_mode = 'NO_UNSIGNED_SUBTRACTION';

SELECT top_id,CONCAT(top_1, ';', top_2, ';', top_3) INTO topsid,topList
FROM Tops
WHERE red = cred AND green = cgreen AND  blue = cblue
ORDER BY top_ID asc
LIMIT 0 , 1 ;

insert into debug_table (msg) values (concat('Start topsid:', coalesce(topsid,'not found'),' toplist:',coalesce(topList,'null'),' cred:',cred,' cgreen:',cgreen,' cblue:',cblue));

IF topList IS NULL THEN 
BEGIN
    SELECT  top_1, top_2, top_3 
    INTO top1, top2, top3
    FROM Tops 
    WHERE top_1>0
    LIMIT 0 , 1 ;

    insert into debug_table (msg) values (concat("in IF",' top1:',coalesce(top1,'null'),' len top1:',if(top1 is not null,CHAR_LENGTH(top1),0)));

    IF (top1 IS NULL) THEN 
        SET  get_result:= 'None';
    ELSE
        SET  get_result:= 'Nearest';
    END IF;

    SET topList=top1+ ','+ top2+ ','+ top3;

    #SET dev_notes='result:'+get_result+' mapID:'+mapID+' User ID:'+userID+' date/time:'+NOW();
    SET dev_notes=CONCAT('result:',get_result,' mapID:',mapID,' User ID:',userID,' date/time:',NOW());

     insert into debug_table (msg) values (concat('about to insert toplist:',coalesce(topList,'null'),' get_result:',get_result,' dev_notes:',DEV_NOTES));

    INSERT INTO Tops (red,green,blue,top_1,top_2,top_3,notes) VALUES (cred,cgreen,cblue,top1,top2,top3,dev_notes);
END;
ELSE BEGIN
    SET  get_result:= 'Exact';
   insert into debug_table (msg) values (concat(' in else toplist:',coalesce(topList,'null'),' get_result:',get_result,' dev_notes:',DEV_NOTES));
END; 
END IF;
#SELECT CHAR_LENGTH(MAPID);
#IF CHAR_LENGTH(mapID)>0 THEN
#    UPDATE Map SET toponym=toponymList, toponym_conf=get_result WHERE map_ID=mapID;
#END IF;

END$$
DELIMITER ;

如果上衣看起来像这样

DROP TABLE IF EXISTS TOPS;
CREATE TABLE TOPS(TOP_ID INT AUTO_INCREMENT PRIMARY KEY,
red INT,green INT,blue INT,top_1 varchar(4),top_2 varchar(4),top_3 varchar(4),notes VARCHAR(100));

我就是这么做的

ariaDB [sandbox]> TRUNCATE TABLE TOPS;
Query OK, 0 rows affected (0.16 sec)

MariaDB [sandbox]> truncate table debug_table;
Query OK, 0 rows affected (0.24 sec)

MariaDB [sandbox]> CALL GET_TOP(1,1,1,1,'1','1');
Query OK, 1 row affected (0.17 sec)

MariaDB [sandbox]> select * from tops;
+--------+------+-------+------+-------+-------+-------+-------------------------------------------------------------+
| TOP_ID | red  | green | blue | top_1 | top_2 | top_3 | notes                                                       |
+--------+------+-------+------+-------+-------+-------+-------------------------------------------------------------+
|      1 |    1 |     1 |    1 | NULL  | NULL  | NULL  | result:None mapID:1 User ID:1 date/time:2017-07-20 09:45:00 |
+--------+------+-------+------+-------+-------+-------+-------------------------------------------------------------+
1 row in set (0.00 sec)

MariaDB [sandbox]> CALL GET_TOP(1,1,1,1,'1','1');
Query OK, 1 row affected (0.10 sec)

MariaDB [sandbox]>
MariaDB [sandbox]> SELECT * FROM debug_table;
+----+--------------------------------------------------------------------------------------------------------------------+
| id | msg                                                                                                                |
+----+--------------------------------------------------------------------------------------------------------------------+
|  1 | Start topsid:not found toplist:null cred:1 cgreen:1 cblue:1                                                        |
|  2 | in IF top1:null len top1:0                                                                                         |
|  3 | about to insert toplist:null get_result:None dev_notes:result:None mapID:1 User ID:1 date/time:2017-07-20 09:45:00 |
|  4 | Start topsid:1 toplist:null cred:1 cgreen:1 cblue:1                                                                |
|  5 | in IF top1:null len top1:0                                                                                         |
|  6 | about to insert toplist:null get_result:None dev_notes:result:None mapID:1 User ID:1 date/time:2017-07-20 09:45:00 |
+----+--------------------------------------------------------------------------------------------------------------------+
6 rows in set (0.00 sec)

我希望在第一次调用时,tops 中不会找到任何记录,并且 topslist 将为空,这由 debug_table 中的前三个记录证明。在第二次调用时,在 tops 中找到一条记录,但由于 top_1、top_2 和 top_3 为空,因此 topslist 再次为空。 if 中的选择“失败”,因为没有值 > 0 的 tops_1 记录,因此将空值插入到 tops 的另一条记录中,这可以在 debug_table 记录 4 -6 中跟踪。顺便说一句,检查 varchar 字段的值是否 > 0 并不是一个好主意。

关于mysql存储过程问题: insert runs first and always whatever If condition I put,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45193283/

相关文章:

java - Solr 自动提交和自动优化?

php - 条件 PDO bindParam 更新

mysql - SQL 查询问题 (MySQL)

mysql - SQL 在列表 A 中选择但不在列表 B 中

mysql - 获取不同的用户但关联的所有其他行

'0' 附近的 Java 语法不正确

mysql - VB.NET函数返回错误并退出子进程

sql - 从单个表或 Sql Server 2005/8 中的所有表中编写所有数据?

sql - 创建包含具有静态信息的列的 View

database - 为什么 RDS 突发平衡看起来是随机的,永远不会低于 99%,并且与系统流量无关?