我一直在BEGIN ... END塊中將代碼小節偶然分組,當它看起來正確時。大多數情況下,當我正在處理更長的存儲過程並且需要在一個地方使用臨時變量時,我會爲該代碼的那部分聲明它。當我想識別和處理針對特定代碼段拋出的異常時,我也會這樣做。什麼時候應該嵌套PL/SQL BEGIN ... END塊?
爲什麼要在程序,函數或其他更大的PL/SQL塊中嵌套塊的其他原因?
我一直在BEGIN ... END塊中將代碼小節偶然分組,當它看起來正確時。大多數情況下,當我正在處理更長的存儲過程並且需要在一個地方使用臨時變量時,我會爲該代碼的那部分聲明它。當我想識別和處理針對特定代碼段拋出的異常時,我也會這樣做。什麼時候應該嵌套PL/SQL BEGIN ... END塊?
爲什麼要在程序,函數或其他更大的PL/SQL塊中嵌套塊的其他原因?
當你想在本地處理異常這樣的:
begin
for emp_rec in (select * from emp) loop
begin
my_proc (emp_rec);
exception
when some_exception then
log_error('Failed to process employee '||emp_rec.empno);
end;
end loop;
end;
在這個例子中,異常被處理,然後我們繼承和處理下一個員工。
的另一個用途是聲明局部變量具有有限的範圍是這樣的:
declare
l_var1 integer;
-- lots of variables
begin
-- lots of lines of code
...
for emp_rec in (select * from emp) loop
declare
l_localvar integer := 0;
begin
-- Use l_localvar
...
end
end loop;
end;
你要知道,想要做這往往是一個跡象,表明你的程序太大,應該被打破了:
declare
l_var1 integer;
-- lots of variables
...
procedure local_proc (emp_rec emp%rowtype):
l_localvar integer := 0;
begin
-- Use l_localvar
...
end
begin
-- lots of lines of code
...
for emp_rec in (select * from emp) loop
local_proc (emp_rec);
end loop;
end;
當我想創建特定於只存在於塊內的數據的過程時,我傾向於嵌套塊。這是一個人爲的例子:
BEGIN
FOR customer IN customers LOOP
DECLARE
PROCEDURE create_invoice(description VARCHAR2, amount NUMBER) IS
BEGIN
some_complicated_customer_package.create_invoice(
customer_id => customer.customer_id,
description => description,
amount => amount
);
END;
BEGIN
/* All three calls are being applied to the current customer,
even if we're not explicitly passing customer_id.
*/
create_invoice('Telephone bill', 150.00);
create_invoice('Internet bill', 550.75);
create_invoice('Television bill', 560.45);
END;
END LOOP;
END;
誠然,這通常不是必要的,但它已經來到了真的方便,當一個程序可以從許多地方調用。
我看不到需要 - 你已經在一個循環內。其次,存儲過程聲明不應該發生在循環之外嗎? – 2010-02-25 15:12:47
@OMG Ponies:這個例子的目的是爲了說明這樣一個事實,即可以在塊中聲明過程來利用該塊的數據,而不必通過參數傳遞信息。你是對的,如果你想明確地把'customer_id'作爲參數傳遞給'create_invoice',它就必須在循環之外聲明。根據我的經驗,我遇到了利用該塊信息更清晰的情況。 – 2010-02-25 15:59:03
嵌套BEGIN/END塊的一個原因是能夠處理代碼的特定本地部分的異常,並且可能在處理異常時繼續處理。
+1。 「開始/結束」塊的最佳做法是匿名塊,命名塊(過程/函數)或處理特定異常,如第一個示例中所述。在'begin/end'塊中嵌套一個'declare'語句,我會調用一個編程錯誤,因爲它引入了可變範圍碰撞的可能性,而這些都是一個調試的痛苦。 – 2010-02-25 18:48:51