2016-07-13 3 views
0

Я пытаюсь создать хранимую процедуру, которая уведомит меня, если в таблице уже существует имя пользователя или электронная почта. Вот структура моего столаСохраненная процедура не работает должным образом

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 Если это уникальная запись и она будет вставлена ​​в таблицу, ячейки столбца паролей в этой конкретной строке Вставляется с пустой строкой.

Что может быть причиной всего вышеперечисленного? Спасибо вам.

ответ

1

Возможно, эти изменения являются тем, что вы ищете. Изменения в схеме и блоки if, а также возвращаемые значения.

Возвращаемое значение - это идентификатор пользователя AUTO_INCREMENT. Заметьте, я в значительной степени следовал вашей схеме. Возможно, ваш первичный ключ в этой таблице немного свернут. Некоторые могут пойти на худой, не используя идентификатор пользователя или имя пользователя, а просто адрес электронной почты в качестве ПК. Это вещи, о которых нужно думать. Я также добавил уникальный ключ для адреса электронной почты.

Схема:

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','[email protected]','thepass01',101); 
call sp_create_account('Katherine','[email protected]','thepass01',101); 
call sp_create_account('Katherine','[email protected]','thepass01',101); 
call sp_create_account('caspar','[email protected]','thepass02',77); 
select * from user; 
+---------+-----------+---------------------+------------------+--------+---------------------+------------------+ 
| user_id | username | email    | password   | active | date_joined   | user_category_id | 
+---------+-----------+---------------------+------------------+--------+---------------------+------------------+ 
|  1 | Katherine | [email protected] | _╦*Fó▄GàB╔┌O►²§' |  1 | 2016-07-13 17:56:54 |    101 | 
|  2 | caspar | [email protected] | ♀½B§5U├↨I♀#*├ ∟L |  1 | 2016-07-13 17:57:09 |    77 | 
+---------+-----------+---------------------+------------------+--------+---------------------+------------------+ 
2 rows in set (0.00 sec) 
+0

Спасибо, вы дали мне способ понять это. Я ценю – kellymandem

+0

yw Kelly в любое время – Drew

0

Ваш последний ELSE должен иметь все команды, которые вы ожидаете выполнить в нем, заключенный в BEGIN ... END. Может быть? В последнее время я больше работаю в MSSQL.

+0

вы могли бы помочь тени больше света на что – kellymandem

+0

@kellymandem В MS SQL, если вы хотите иметь более одного оператора в корпусе IF или ELSE, вы должны окружить их 'BEGIN' и' END' (таким же образом языки C используют '{' и '}'). _It поскользнулся, что MySQL обрабатывает его больше как VB с if ... then ... endif_ – Uueerdo

Смежные вопросы