1. 程式人生 > >Oracle常見錯誤及解決方案彙總

Oracle常見錯誤及解決方案彙總

(原創作者:陳玓玏)

這篇文章主要是記錄一些工作中常常會碰到的錯誤跟解決方案,彙總到一起,方便查詢。

1、 錯誤提示ORA-00933: SQL command not properly ended in?

可能的原因:

1)語句寫的順序不正確,比如WHERE語句寫在了GROUP BY後面;
2)使用了含有ORDER BY或INNER JOIN子句的INSERT、DELETE語句;
3)使用了含有INNER JOIN子句的UPDATE語句;
4)使用了條件中含有自連線表字段比較的Triangular Join;

解決方案:
檢查語句的子句組合是否正確,檢查語句的使用順序是否正確,比如GROUP BY是否放在WHERE之後,ORDER BY是否放在GROUP BY之後。

2、 ORA-01830:日期格式圖片在轉換整個輸入字串之前結束

錯誤原因:
date型別不能包含秒以後的精度,如日期:2012-06-20 21:01:24,如果使用to_date()函式來處理這種格式的時間,就會出現這種錯誤。

解決方案:
把to_date(date,’yyyy-mm-dd’)改成to_date(substr(date,1,10),’yyyy-mm-dd’),如果date本身不是字串格式,在使用substr之前還需要先用to_char()轉換成字串型別,並且在使用substr時,注意驗證取數長度,也就是substr函式的第二、三個引數。

3、ORA-01652:無法通過 128 (在表空間 TEMP 中) 擴充套件 temp 段

這個問題是我同事遇到的,我和她運行同樣的程式碼,但是我的沒錯,她的出現了這個錯誤,而且她把整段程式碼刪除後重貼,錯誤就解決了,很奇怪。
可能的原因:
1)臨時表空間大小做了限制,而當進行order by、group by這些排序相關的運算,或者訪問檢視等操作時,空間大小受到限制就會出現這類錯誤。
2)還有一種我自己猜測的原因,就是在寫join的時候,沒有注意到匹配條件,導致產生了笛卡爾積,那麼基本表很大的情況下,再大的臨時表空間也可能會不夠用,所以寫join或者用where子句實現join功能的時候,一定要注意匹配條件。

解決方案:
擴充套件臨時表空間(這個一般如果自己不會,可以找DBA幫忙?):
方法一、增大臨時檔案大小:
SQL> alter database tempfile ‘/u01/app/oracle/oradata/orcl/temp01.dbf’ resize100m;
Database altered.
方法二、將臨時資料檔案設為自動擴充套件:
SQL> alter database tempfile ‘/u01/app/oracle/oradata/orcl/temp01.dbf’ autoextend on next 5m maxsize unlimited;
參考連結:

https://www.cnblogs.com/songling/archive/2011/03/04/1970965.html

4、ORA-00955: 名稱已由現有物件使用:

可能的原因:
1)表重名;
2)列重名;
3)在Oracle裡寫了drop table if exists這樣的語句。

解決方案:
如果出現了第三種情況,果斷把if exists刪掉就好了,這個在Oracle裡是錯誤寫法,主要還是SQL語言可移植性差。如果沒出現第三種情況,那就老實檢查表名和列名的重名情況吧。

5、ORA-01861: 文字與格式字串不匹配:

可能的原因:
使用to_date函式時,且很有可能轉換的引數是一個未可知的格式,時間引數的格式和要轉換的格式不匹配,這個原因和ORA-01830錯誤類似,解決方案也類似,要保證時間引數的型別、格式,時間處理函式都沒有出錯才行,而且時間處理函式在每個資料庫裡都不太一樣,要尤其注意。

解決方案:
先把要轉換的引數換成字串格式,再用to_date函式,更保險一點。

6、ORA-00904:標示符無效

可能的原因:
1)列名寫錯了,和資料表中的列名不一致
2)中文列名沒帶引號

7、ORA-00979: 不是 GROUP BY 表示式:

可能的原因:
SELECT子句裡用到的除了count等計算函式裡用到的列以外,其他的列沒有在GROUP BY子句裡寫出來。因為資料庫有這個要求,除了函式裡面的列名,其他的必須前後都有。

解決方案:
老實在GROUP BY裡面把列名都加上。不過如果想在SELECT裡面取很多列,還加上計算函式的輸出結果,也是不太現實,因為一般計算函式都是針對多行而言的,如果在SELECT子句裡寫了一些唯一標識的欄位,比如id類欄位,那麼在GROUP BY裡也必須加上這個欄位,那COUNT也就沒意義了。所以如果又要計算,又要取很多列,可能還是老實做join比較靠譜。

8、ORA-00923:未找到要求的 FROM 關鍵字

可能的原因:
取別名的時候用了關鍵字,比如用size、date之類的做列名

解決方案:
別名的選擇儘量避開這些關鍵字,最好是所有的列名都避開這些關鍵字。

9、ORA-00937: not a single-group group function

原因和解決方案都和ORA-00979類似

10、ORA-00911:invalid character

可能的原因:
這個問題是在Python中寫SQL程式碼的時候碰到的。因為Python裡的SQL程式碼不能有分號,但是在SQL裡寫程式碼的時候習慣帶分號,所以出現了這個錯。

解決方案:
刪掉分號就好了,其實在SQL裡執行SQL語句也可以沒有分號的,所以我現在都直接不寫分號了,複製到Python裡執行自然也就不會出現這個錯誤了。

11、ORA-01476: 除數為 0:

可能的原因:
計算除法的時候,分母為0

解決方案:
用decode函式在判斷分母為0的時候把分母設為不為0的函式即可。比如decode(num,0,1) 。

12、ORA-01840: 輸入值對於日期格式不夠長

可能的原因:
1)日期本身不對,比如寫了2月29日,結果根本沒有這天
2)時間格式不對,比如你要求轉換成帶時分秒的,結果字串並沒有這麼長

解決方案:
檢查資料型別、格式、資料是否正確,時間上出的錯,大都是這麼檢查,然後用to_char,substr和改變要轉換的時間格式來組合解決問題。

13、SQL執行錯誤#1248,提示Every derived table must have its own alias

可能的原因:
出現這個錯誤時,我寫了很多個select語句,就是層層過濾需要的資訊,實現的功能是從一個表中先獲取所有屬於某個班的學生的id,再根據這些id從另一個表中獲取這些學生所有課程的成績得分,再從這次過濾的結果中根據課程進行Group by求均值。前面兩個select語句都沒出錯,寫到第三個的時候就報了這個錯。

解決方案:
在用select過濾資料形成一個新的臨時表時,最好用as給這個表定義一個別名。如下:

select t.cno,avg(t.degree) from
(select * from score where sno in
(select sno from student where class=95033)) as t   #這裡寫了三個select語句,如果不重名名的話,會報錯
group by t.cno

不寫as t就報錯了。