關於shell中的pl/sql指令碼錯誤排查與分析
今天有個同事問我一個問題,他說執行shell指令碼的時候丟擲了ORA 錯誤,但是對於錯誤的原因沒有思路,想讓我幫他看看。
我檢視了下,指令碼的結構比較清晰。
指令碼是有一個shell指令碼,一個sql檔案組成,shell指令碼作為基本的流程控制,sql檔案中是pl/sql指令碼。
大體明白了shell指令碼的部分,沒有做過多的追究,就開始瞭解pl/sql指令碼的內容了。
首先在pl/sql中宣告瞭大量的procedure,類似shell中的function,大概有10多個procedure
然後在最後使用一個類似main函式的pl/sql塊來判斷,什麼場景呼叫什麼procedure
指令碼結構類似
declare
flag varchar2(100); --宣告的變數
procedure proc1 is
begin
dbms_output.put_line('this is a test for procedure one'); --儲存過程的內容
end;
procedure proc2 is
begin
dbms_output.put_line('this is a test for procedure two);
end;
---more procedures defined here
begin --類似main方法的部分
flag:='a'; --宣告的變數透過shell變數傳入
if(flag='a') then
proc1; --呼叫儲存過程
end if;
if(flag='b') then
proc2;
end if;
end;
/
儲存過程大概有10多個,所以抓住重點來看整個shell指令碼就比較清晰了,要不直接上來就看儲存過程的細節,馬上就迷茫了。
明白了儲存過程的整體實現思路,來看丟擲的錯誤,錯誤是一個老套的ORA錯誤。
ORA-00942: table or view does not exist
根據錯誤的資訊,出錯的地方是在第一個儲存過程proc1
這個儲存過程的內容就很豐富了,裡面會呼叫動態sql建立view,建立臨時表。
細數下來,建立view,function,table的操作大概有6,7處。
如何儘快地排查出倒底是在哪個環節出錯還是比較棘手的。
比如一個呼叫動態pl/sql建立view, 建立的於假設為
create or replace view test_view as select xxxxx,xxxx,xxxxx, xxx from table1,table2,table3,table4
where xxxxxxx xxxxx xxxx
對於大量的這種操作一種比較快捷的方式就是使用explain plan來校驗。
因為有些pl/sql塊不能隨便執行,不能隨便建立view,table等,所以透過explain plan能夠快速的校驗出哪些表可能存在問題或者無法訪問等等。
如果存在,那麼很快就會解析生成執行計劃。影響是很小的。
SQL> explain plan for select test.object_id,t.object_id from test ,t where test.object_id=t.object_id;
Explained.
如果出錯,就會很明顯的得到錯誤的出處。
explain plan for select test.object_id,t.object_id from test ,ttttt t where test.object_id=t.object_id
*
ERROR at line 1:
ORA-00942: table or view does not exist
這樣就會很明顯的發現錯誤之處在於ttttt不可訪問或者不存在。
明白了這點,問題的檢查會很有條理,可以略過一些複雜的pl/sql過濾條件細節,一般from之後的表名都不會是動態的。可以很方便地進行校驗。
但是讓人奇怪的是檢查了一圈,沒有發現問題。最後無奈之下就嘗試在指令碼中臨時加入一些資訊日誌,然後精確地定位出錯的問題才發現原來是檔案路徑的問題,
比如在庫檔案的根路徑在 /u01/app/plsql/test.sql
但是在開發目錄下執行指令碼的時候路徑是/u02/app/plsql/test.sql
這樣在shell指令碼中呼叫使用@test.sql的呼叫方式來執行pl/sql塊就很可能就是庫檔案的路徑而不是當前的開發目錄下了。
這種問題可能比較隱晦,出了問題確實不好查詢,可以使用絕對路徑來完成,絕對路徑可以根據shell變數來靈活的配置指定。
比如庫檔案路徑為我們定義變數LIB_CORE_PATH= /u01/app/plsql
定義開發路徑為 LIB_DEV_PATH=/u02/app/plsql,這樣在呼叫的時候就可以明確的指定需要使用哪個檔案了。
問題的校驗過程是枯燥繁瑣的,但是當明白了問題的原因之後,才發現都是有一些潛在的問題造成的。
我檢視了下,指令碼的結構比較清晰。
指令碼是有一個shell指令碼,一個sql檔案組成,shell指令碼作為基本的流程控制,sql檔案中是pl/sql指令碼。
大體明白了shell指令碼的部分,沒有做過多的追究,就開始瞭解pl/sql指令碼的內容了。
首先在pl/sql中宣告瞭大量的procedure,類似shell中的function,大概有10多個procedure
然後在最後使用一個類似main函式的pl/sql塊來判斷,什麼場景呼叫什麼procedure
指令碼結構類似
declare
flag varchar2(100); --宣告的變數
procedure proc1 is
begin
dbms_output.put_line('this is a test for procedure one'); --儲存過程的內容
end;
procedure proc2 is
begin
dbms_output.put_line('this is a test for procedure two);
end;
---more procedures defined here
begin --類似main方法的部分
flag:='a'; --宣告的變數透過shell變數傳入
if(flag='a') then
proc1; --呼叫儲存過程
end if;
if(flag='b') then
proc2;
end if;
end;
/
儲存過程大概有10多個,所以抓住重點來看整個shell指令碼就比較清晰了,要不直接上來就看儲存過程的細節,馬上就迷茫了。
明白了儲存過程的整體實現思路,來看丟擲的錯誤,錯誤是一個老套的ORA錯誤。
ORA-00942: table or view does not exist
根據錯誤的資訊,出錯的地方是在第一個儲存過程proc1
這個儲存過程的內容就很豐富了,裡面會呼叫動態sql建立view,建立臨時表。
細數下來,建立view,function,table的操作大概有6,7處。
如何儘快地排查出倒底是在哪個環節出錯還是比較棘手的。
比如一個呼叫動態pl/sql建立view, 建立的於假設為
create or replace view test_view as select xxxxx,xxxx,xxxxx, xxx from table1,table2,table3,table4
where xxxxxxx xxxxx xxxx
對於大量的這種操作一種比較快捷的方式就是使用explain plan來校驗。
因為有些pl/sql塊不能隨便執行,不能隨便建立view,table等,所以透過explain plan能夠快速的校驗出哪些表可能存在問題或者無法訪問等等。
如果存在,那麼很快就會解析生成執行計劃。影響是很小的。
SQL> explain plan for select test.object_id,t.object_id from test ,t where test.object_id=t.object_id;
Explained.
如果出錯,就會很明顯的得到錯誤的出處。
explain plan for select test.object_id,t.object_id from test ,ttttt t where test.object_id=t.object_id
*
ERROR at line 1:
ORA-00942: table or view does not exist
這樣就會很明顯的發現錯誤之處在於ttttt不可訪問或者不存在。
明白了這點,問題的檢查會很有條理,可以略過一些複雜的pl/sql過濾條件細節,一般from之後的表名都不會是動態的。可以很方便地進行校驗。
但是讓人奇怪的是檢查了一圈,沒有發現問題。最後無奈之下就嘗試在指令碼中臨時加入一些資訊日誌,然後精確地定位出錯的問題才發現原來是檔案路徑的問題,
比如在庫檔案的根路徑在 /u01/app/plsql/test.sql
但是在開發目錄下執行指令碼的時候路徑是/u02/app/plsql/test.sql
這樣在shell指令碼中呼叫使用@test.sql的呼叫方式來執行pl/sql塊就很可能就是庫檔案的路徑而不是當前的開發目錄下了。
這種問題可能比較隱晦,出了問題確實不好查詢,可以使用絕對路徑來完成,絕對路徑可以根據shell變數來靈活的配置指定。
比如庫檔案路徑為我們定義變數LIB_CORE_PATH= /u01/app/plsql
定義開發路徑為 LIB_DEV_PATH=/u02/app/plsql,這樣在呼叫的時候就可以明確的指定需要使用哪個檔案了。
問題的校驗過程是枯燥繁瑣的,但是當明白了問題的原因之後,才發現都是有一些潛在的問題造成的。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/8494287/viewspace-1422004/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- pl/sql程式碼中不得犯的錯誤!SQL
- shell動態指令碼和pl/sql動態指令碼的比較指令碼SQL
- pl/sql中錯誤的異常處理SQL
- shell指令碼中如何報錯即刻退出以及如何獲取子shell指令碼的錯誤資訊:set -o errexit指令碼
- 30個關於Shell指令碼的經典案例(中)指令碼
- Shell 中 $ 關於指令碼引數的幾種用法指令碼
- 關於pl/sql的程式碼保護SQL
- 【Shell】使用Shell指令碼快速完成SQL指令碼中重複枯燥的任務指令碼SQL
- 關於pl/sql中的繫結變數SQL變數
- Linux/Unix shell 指令碼中呼叫SQL,RMAN指令碼Linux指令碼SQL
- Shell排查錯
- 解決shell指令碼錯誤$’r’ command not found指令碼
- shell指令碼執行錯誤 $‘\r‘:command not found指令碼
- Bash 指令碼中的錯誤處理指令碼
- dbstart&dbshut指令碼中的錯誤指令碼
- 使用PL/Scope分析PL/SQL程式碼SQL
- 30個關於Shell指令碼的經典案例(下)指令碼
- 30個關於Shell指令碼的經典案例(上)指令碼
- ECSAPI中Signature錯誤的排查方法API
- 總結一篇shell除錯技巧及常見的指令碼錯誤除錯指令碼
- shell 指令碼的除錯問題指令碼除錯
- 【Oracle】--PL/SQL匯入Oracle sql指令碼"傻瓜教程"OracleSQL指令碼
- 關於 Bash 指令碼中 Shebang 的趣事指令碼
- shell指令碼報錯:[: missing `]‘指令碼
- 執行指令碼diagcollection.pl報錯指令碼GC
- SQL中關於NULL的程式碼SQLNull
- 執行指令碼寫入中間表錯誤返回錯誤資訊指令碼
- 關於vuex的錯誤Vue
- heartbeat錯誤排查
- 關於SQLRecoverableException問題的排查和分析SQLException
- 使用shell指令碼生成只讀許可權的sql指令碼指令碼SQL
- 使用批處理指令碼或SHELL配合SQL指令碼指令碼SQL
- 通過shell指令碼抓取awr報告中的問題sql指令碼SQL
- 透過shell指令碼抓取awr報告中的問題sql指令碼SQL
- IE 頁面不正常顯示 錯誤指令碼不報錯 指令碼除錯相關指令碼除錯
- 透過shell指令碼分析足彩指令碼
- 通過shell指令碼分析足彩指令碼
- PL/SQL:ORA-04063錯誤解決方法SQL