检查MySQL函数中是否存在行

时间:2014-09-11 03:12:16

标签: mysql stored-procedures

在我的user表中,ID user_id由以下函数随机生成:

DELIMITER #
CREATE FUNCTION GenerateRandomUserID()
    RETURNS CHAR(15)
    BEGIN
        DECLARE user_id CHAR(15) DEFAULT '';

        WHILE LENGTH(user_id) < 15 DO
            SET user_id = CONCAT(user_id, SUBSTRING('0123456789', RAND() * 10 + 1, 1));
        END WHILE;

        RETURN user_id;
    END#
DELIMITER ;

DELIMITER #
CREATE FUNCTION GenerateUniqueUserID()
    RETURNS CHAR(15)
    BEGIN
        DECLARE user_id CHAR(15) DEFAULT '';

        REPEAT
            SET user_id = GenerateRandomUserID();
        UNTIL NOT UserIDExists(user_id) END REPEAT;

        RETURN user_id;
    END#
DELIMITER ;

然后我插入一个用这个函数生成ID的用户。到现在为止还挺好。问题是当我插入另一个用户时,会产生无限循环。我设法将问题归结为另一个函数UserIDExists,它总是返回TRUE(显然不应该这样)。

DELIMITER #
CREATE FUNCTION UserIDExists(user_id CHAR(15))
    RETURNS BOOL
    BEGIN
        RETURN EXISTS(SELECT 1 FROM `user` WHERE `user_id` = user_id);
    END#
DELIMITER ;

这最后一个功能没有做到它应该做的,但我无法弄清楚为什么。如果单个用户存在任何密码,则会返回TRUE,只有在没有用户的情况下才会返回FALSE。任何人都可以找出原因吗?

更新

我也尝试过这个。相同的结果:

DELIMITER #
CREATE PROCEDURE UserIDExists(IN user_id CHAR(15), OUT user_id_exists BOOL)
    BEGIN
        SET user_id_exists = 0;
        SELECT 1 INTO user_id_exists FROM `user` WHERE `user_id` = user_id;
    END#
DELIMITER ;

更新

也试过这个:

DELIMITER #
CREATE PROCEDURE UserIDExists(IN user_id CHAR(15), OUT user_id_exists BOOL)
    BEGIN
        IF ((SELECT `user_id` FROM `user` WHERE `user_id` = user_id) != NULL) THEN
            SET user_id_exists = TRUE;
        ELSE
            SET user_id_exists = FALSE;
        END IF;
    END#
DELIMITER ;

更新

我尝试了以下几个variantes:

DELIMITER #
CREATE PROCEDURE UserIDExists_2(IN user_id CHAR(15), OUT user_id_exists CHAR)
    BEGIN
        SELECT `user_id` FROM `user` WHERE `user_id` = user_id;
    END#
DELIMITER ;

得出结论,当1也是user_id时,这会返回1,并且不会为任何其他值返回任何内容。这很奇怪,因为这是我在桌子上唯一的一行:

# user_id, first_name, last_name, pwd, is_confirmed
'252316605573186', 'André', 'Fratelli', NULL, '0'

这让我感到紧张......

1 个答案:

答案 0 :(得分:0)

这很有效。我虽然引用的地方足以区分程序的参数和表的列,但我想我错了。

DELIMITER #
CREATE PROCEDURE UserIDExists(IN p_user_id CHAR(15), OUT p_user_id_exists BOOL)
    BEGIN
        SET p_user_id_exists = EXISTS(SELECT `user_id` FROM `user` WHERE `user_id` = p_user_id);
    END#
DELIMITER ;