宣告並指派變數和常數的值
在套件規格中宣告的變數或常數,可供任何可存取套件的程式使用。在套裝程式主體或子程式中宣告之變數或常數是該套裝程式或子程式的區域。宣告常數時,您必須指派初始值給常數。
PL/SQL 勝於 SQL 的一大優勢是 PL/SQL 可讓您宣告及使用變數和常數。
在套件規格中宣告的變數或常數,可供任何可存取套件的程式使用。在套裝程式主體或子程式中宣告之變數或常數是該套裝程式或子程式的區域。
變數會保存特定資料類型的值。程式可以在執行時期變更值。常數會保留無法變更的值。
變數或常數都可以具有任何的 PL/SQL 資料類型。宣告變數時,您可以將它指派為起始值;如果沒有,它的起始值為空值。宣告常數時,您必須指派初始值給常數。若要將起始值指派給變數或常數,請使用指派運算子 (:=)。
秘訣:宣告未變更為常數的所有值。這個做法可將已編譯的程式碼最佳化,並且讓您的原始程式碼變得容易維護。
另請參閱:Oracle Database PL/SQL Language Reference,瞭解變數和常數的一般資訊
教學課程:在子程式中宣告變數和常數
本教學課程示範如何使用 SQL Developer 工具「編輯」,宣告 EMP_EVAL.CALCULATE_SCORE 函數中的變數與常數。(此教學課程也是變更套裝程式主體的範例。)
EMP_EVAL.CALCULATE_SCORE 函數是在「教學課程:建立套裝程式規格」中指定。
宣告 CALCULATE_SCORE 函數中變數與常數的步驟:
-
在「連線」框架中,展開 hr_conn 。
-
在綱要物件類型清單中,展開套裝程式。
-
在薪資配套清單中,展開 EMP_EVAL 。
-
在選項清單中,以滑鼠右鍵按一下 EMP_EVAL 主體。
將會顯示選項清單。
-
在選項清單中,選取編輯。
便會顯示「EMP_EVAL 主體」窗格,其中顯示套裝程式主體的程式碼:
CREATE OR REPLACE PACKAGE BODY EMP_EVAL AS PROCEDURE eval_department ( dept_id IN NUMBER ) AS BEGIN -- TODO implementation required for PROCEDURE EMP_EVAL.eval_department NULL; END eval_department; FUNCTION calculate_score ( evaluation_id IN NUMBER , performance_id IN NUMBER) RETURN NUMBER AS BEGIN -- TODO implementation required for FUNCTION EMP_EVAL.calculate_score RETURN NULL; END calculate_score; END EMP_EVAL; -
在
RETURN NUMBER AS與BEGIN之間,新增這些變數與常數宣告:n_score NUMBER(1,0); -- variable n_weight NUMBER; -- variable max_score CONSTANT NUMBER(1,0) := 9; -- constant, initial value 9 max_weight CONSTANT NUMBER(8,8) := 1; -- constant, initial value 1The title of the EMP_EVAL Bodypane changes to italic font, indicating that the code is not saved in the database. -
從「檔案」功能表中選取儲存。
Oracle Database 會編譯並儲存變更的套裝程式主體。EMP_EVAL 主體窗格的標題已不再是斜體字。
另請參閱:
-
Oracle Database PL/SQL Language Reference,瞭解宣告變數和常數的一般資訊
確定變數、常數和參數之資料類型的正確性
請以 %TYPE 屬性宣告變數、常數及參數,以確保其資料類型正確。
在「教學課程:在子程式中宣告變數與常數」之後,EMP_EVAL.CALCULATE_SCORE 函式的代碼為:
FUNCTION calculate_score ( evaluation_id IN NUMBER
, performance_id IN NUMBER )
RETURN NUMBER AS
n_score NUMBER(1,0); -- variable
n_weight NUMBER; -- variable
max_score CONSTANT NUMBER(1,0) := 9; -- constant, initial value 9
max_weight CONSTANT NUMBER(8,8) := 1; -- constant, initial value 1
BEGIN
-- TODO implementation required for FUNCTION EMP_EVAL.calculate_score
RETURN NULL;
END calculate_score;
函數的變數、常數和參數代表 SCORES 和 PERFORMANCE_PARTS 表格的值 (在「建立表格」中建立):
-
變數 n_score 將保留欄 SCORE.SCORES 的值,而常數 max_score 將與這些值進行比較。
-
變數 n_weight 會保留欄 PERFORMANCE_PARTS.WEIGHT 的值,且常數 max_weight 將與這些值進行比較。
-
參數 evaluation_id 會保留欄位 SCORE.EVALUATION_ID 的值。
-
參數 performance_id 將保留欄 SCORE.PERFORMANCE_ID 的值。
因此,每個變數、常數和參數都具有與其對應資料欄相同的資料類型。
如果資料欄的資料類型變更,您想要將變數、常數和參數的資料型態變更為相同的資料類型;否則,CALCULATE_SCORE 函數就會變成無效。
若要確保變數、常數與參數的資料型態一律符合欄的資料型態,請使用 %TYPE 屬性來宣告這些變數。%TYPE 屬性提供表格資料欄或其他變數的資料類型,以確保正確的資料類型指派。
另請參閱:
-
Oracle Database PL/SQL 語言參照,瞭解有關
%TYPE屬性的詳細資訊 -
Oracle Database PL/SQL Language Reference,瞭解 %TYPE 屬性的語法
教學課程:將宣告變更為使用 %TYPE 屬性
本教學課程說明如何使用 SQL Developer 工具「編輯」,變更 EMP_EVAL.CALCULATE_SCORE 函數之變數、常數及正式參數的宣告,以使用 %TYPE 屬性。
EMP_EVAL.CALCULATE_SCORE 函數會顯示在教學課程:宣告子程式中的變數和常數中。
將 CALCULATE_SCORE 中的宣告變更為使用 %TYPE 的步驟:
-
在「連線」框架中,展開 hr_conn 。
-
在綱要物件類型清單中,展開套裝程式。
-
在薪資配套清單中,展開 EMP_EVAL 。
-
在選項清單中,以滑鼠右鍵按一下 EMP_EVAL 主體。
-
在選項清單中,選取編輯。
EMP_EVAL Bodypane 會出現,顯示套件主體的代碼:
CREATE OR REPLACE PACKAGE BODY emp_eval AS PROCEDURE eval_department ( dept_id IN NUMBER ) AS BEGIN -- TODO implementation required for PROCEDURE EMP_EVAL.eval_department NULL; END eval_department; FUNCTION calculate_score ( evaluation_id IN NUMBER , performance_id IN NUMBER ) RETURN NUMBER AS n_score NUMBER(1,0); -- variable n_weight NUMBER; -- variable max_score CONSTANT NUMBER(1,0) := 9; -- constant, initial value 9 max_weight CONSTANT NUMBER(8,8) := 1; -- constant, initial value 1 BEGIN -- TODO implementation required for FUNCTION EMP_EVAL.calculate_score RETURN NULL; END calculate_score; END emp_eval; -
在函數的程式碼中,進行下列變更:
FUNCTION calculate_score ( evaluation_id IN SCORES.EVALUATION_ID%TYPE , performance_id IN SCORES.PERFORMANCE_ID%TYPE) RETURN NUMBER AS n_score SCORES.SCORE%TYPE; n_weight PERFORMANCE_PARTS.WEIGHT%TYPE; max_score CONSTANT SCORES.SCORE%TYPE := 9; max_weight CONSTANT PERFORMANCE_PARTS.WEIGHT%TYPE := 1; -
在 EMP_EVAL 上按一下滑鼠右鍵。
-
在選項清單中,選取編輯。
EMP_EVAL 窗格開啟,顯示建立套裝程式的 CREATE PACKAGE 敘述句:
CREATE OR REPLACE PACKAGE EMP_EVAL AS PROCEDURE eval_department(dept_id IN NUMBER); FUNCTION calculate_score(evaluation_id IN NUMBER , performance_id IN NUMBER) RETURN NUMBER; END EMP_EVAL; -
在函數的程式碼中,進行下列變更:
FUNCTION calculate_score(evaluation_id IN scores.evaluation_id%TYPE , performance_id IN scores.performance_id%TYPE) -
在 EMP_EVAL 上按一下滑鼠右鍵。
-
在選項清單中,選取編譯。
-
在 EMP_EVAL 主體上按一下滑鼠右鍵。
-
在選項清單中,選取編譯。
指派變數值
您可以使用下列方式將值指定給變數:
-
使用指派運算子指派表示式的值
-
使用 SELECT INTO 或 FETCH 敘述句來指派表格中的值。
-
將它當作 OUT 或 IN OUT 參數傳送至子程式,然後在子程式內指派值。
-
連結變數與值。
另請參閱:
-
Oracle Database PL/SQL Language Reference,瞭解有關將值指派給變數的詳細資訊
-
Oracle Database 2 Day + Java 開發人員指南,瞭解連結變數的相關資訊
使用指派運算子指派變數值
使用指派運算子 (:=),您可以將表示式的值指派給子程式之宣告式或可執行部份中的變數。
在子程式的宣告部分中,您可以在宣告變數時,為變數指派起始值。語法如下:
variable_name data_type := expression;
在子程式的宣告部分中,您可以使用指派敘述句指派變數值。語法如下:
variable_name := expression;
範例 5-1 顯示要對 EMP_EVAL.CALCULATE_SCORE 函數進行的變更,以新增變數 running_total,並使用它作為函數的傳回值。指派運算子會同時出現在函數的宣告和可執行部分。(run_total 的資料類型必須為 NUMBER,而不是 SCORES.SCORE%TYPE 或 PERFORMANCE_PARTS.WEIGHT%TYPE,因為它包含兩個 NUMBER 值且具有不同精確度與縮放比例的乘積。)
另請參閱:
範例 5-1 使用指派運算子將值指派給變數
FUNCTION calculate_score(evaluation_id IN SCORES.EVALUATION_ID%TYPE
, performance_id IN SCORES.PERFORMANCE_ID%TYPE)
RETURN NUMBER AS
n_score SCORES.SCORE%TYPE;
n_weight PERFORMANCE_PARTS.WEIGHT%TYPE;
running_total NUMBER := 0;
max_score CONSTANT SCORES.SCORE%TYPE := 9;
max_weight CONSTANT PERFORMANCE_PARTS.WEIGHT%TYPE:= 1;
BEGIN
running_total := max_score * max_weight;
RETURN running_total;
END calculate_score;
使用 SELECT INTO 敘述句指派變數值
若要在子程式設計或套裝程式中使用表格值,您必須使用 SELECT INTO 敘述句將它們指派給變數。範例 5-2 顯示對 EMP_EVAL.CALCULATE_SCORE 函數所做的變更,讓函數從表格值計算 running_total。
範例 5-3 中的 ADD_EVAL 程序使用 EMPLOYEES 表格中對應列的值,將一列插入 EVALUATIONS 表格中。將 ADD_EVAL 程序新增至 EMP_EVAL 套裝程式的主體,但不會新增至規格。因為它不在規格中,所以 ADD_EVAL 是套件的本機元件,只能由套件中的其他子程式呼叫,而非從套件外部叫用。
另請參閱:Oracle Database PL/SQL Language Reference,瞭解有關 SELECT INTO 敘述句的詳細資訊
範例 5-2 使用 SELECT INTO 將表格值指派給變數
FUNCTION calculate_score ( evaluation_id IN scores.evaluation_id%TYPE
, performance_id IN scores.performance_id%TYPE )
RETURN NUMBER AS
n_score scores.score%TYPE;
n_weight performance_parts.weight%TYPE;
running_total NUMBER := 0;
max_score CONSTANT scores.score%TYPE := 9;
max_weight CONSTANT performance_parts.weight%TYPE:= 1;
BEGIN
SELECT s.score INTO n_score
FROM SCORES s
WHERE evaluation_id = s.evaluation_id
AND performance_id = s.performance_id;
SELECT p.weight INTO n_weight
FROM PERFORMANCE_PARTS p
WHERE performance_id = p.performance_id;
running_total := n_score * n_weight;
RETURN running_total;
END calculate_score;
範例 5-3 使用其他表格中的值插入表格資料列
PROCEDURE add_eval ( employee_id IN EMPLOYEES.EMPLOYEE_ID%TYPE
, today IN DATE )
AS
job_id EMPLOYEES.JOB_ID%TYPE;
manager_id EMPLOYEES.MANAGER_ID%TYPE;
department_id EMPLOYEES.DEPARTMENT_ID%TYPE;
BEGIN
INSERT INTO EVALUATIONS (
evaluation_id,
employee_id,
evaluation_date,
job_id,
manager_id,
department_id,
total_score
)
SELECT
evaluations_sequence.NEXTVAL, -- evaluation_id
add_eval.employee_id, -- employee_id
add_eval.today, -- evaluation_date
e.job_id, -- job_id
e.manager_id, -- manager_id
e.department_id, -- department_id
0 -- total_score
FROM employees e;
IF SQL%ROWCOUNT = 0 THEN
RAISE NO_DATA_FOUND;
END IF;
END add_eval;