SpringBoot項目調用數(shù)據(jù)庫函數(shù)報錯Result consisted of more than one row

這個報錯太具有誤導性了,致使我們花了好長時間,采用了很多錯誤的解決方案。

項目中有一個表,有id、qr_code、parent_qr_code這3個字段,層級沒有限制。有時候需要在代碼中查詢某個qr_code的頂級qr_code,用代碼寫遞歸查詢感覺效率會比較差,所以寫了個函數(shù)來查root節(jié)點:

BEGIN
    DECLARE current_qrcode VARCHAR(255);
    DECLARE parent_qrcode VARCHAR(255);

    SET current_qrcode = start_qrcode;

    -- 防止無限循環(huán),設置最大層級
    SET @max_level = 100;
    SET @current_level = 0;

    loop_label: LOOP
        SET @current_level = @current_level + 1;

        -- 如果超過最大層級,退出循環(huán)
        IF @current_level > @max_level THEN
            LEAVE loop_label;
        END IF;

        -- 查詢當前記錄的父級
        SELECT t.parent_qr_code INTO parent_qrcode
        FROM qr_tree t
        WHERE t.qr_code = current_qrcode;

        -- 如果沒有父級或者父級為空,說明找到頂級
        IF parent_qrcode IS NULL OR parent_qrcode = '' THEN
            LEAVE loop_label;
        ELSE
            SET current_qrcode = parent_qrcode;
        END IF;
    END LOOP;

    RETURN current_qrcode;
END

在測試環(huán)境之前走的一切正常,但是今天上生產環(huán)境突然報錯:

### Cause: java.sql.SQLSyntaxErrorException: Result consisted of more than one row
; bad SQL grammar []; nested exception is java.sql.SQLSyntaxErrorException: Result consisted of more than one row
org.springframework.jdbc.BadSqlGrammarException: 
### Error querying database.  Cause: java.sql.SQLSyntaxErrorException: Result consisted of more than one row
### The error may exist in URL [jar:file:/home/PROJECT/spring-boot-system.jar!/BOOT-INF/lib/spring-boot-business.jar!/org/qrTree/mapper/xml/QrTree.xml]
### The error may involve defaultParameterMap
### The error occurred while setting parameters
### SQL: select * from qr_tree where qr_code = (SELECT find_top_qrcode(?)) limit 1
### Cause: java.sql.SQLSyntaxErrorException: Result consisted of more than one row
; bad SQL grammar []; nested exception is java.sql.SQLSyntaxErrorException: Result consisted of more than one row

這個報錯太具有誤導性了,一開始一看到這個報錯,就覺得是函數(shù)或者整條SQL返回了多條數(shù)據(jù),而只能接收一條所報的錯,于是在Navicat里各種執(zhí)行,發(fā)現(xiàn)都沒問題,但是在項目里就是會報錯。
代碼改來改去都不行,不如給函數(shù)后面加個LIMIT 1,或者去掉嵌套式的查詢直接qr_code=find_top_qrcode(),結果發(fā)現(xiàn)依然報錯。
然后就給函數(shù)里面的查詢加了個LIMIT 1,就是這一段:

SELECT t.parent_qr_code INTO parent_qrcode
FROM qr_tree t
WHERE t.qr_code = current_qrcode LIMIT 1;

然后發(fā)現(xiàn)果然不報錯了。

就在我們以為萬事大吉之后,發(fā)現(xiàn)了另一個問題:這個業(yè)務操作之后,這個表中的qr_code列會出現(xiàn)重復。

經過代碼的梳理,我發(fā)現(xiàn)我本來寫的是replace info,因為數(shù)據(jù)庫的ID沒有自增,所以手動設置了UUID,這時候就發(fā)現(xiàn)問題了,生產環(huán)境的數(shù)據(jù)庫沒!有!設!置!唯!一!鍵!

如果設置了唯一鍵,這個表的qr_code就不可能重復。那么加上唯一鍵,剛才的報錯會消失嗎?

我加上了唯一鍵,并且去掉了剛才胡亂添加的LIMIT 1,再跑一遍代碼,果然,不報錯了!

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容