【问题标题】:Stored procedure not working as expected存储过程未按预期工作
【发布时间】:2016-07-13 17:19:00
【问题描述】:

我正在尝试创建一个存储过程,如果表中已经存在用户名或电子邮件,它将通知我。 这是我的表的结构

CREATE TABLE IF NOT EXISTS `user` (
`user_id` smallint(5) unsigned NOT NULL,
`username` varchar(40) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
`email` varchar(60) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
`password` varchar(128) NOT NULL,
`active` tinyint(4) NOT NULL DEFAULT '1',
`date_joined` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
`user_category_id` tinyint(3) unsigned NOT NULL
) ENGINE=InnoDB AUTO_INCREMENT=13 DEFAULT CHARSET=utf8;

这是存储过程的代码

DELIMITER $$
CREATE PROCEDURE `sp_create_account`( username_param VARCHAR(40),      email_param VARCHAR(60), pass VARCHAR(30), category_id TINYINT )
BEGIN 
DECLARE salt VARCHAR(60);
DECLARE username_var VARCHAR(40);
DECLARE email_var VARCHAR(60);

SELECT username_var INTO username_var FROM user WHERE username = username_param;
SELECT email_var INTO email_var FROM user WHERE email = email_param;

IF username_var = username_param THEN 
    SELECT 'username' AS message;
ELSEIF email_var = email_param THEN
    SELECT 'email' AS message;
ELSE 
    SET salt = '@4$^7EC%?';
    SET salt = CONCAT( username_param, salt );
    INSERT INTO user VALUES 
    ( DEFAULT, username_param, email_param, AES_ENCRYPT( pass, salt ), DEFAULT, DEFAULT, category_id );

    SELECT 'created' AS message;
END IF;
END$$
DELIMITER ;

两个问题: 问题 1: 插入不存在用户名或电子邮件的唯一条目时一切正常,但是当用户名或电子邮件确实存在时,我在下面的屏幕截图中收到这些错误,但我希望存储过程返回一个简单的选择,指示问题出在哪里可能是或表示成功,因为它返回“已创建”

问题 2 如果它是一个唯一条目并且它被插入到表中,则该特定行中的密码列单元格将被插入一个空字符串。

以上所有可能是什么原因?谢谢你。

【问题讨论】:

    标签: mysql stored-procedures


    【解决方案1】:

    也许这些变化正是您想要的。对架构、if 块和返回值的更改。

    返回值为用户id的AUTO_INCREMENT。请注意,我几乎遵循了您的架构。该表中的主键可能会折叠一点。有些人可能会在没有用户 ID 或用户名的情况下变得精简,而只有电子邮件地址作为 PK。这些都是要考虑的事情。我还为电子邮件地址添加了唯一键。

    架构:

    CREATE TABLE IF NOT EXISTS `user` (
        `user_id` int auto_increment primary key,
        `username` varchar(40) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
        `email` varchar(60) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
        `password` varbinary(128) NOT NULL,
        `active` tinyint(4) NOT NULL DEFAULT '1',
        `date_joined` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
        `user_category_id` tinyint(3) unsigned NOT NULL,
        unique key (`email`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
    -- truncate table user;
    

    存储过程:

    drop procedure if exists sp_create_account;
    DELIMITER $$
    CREATE PROCEDURE `sp_create_account`
    (   username_param VARCHAR(40),      
        email_param VARCHAR(60), 
        pass VARCHAR(30), 
        category_id TINYINT 
    )
    BEGIN 
        DECLARE salt VARCHAR(60);
        DECLARE username_var VARCHAR(40);
        DECLARE email_var VARCHAR(60);
        DECLARE recFound int;
        DECLARE foundStatus int DEFAULT 0;
    
        SELECT user_id INTO recFound FROM user WHERE username = username_param;
        IF recFound is null THEN
            SELECT user_id INTO recFound FROM user WHERE email = email_param;
            IF recFound is not null THEN
                SET foundStatus=1;
            END IF;
        ELSE
            SET foundStatus=1;
        END IF;
    
        IF foundStatus=0 THEN 
            SET salt = '@4$^7EC%?';
            SET salt = CONCAT( username_param, salt );
            INSERT INTO user (username,email,password,active,date_joined,user_category_id) VALUES 
            ( username_param, email_param, AES_ENCRYPT( pass, salt ), DEFAULT, DEFAULT, category_id );
            set recFound=LAST_INSERT_ID();
        END IF;
        SELECT recFound;
    END$$
    DELIMITER ;
    

    测试:

    call sp_create_account('Katherine','ksmith@hotmail.com','thepass01',101);
    call sp_create_account('Katherine','ksmith@hotmail.com','thepass01',101);
    call sp_create_account('Katherine','ksmith@hotmail.com','thepass01',101);
    call sp_create_account('caspar','caspar001@gmail.com','thepass02',77);
    select * from user;
    +---------+-----------+---------------------+------------------+--------+---------------------+------------------+
    | user_id | username  | email               | password         | active | date_joined         | user_category_id |
    +---------+-----------+---------------------+------------------+--------+---------------------+------------------+
    |       1 | Katherine | ksmith@hotmail.com  | _╦*Fó▄GàB╔┌O►²§' |      1 | 2016-07-13 17:56:54 |              101 |
    |       2 | caspar    | caspar001@gmail.com | ♀½B§5U├↨I♀#*├ ∟L |      1 | 2016-07-13 17:57:09 |               77 |
    +---------+-----------+---------------------+------------------+--------+---------------------+------------------+
    2 rows in set (0.00 sec)
    

    【讨论】:

    • 谢谢你,你给了我一个解决办法。我很感激
    【解决方案2】:

    您的最后一个 ELSE 需要将您希望在其中执行的所有命令包含在 BEGIN ... END 中。也许? 我最近在 MSSQL 方面工作得更多。

    【讨论】:

    • 你能帮帮我多解释一下吗
    • @kellymandem 在 MS SQL 中,如果您想在 IF 或 ELSE 主体中使用多个语句,则必须用 BEGINEND 将它们包围(与 C 语言使用 @ 的方式相同) 987654325@ 和 })。 我没想到 MySQL 处理它更像是 VB 用 if...then...endif
    猜你喜欢
    • 1970-01-01
    • 2013-01-05
    • 1970-01-01
    • 1970-01-01
    • 2016-05-02
    • 1970-01-01
    • 2012-09-01
    • 2019-12-08
    • 1970-01-01
    相关资源
    最近更新 更多