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 ; 

2つの問題のためのコードです: 問題1:でユニークなエントリを挿入するとき すべてが正常に動作しますユーザー名や電子メールは存在しませんが、ユーザー名や電子メールが存在するときは、以下のスクリーンショットでこれらのエラーが表示されますが、ストアドプロシージャは、問題がどこにあるかを示す簡単な選択を返すか、それは一意のエントリであり、それはテーブルに挿入入った場合場合に、それは enter image description here

通報2 返し「作成」場合、その特定の行のパスワード列のセルは、空の文字列が挿入されます。

上記のすべての原因は何ですか?ありがとうございます。

答えて

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','[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のようにVBのように処理するということを私の考えに伝えました... endif_ – Uueerdo

関連する問題