mysql - 存储过程未按预期工作

标签 mysql stored-procedures

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

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: 当插入用户名或电子邮件不存在的唯一条目时,一切正常,但是当用户名或电子邮件确实存在时,我在下面的屏幕截图中收到这些错误,但我希望存储过程返回一个简单的选择,指示问题所在可能是或表明成功,就像它返回“已创建”时的情况一样 enter image description here

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

造成上述情况的原因是什么?谢谢你。

最佳答案

也许这些改变正是您所寻求的。对架构、if block 和返回值的更改。

返回值是用户ID的AUTO_INCRMENT。请注意,我几乎遵循了您的模式。该表中的主键可能会稍微折叠。有些人可能会在没有用户 ID 或用户名的情况下进行精简,而仅使用电子邮件地址作为 PK。这些都是值得思考的事情。我还添加了电子邮件地址的唯一 key 。

架构:

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)

关于mysql - 存储过程未按预期工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38358001/

相关文章:

php - laravel5.1 使用 Eloquent 检索不直接相关的嵌套属性

mysql - 在 on 之后加入 Select 语句

mysql - mysql 中的内连接(多对多连接)

mysql - 多个处理程序冲突

sql-server - SQL Server 存储过程的单元测试

oracle - 如何在打开游标之前在存储过程中创建临时表?

mysql - 有没有办法使用 RMySQL 调用存储过程?

mysql - NodeJs 和 MariaDB,存储用户和密码

php - 如何获取数据库中存储的较大时间来扣除较小时间

MySQL存储过程,奇怪的无效结果