You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 09:25:15