ITPUB SQL大賽之BUG(八)
由於SQL大賽題目相對比較困難,不但需要使用大量的特性,且SQL實現十分複雜,一般執行時間也會比較長,這些因素導致碰到bug的機率直線上升。這裡介紹SQL大賽期間碰到的幾個bug。
這篇描述PLS-306錯誤。
ITPUB SQL大賽之BUG(一):http://yangtingkun.itpub.net/post/468/515815
ITPUB SQL大賽之BUG(二):http://yangtingkun.itpub.net/post/468/515926
ITPUB SQL大賽之BUG(三):http://yangtingkun.itpub.net/post/468/515982
ITPUB SQL大賽之BUG(四):http://yangtingkun.itpub.net/post/468/516023
ITPUB SQL大賽之BUG(五):http://yangtingkun.itpub.net/post/468/516219
ITPUB SQL大賽之BUG(六):http://yangtingkun.itpub.net/post/468/516307
ITPUB SQL大賽之BUG(七):http://yangtingkun.itpub.net/post/468/516340
這篇碰到的問題並不是一個bug,但是卻有可能成為一個隱藏很深,很難檢查到的問題。
在第三期修改SQL的過程中,有一次碰到了這樣一個錯誤:
SQL> WITH ROUTE_D AS /* get full routes */
2
(
3
SELECT CITY1 R, CITY2 T, DISTANCE DIS
4
FROM ROUTES
5
UNION ALL
6
SELECT CITY2, CITY1, DISTANCE
7
FROM ROUTES
8
),
9
ROUTE_ALL_D (C1, C2, LINES, DISTANCE) AS /* get every route of any two cities
*/
10
(
11
SELECT R, T, CAST('"' || R || '"' || T || '"' AS VARCHAR2(4000)),
DIS /* avoid ora-1489 error */
12
FROM ROUTE_D
13
UNION ALL
14
SELECT A.C1, T, LINES || T || '"', DIS + DISTANCE /* '"' for avoid
city name contains other city name */
15
FROM ROUTE_D R, ROUTE_ALL_D A
16
WHERE A.C2 = R.R
17
AND INSTR(LINES, '"' || T || '"', 1, 1) = 0 /* avoit duplicate
city */
18
AND DISTANCE + DIS <= /* filter the distance longer than routes */
19 NVL
20 (
21 (
22 SELECT DISTANCE
23 FROM ROUTES RS
24 WHERE (A.C1 = RS.CITY1
25 AND R.T = RS.CITY2)
26 OR (A.C1 = RS.CITY2
27 AND R.T = RS.CITY1)
28 ),
29
9.9E38
30 )
31
),
32
RESULT_HALF AS
33
(
34
SELECT C1 R, C2 T, MIN(DISTANCE) DIS
35
FROM ROUTE_ALL_D
36
WHERE C1 < C2
37
GROUP BY C1, C2
38
),
39
RESULT_ALL AS
40
(
41
SELECT R, T, DIS
42
FROM RESULT_HALF
43
UNION ALL
44
SELECT T, R, DIS
45
FROM RESULT_HALF
46
),
47
RESULT AS
48
(
49
SELECT R, T,
50 DISTANCE * 2 * C.MEMBERS COST,
51 SUM(DISTANCE * 2 * C.MEMBERS) OVER(PARTITION
BY R) COST_CITY
52
FROM RESULT_ALL R, CITIES C
53
WHERE R.T = C.CITY_NAME(+) /* any city in route can win even the city have
no member */
54
)
55
SELECT R, NVL(T, 'TOTAL') T, NVL(SUM(COST), 0) COST
56
FROM
57
(
58
SELECT R, T, COST, RANK() OVER(ORDER BY COST_CITY) RN
59
FROM RESULT
60
)
61
WHERE RN = 1
62
GROUP BY GROUPING SETS ((R, T), R)
63
ORDER BY R, DECODE(T, 'TOTAL', CHR(0), T);
SUM(DISTANCE * 2 * C.MEMBERS)
OVER(PARTITION BY R) COST_CITY
*
第 51 行出現錯誤:
ORA-06553: PLS-306: 呼叫 'OGC_DISTANCE' 時引數個數或型別錯誤
這個錯誤很有意思,只是在最佳化調整SQL,怎麼會突然出現一個PLS-306的錯誤,而且我也沒有呼叫任何什麼特別的函式。
仔細檢查後發現,由於調整了WITH子句中列的別名,DISTANCE被改成了DIS,而查詢這個WITH子句的SQL沒有進行對應的修改,導致了這個錯誤。
從這一點上看,這個DISTANCE還應該是一個PUBLIC的同義詞才對,檢查資料字典:
SQL> SELECT OWNER, OBJECT_NAME, OBJECT_TYPE
2
FROM DBA_OBJECTS
3
WHERE OBJECT_NAME = 'DISTANCE';
OWNER OBJECT_NAME OBJECT_TYPE
---------- ------------------------------ -------------------
PUBLIC DISTANCE SYNONYM
SQL> SELECT OWNER, SYNONYM_NAME, TABLE_OWNER, TABLE_NAME
2
FROM DBA_SYNONYMS
3
WHERE SYNONYM_NAME = 'DISTANCE';
OWNER SYNONYM_NAME TABLE_OWNER TABLE_NAME
---------- --------------- --------------- ------------------------------
PUBLIC DISTANCE MDSYS OGC_DISTANCE
SQL> SELECT OWNER, OBJECT_NAME, OBJECT_TYPE
2
FROM DBA_OBJECTS
3
WHERE OBJECT_NAME = 'OGC_DISTANCE'
4
AND WNER = 'MDSYS';
OWNER OBJECT_NAME OBJECT_TYPE
---------- ------------------------------ -------------------
MDSYS OGC_DISTANCE FUNCTION
到這裡已經和錯誤資訊對上了,由於指定的DISTANCE在當前使用者的表中找不到,因此Oracle從PUBLIC物件中進行解析,找到一個同義詞後,發現是一個函式,而由於這個函式需要引數才能返回結果,因此SQL執行報錯。
分析到這裡被嚇了一跳,如果這個OGC_DISTANCE函式在沒有引數的情況下也可以返回NUMBER型別的數值,那麼就徹底杯具了。那麼這個bug隱藏的極為隱蔽,很難被檢測到。
看來透過表名的列名的組合來明確的指示一個列是有必要的,至少可以大大減少這種隱蔽錯誤產生的機率。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/4227/viewspace-692268/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- ITPUB SQL大賽之BUG(七)SQL
- ITPUB SQL大賽之BUG(六)SQL
- ITPUB SQL大賽之BUG(五)SQL
- ITPUB SQL大賽之BUG(四)SQL
- ITPUB SQL大賽之BUG(三)SQL
- ITPUB SQL大賽之BUG(二)SQL
- ITPUB SQL大賽之BUG(一)SQL
- ITPUB SQL大賽第三期SQL
- ITPUB SQL大賽第一期SQL
- ITPUB SQL大賽第二期SQL
- ITPUB SQL大賽第四期SQL
- ITPUB SQL大賽第三期(二)SQL
- ITPUB SQL大賽第二期(二)SQL
- ITPUB SQL大賽第二期(一)SQL
- sql大賽總結SQL
- sql大賽第四期SQL
- 第八屆“網際網路+”大賽 | 雲原生賽道邀你來挑戰
- 《戰爭藝術》大師賽主播邀請賽B組鏖戰 八位主播貢獻精彩賽事
- SQL資料庫程式設計大賽隨感SQL資料庫程式設計
- SQL資料庫程式設計大賽開幕SQL資料庫程式設計
- 大資料實戰之環境搭建(八)大資料
- SQL菜鳥筆記之第八篇 SQL單行函式 (中)SQL筆記函式
- itpub 復活節最短sql(未完成程式碼)SQL
- Introduction to SQL Tuning Advisor zt自ITPUBSQL
- 周大俠啊進擊的JavaScript(八)之繼承JavaScript繼承
- JVM引數調優八大技巧之筆記JVM筆記
- itpub
- 【ITPUB】ITPUB十週年感言 - Secooler
- 一路走來之“網路技術大賽”
- 「雜文」演算法競賽之黑話大賞演算法
- 專案管理之八大績效域-------筆記(二)專案管理筆記
- 專案管理之八大績效域------筆記(三)專案管理筆記
- 專案管理之八大績效域------筆記(五)專案管理筆記
- upyun開發者大賽
- 積木大賽
- oracle之BUG 7497640Oracle
- 第八屆中國國際“網際網路+”大學生創新創業大賽介紹創業
- SQL Server索引管理之六大鐵律SQLServer索引