今天有個同事問我乙個問題,他說執行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 ***xx,***x,***xx, *** from table1,table2,table3,table4
where ******x ***xx ***x
對於大量的這種操作一種比較快捷的方式就是使用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之後的表名都不會是動態的。可以很方便地進行校驗。
但是讓人奇怪的是檢查了一圈,沒有發現問題。最後無奈之下就嘗試在指令碼中臨時加入一些資訊日誌,然後精確地定位出錯的問題才發現原來是檔案路徑的問題,
這樣在shell指令碼中呼叫使用@test.sql的呼叫方式來執行pl/sql塊就很可能就是庫檔案的路徑而不是當前的開發目錄下了。
這種問題可能比較隱晦,出了問題確實不好查詢,可以使用絕對路徑來完成,絕對路徑可以根據shell變數來靈活的配置指定。
比如庫檔案路徑為我們定義變數lib_core_path=
問題的校驗過程是枯燥繁瑣的,但是當明白了問題的原因之後,才發現都是有一些潛在的問題造成的。
PL SQL中關於for的使用總結
從兩段 中分析出兩個使用總結 第一種形式 declare v max id number begin 將表中主鍵的最大值找出賦給v max id select max deptno into v max id from dept 對資料表進行操作 insert into dept values v ...
linux重啟tomcat的shell指令碼
基本思路 先檢查待重啟的tomcat的程序是否存在 存在則執行shutdown.然後再次檢查程序是否還存在,不存在則執行kill 然後刪除工作空間及10天前的日誌。最後執行啟動。bin sh tomname 1 ctompath opt tomcats echo restart tomcat sta...
關於PowerShell中建立受信任的指令碼
自從研究powershell以來,經歷了很多,過程是很艱辛啊。尤其是當我去網路上搜尋關於powershell的資料的時候,我發現找到的很少,甚至是少得可憐。或者可以說是一篇文章,大家互相 google幾頁以後,發現的資料基本如出一轍。沒辦法,只能自己研究。由於要用到執行策略的更改,所以涉及到自己建立...