Oracle存储过程验证用户名密码时异常触发问题求助
解决Oracle存储过程
member_ck_sp验证凭证始终触发异常的问题 我一眼就看出问题所在了——你的循环逻辑有个致命的缺陷:它会遍历所有用户记录,哪怕中途已经找到匹配的用户名和密码,后续的不匹配记录会把lv_check_txt重新设为'Fail'。最后当循环结束时,只有最后一条记录恰好是你要验证的用户时,lv_check_txt才会是'Pass',否则都会变成'Fail',这就是为什么哪怕输入正确的凭证也会触发no_data_found异常。
下面给你两种修复方案,推荐第二种(更高效简洁):
方案一:修复循环逻辑,找到匹配后立即退出
在找到匹配的用户时,设置lv_check_txt为'Pass'并跳出循环,避免后续记录覆盖结果:
create or replace PROCEDURE member_ck_sp ( p_uname IN VARCHAR2, p_pass IN VARCHAR2, p_name OUT VARCHAR2, p_cookie OUT VARCHAR2 ) IS CURSOR CUR_CHECK IS SELECT USERNAME, PASSWORD,FIRSTNAME||''||LASTNAME, COOKIE FROM bb_shopper; lv_check_txt VARCHAR2(100) := 'Fail'; -- 默认设为Fail BEGIN FOR rec_check IN cur_check LOOP IF p_uname = rec_check.username AND p_pass = rec_check.PASSWORD THEN lv_check_txt := 'Pass'; -- 找到匹配后立即退出循环,防止被后续记录覆盖 EXIT; END IF; END LOOP; IF lv_check_txt = 'Pass' THEN SELECT FIRSTNAME||''||LASTNAME, COOKIE INTO p_name, p_cookie FROM bb_shopper WHERE USERNAME = P_UNAME AND password = p_pass; dbms_output.put_line(p_name||' '|| p_cookie); ELSE raise no_data_found; END IF; EXCEPTION WHEN no_data_found THEN dbms_output.put_line('Please reenter credentials'); END;
方案二:去掉循环,直接用查询+异常处理(推荐)
这种方式更符合Oracle的编程习惯,不需要遍历全表,直接通过SELECT INTO尝试获取匹配的用户,如果没有找到会自动触发no_data_found异常,代码更简洁高效:
create or replace PROCEDURE member_ck_sp ( p_uname IN VARCHAR2, p_pass IN VARCHAR2, p_name OUT VARCHAR2, p_cookie OUT VARCHAR2 ) IS BEGIN -- 直接查询匹配的用户,找不到会自动触发no_data_found SELECT FIRSTNAME||''||LASTNAME, COOKIE INTO p_name, p_cookie FROM bb_shopper WHERE USERNAME = p_uname AND password = p_pass; dbms_output.put_line(p_name||' '|| p_cookie); EXCEPTION WHEN no_data_found THEN dbms_output.put_line('Please reenter credentials'); END;
测试验证
用你提供的测试代码运行修复后的存储过程,就能正常输出用户信息,不会再触发异常了:
DECLARE lv_username_txt bb_shopper.username%TYPE := 'rat55'; lv_password_txt bb_shopper.PASSWORD%TYPE := 'kile'; lv_name_txt VARCHAR2(200); lv_cookie_txt bb_shopper.cookie%TYPE; BEGIN member_ck_sp(lv_username_txt,lv_password_txt,lv_name_txt,lv_cookie_txt); -- DBMS_OUTPUT.PUT_LINE('User name is '||lv_name_txt||' and cookie '||lv_cookie_txt); END;
内容的提问来源于stack exchange,提问作者DKCroat
相关产品推荐
相关产品推荐

