今天開發的同事反饋一個問題,該程式已經使用一段時間,在查詢昨天的資料時突然報出了錯誤:
圖1 ORA-01427:single-row subquery returns more than one row
異常為:單行子查詢返回多行
我得到了該查詢頁面對應的sql語句:
SELECT ID,(SELECT NAME FROM TABLE01 WHERE TID = t.id ) NAME FROM TABLE02 t WHERE TYPE = '1'
從sql語句能夠猜出來錯誤應該是從子查詢裡返回的。
按照ORA-01427的錯誤,應該是子查詢(SELECT NAME FROM TABLE01 WHERE TID = t.ID ) 返回了多行值。
驗證一下,首先根據type='1'能夠得到下面的查詢結果
SQL>SELECT ID FROM TABLE02 t WHERE TYPE = '1'
ID
--------------------------------------------------
1
2
3
取出任意一條,然後按照兩個表的關聯欄位值查詢,可以看到輸出大於一行資料。
SQL> SELECT NAME FROM TABLE01 WHERE TID = '3'
NAME
--------------------------------------------------------------------------------
3_NAME_01
3_NAME_02
3_NAME_03
所以這種情況的解決方案有幾種:
* 這種方式可以輸出結果而不會報錯,存在冗餘資料。
SELECT ID,NAME FROM TABLE01,TABLE02 t WHERE TID = t.id AND TYPE = '1'
* 另一種思路是在子查詢中進行重複值的過濾,使用group by來完成。
SELECT ID,(SELECT NAME FROM TABLE01 WHERE TID = t.id GROUP BY NAME ) NAME FROM TABLE02 t WHERE TYPE = '1'
* 如果對這個問題進一步最佳化,可以在確認這個表結構的基礎上,看看能夠添加相應的約束,這樣也能夠保證表中的資料不會存在冗餘,避免後續出現此類的問題。
* 與開發同事簡單溝通,這個表中還是存在部分的髒資料,刪除冗餘的資料,問題就解決了,這種方案不用修改代碼。
希望對你有協助,祝你有一個好心情,加油。