EXECUTE 陳述式
EXECUTE 陳述式會執行備妥的 SQL 陳述式。
呼叫
此陳述式只能內嵌在應用程式中。 它是無法動態準備的可執行陳述式。
授權
- 模組中未定義之廣域變數的 READ 專用權
- 模組中所定義廣域變數之模組的 EXECUTE 專用權
- 包含模組中所定義廣域變數之模組的綱目 EXECUTEIN 專用權
- 包含模組中所定義廣域變數之模組的綱目 DATAACCESS 權限
- 未定義在模組中之廣域變數的 WRITE 專用權
- 模組中所定義廣域變數之模組的 EXECUTE 專用權
- 包含模組中所定義廣域變數之模組的綱目 EXECUTEIN 專用權
- 包含模組中所定義廣域變數之模組的綱目 DATAACCESS 權限
對於在陳述式執行時間執行授權檢查的陳述式 (DDL、GRANT 及 REVOKE 陳述式) ,陳述式授權 ID 所保留的專用權必須包括執行 PREPARE 陳述式所指定 SQL 陳述式所需的專用權。 陳述式的授權 ID 可能受到 DYNAMICRULES 連結選項的影響。
對於在陳述式準備時間 (DML) 執行授權檢查的陳述式,不會對 PREPARE 陳述式指定的 SQL 陳述式執行進一步授權檢查。
語法
- 1 An expression other than host-variable can only be used when the EXECUTE statement is used within a compound SQL (compiled) statement.
說明
- 陳述式名稱
- 識別要執行的備妥陳述式。 陳述式名稱 必須識別先前已備妥的陳述式,且備妥陳述式不能是 SELECT 陳述式。
- 變成
- 建立 目標 清單,用來從備妥陳述式中的輸出參數標記接收值。 對目標的每一個指派都會依序透過清單進行。 如果任何指派發生錯誤,則不會將值指派給目標,也不會再將值指派給目標。 任何已指派給目標的值仍會被指派。
對於動態 CALL 陳述式,在程序的 OUT 和 INOUT 引數中出現的參數標記是輸出參數標記。 如果陳述式中出現任何輸出參數標記,則必須指定 INTO 子句 (SQLSTATE 07007)。
- 指派-目標
- 識別一或多個用於指派輸出值的目標。 結果列中的第一個值會指派給清單中的第一個目標,第二個值會指派給第二個目標,依此類推。
如果 assignment-target 的資料類型是列類型,則必須正好指定一個 assignment-target (SQLSTATE 428HR) ,欄數必須符合中的欄位數 列類型及所提取列之直欄的資料類型必須可指派給列類型的對應欄位 (SQLSTATE 42821)。
如果 assignment-target 的資料類型是陣列元素,則必須正好指定一個 assignment-target 。
- 廣域變數名稱
- 識別作為指派目標的廣域變數。 主變數名稱
- 識別作為指派目標的主變數。 對於 LOB 輸出值,目標可以是一般主變數 (如果足夠大的話)、LOB 定位器變數或 LOB 檔案參照變數。 SQL-parameter-name
- 識別作為指派目標的常式參數。 SQL 變數名稱
- 識別作為指派目標的 SQL 變數。 SQL 變數在使用之前必須先宣告。 transition-variable-name
- 識別要在轉移列中更新的直欄。 transition-variable-name 必須識別觸發程式的主旨表格中的直欄,並選擇性地由識別新值的相關性名稱來限定。 陣列變數名稱
- 識別陣列類型的 SQL 變數、SQL 參數或廣域變數。
- array-index
- 指定陣列中哪一個元素將成為指派目標的表示式。 對於一般陣列, array-index 表示式必須可指派給 INTEGER (SQLSTATE 428H1) ,且不能是空值。 其值必須介於 1 與定義給陣列的基數上限 (SQLSTATE 2202E) 之間。 對於聯合陣列, array-index 表示式必須可指派給聯合陣列的索引資料類型 (SQLSTATE 428H1) ,且不能是空值。
欄位參照 - 識別作為指派目標之列類型值內的欄位。 field-reference 必須指定為限定的 field-name ,其中限定元識別在其中定義欄位的列值。
- DESCRIPTOR 結果描述子名稱
- 識別必須包含主變數有效說明的輸出 SQLDA。在處理 EXECUTE 陳述式之前,使用者必須在輸入 SQLDA 中設定下列欄位:
- SQLN ,指出 SQLDA 中提供的 SQLVAR 出現次數
- SQLDABC ,指出配置給 SQLDA 的儲存體位元組數
- SQLD ,指出處理陳述式時在 SQLDA 中使用的變數數目
- SQLVAR 出現項目,指出變數的屬性。
SQLDA 必須有足夠的儲存體,才能包含所有 SQLVAR 出現項目。 因此, SQLDABC 中的值必須大於或等於 16 + SQLN* (N) ,其中 N 是 SQLVAR 出現項目的長度。
如果必須容納 LOB 或結構化資料類型輸出資料,則每個輸出參數標記必須有兩個 SQLVAR 登錄。
SQLD 必須設為大於或等於零且小於或等於 SQLN 的值。
- 識別一或多個用於指派輸出值的目標。 結果列中的第一個值會指派給清單中的第一個目標,第二個值會指派給第二個目標,依此類推。
- USING
- 建立變數或表示式清單,這些變數或表示式的值會替代備妥陳述式中的輸入參數標記。對於動態 CALL 陳述式,程序的 IN 和 INOUT 引數中出現的參數標記是輸入參數標記。 對於所有其他動態陳述式,所有參數標記都是輸入參數標記。 如果陳述式中出現任何輸入參數標記,則必須指定 USING 子句 (SQLSTATE 07004)。
- input-host-variable, ...
- 根據宣告主變數的規則,識別在程式中宣告的主變數。 變數數目必須與備妥陳述式中的輸入參數標記數目相同。 第 n個變數對應於備妥陳述式中的第 n個參數標記。 在適當的情況下,可以提供定位器變數和檔案參照變數作為參數標記的值來源。 表示式
- 識別要在備妥陳述式中用作對應輸入參數標記之輸入的表示式。 只有在複合 SQL (已編譯) 陳述式內發出 EXECUTE 陳述式時,才能指定 主變數 以外的表示式。
- 描述子 輸入描述子名稱
- 識別必須包含主變數有效說明的輸入 SQLDA。在處理 EXECUTE 陳述式之前,使用者必須在輸入 SQLDA 中設定下列欄位:
- SQLN ,指出 SQLDA 中提供的 SQLVAR 出現次數
- SQLDABC ,指出配置給 SQLDA 的儲存體位元組數
- SQLD ,指出處理陳述式時在 SQLDA 中使用的變數數目
- SQLVAR 出現項目,指出變數的屬性。
SQLDA 必須有足夠的儲存體,才能包含所有 SQLVAR 出現項目。 因此, SQLDABC 中的值必須大於或等於 16 + SQLN* (N) ,其中 N 是 SQLVAR 出現次數的長度。
如果必須容納 LOB 或結構化資料類型輸入資料,則每個參數標記必須有兩個 SQLVAR 登錄。
SQLD 必須設為大於或等於零且小於或等於 SQLN 的值。
- FOR 主變數或整數常數 ROWS
指定來源資料的列數。 在 USING 子句中指定插入或合併作業的值。
將 host-variable 或 integer-constant 指派給整數值 k。 如果指定主變數,它必須是整數或 short 類型,且不得包含指示器變數。 k 必須在 2 到 32767 的範圍內。 如果未提供 FOR 主變數或整數常數 ROWS ,則會以大小為 1 的陣列來執行 SQL。
注意事項
- 在執行備妥陳述式之前,會將每一個輸入參數標記有效地取代為其對應變數或表示式的值。 對於類型化參數記號,目標變數或表示式的屬性是 CAST 規格指定的屬性。 對於非類型化參數記號,會根據參數記號的環境定義來決定目標變數或表示式的屬性。讓 V 表示對應於參數標記 P 的輸入變數或表示式。 根據將值指派給直欄的規則,將 V 的值指派給 P 的目標變數。 因此:
- V 必須與目標相容。
- 如果 V 是字串,則其長度不得大於目標的長度屬性。
- 如果 V 是數字,則其整數部分的絕對值不得大於目標整數部分的最大絕對值。
- 如果 V 的屬性與目標的屬性不同,則會轉換值以符合目標的屬性。
當執行備妥陳述式時,用來取代 P 的值是 P 的目標變數值或 P 的目標表示式結果。 例如,如果 V 是 CHAR (6) 且目標是 CHAR (8) ,則用來取代 P 的值是 V 以兩個空白填補的值。
- 若為動態 CALL 陳述式,在執行備妥陳述式之後,會將每一個 OUT 及 INOUT 引數的回覆值指派給對應於用於引數之輸出參數標記的指派目標。 對於類型化參數記號,目標變數的屬性是 CAST 規格指定的屬性。 對於非類型化參數標記,目標變數的屬性是由程序參數的定義所指定。讓 V 表示對應於參數標記 P 的輸出指派目標,該參數標記用於程序的引數 A。 根據從直欄擷取值的規則,將值 A 指派給 V。 因此:
- V 必須與 A 相容。
- 如果 V 是字串,則其長度不得小於 A 的長度,否則會截斷 A 的值。
- 如果 V 是數字,則其整數部分的最大絕對值不得小於 A 整數部分的絕對值。
- 如果 V 的屬性與 A 的屬性不同,則會轉換 A 的值以符合 V 的屬性。
- 動態 SQL 陳述式快取: 當第一次參照靜態 SQL 陳述式或第一次準備動態 SQL 陳述式時,執行動態及靜態 SQL 陳述式所需的資訊會放在資料庫套件快取中。 此資訊會保留在套件快取中,直到它變成無效、另一個陳述式需要快取空間或資料庫關閉為止。
執行或準備 SQL 陳述式時,與發出要求之應用程式相關的套件資訊會從系統型錄載入至套件快取。 個別 SQL 陳述式的實際執行檔區段也會放在快取中: 靜態 SQL 區段是從系統型錄讀取,並在第一次參照陳述式時放在套件快取中; 動態 SQL 區段在建立之後會直接放在快取中。 動態 SQL 區段可以由明確陳述式建立,例如 PREPARE 或 EXECUTE IMMEDIATE。 建立之後,如果因空間管理原因而刪除原始區段,或因環境中的變更而變成無效,系統可以透過隱含的陳述式準備來重建動態 SQL 陳述式的區段。
每一個 SQL 陳述式都會在資料庫層次快取,且可以在應用程式之間共用。 靜態 SQL 陳述式在使用相同套件的應用程式之間共用; 動態 SQL 陳述式在使用相同編譯環境及完全相同的陳述式文字的應用程式之間共用。 如果需要隱含的準備,應用程式所發出的每一個 SQL 陳述式的文字會在本端快取在應用程式內使用。 應用程式中的每一個 PREPARE 陳述式可以快取一個陳述式。 應用程式中的所有 EXECUTE IMMEDIATE 陳述式共用相同的空間,且所有這些 EXECUTE IMMEDIATE 陳述式一次只存在一個快取陳述式。 如果每次都使用不同的 SQL 陳述式多次發出相同的 PREPARE 或任何 EXECUTE IMMEDIATE 陳述式,則只會快取最後一個陳述式以供重複使用。 快取的最佳用法是在應用程式啟動時發出一次不同的 PREPARE 陳述式,然後視需要發出 EXECUTE 或 OPEN 陳述式。
快取動態 SQL 陳述式時,可以在多個工作單元上重複使用陳述式,而不需要重新準備陳述式,除非套件中準備的 SQL 陳述式與
KEEPDYNAMIC NO選項連結。 當環境變更時,必要的話,系統會重新編譯陳述式。下列事件是環境或資料物件變更的範例,這些變更會在下一個 PREPARE、EXECUTE、EXECUTE IMMEDIATE 或 OPEN 要求上隱含地準備快取的動態陳述式:- ALTER FUNCTION
- ALTER METHOD
- ALTER NICKNAME
- ALTER PROCEDURE
- ALTER SERVER
- ALTER TABLE
- ALTER TABLESPACE
- ALTER TYPE
- CREATE FUNCTION
- 建立函數對映
- CREATE INDEX
- CREATE METHOD
- CREATE PROCEDURE
- CREATE TABLE
- CREATE TEMPORARY TABLESPACE
- CREATE TRIGGER
- CREATE TYPE
- DROP (所有物件)
- 任何表格或索引上的 RUNSTATS
- 導致視圖變成無效的任何動作
- 更新任何系統型錄表格中的統計資料
- SET CURRENT DEGREE
- SET PATH
- SET QUERY OPTIMIZATION
- SET SCHEMA
- SET SERVER OPTION
下列清單概述快取動態 SQL 陳述式可預期的行為:- PREPARE 要求: 如果區段仍然有效,則相同陳述式的後續準備不會產生編譯陳述式的成本。 會傳回現行快取區段的成本及基數估計值。 這些值可能不同於先前針對相同 SQL 陳述式所傳回的任何 PREPARE 值。 除非陳述式與與
KEEPDYNAMIC NO連結的套件相關聯,否則您不需要在 COMMIT 或 ROLLBACK 陳述式之後發出 PREPARE 陳述式。 - EXECUTE 要求: 如果陳述式自原始 PREPARE 之後變成無效,則 EXECUTE 陳述式有時會產生隱含地準備陳述式的成本。 如果隱含地準備區段,則會使用現行環境,而不是原始 PREPARE 陳述式的環境。
- EXECUTE IMMEDIATE 要求: 如果區段仍然有效,則相同陳述式的後續 EXECUTE IMMEDIATE 陳述式將不會產生編譯陳述式的成本。
- OPEN 要求: 從原始 PREPARE 陳述式開始,如果陳述式變成無效,動態定義游標的 OPEN 要求有時會產生隱含準備陳述式的成本。 如果隱含地準備區段,則會使用現行環境,而不是原始 PREPARE 陳述式的環境。
- FETCH 要求: 不應預期任何行為變更。
- ROLLBACK: 只有在受回復作業影響的工作單元期間準備或隱含準備的動態 SQL 陳述式才會失效。 與
KEEPDYNAMIC NO連結的套件相關聯的非作用中動態 SQL 陳述式會在 ROLLBACK 作業之後從應用程式 SQL 環境定義中移除,且必須在應用程式可以執行它們之前重新明確準備。 動態 SQL 陳述式仍會在資料庫層次快取,因此如果區段仍然有效,則後續的 PREPARE 要求不會產生編譯陳述式的成本。 - COMMIT: 動態 SQL 陳述式不會失效,但會釋放任何獲得的鎖定。 未使用
WITH HOLD選項定義的游標會關閉並釋放其鎖定。 使用WITH HOLD選項定義的開放式 cusor 會保留其套件及區段鎖定,以在確定處理期間及之後保護作用中區段。 在交易界限之後,與KEEPDYNAMIC NO選項連結的動態 SQL 陳述式未處於備妥狀態,必須重新明確準備,應用程式才能執行它們。 為使用WITH HOLD選項定義的開啟游標所準備的 SELECT 陳述式會保持備妥狀態,直到在關閉游標的位置命中交易界限為止。 在確定作業之後,會從應用程式 SQL 環境定義中移除與連結至KEEPDYNAMIC NO之套件相關聯的非作用中動態 SQL 陳述式,且必須重新明確準備,應用程式才能執行它們。
如果在隱含準備期間發生錯誤,則會針對導致隱含準備的要求傳回錯誤 (SQLSTATE 56098)。
- 對於內嵌式 SQL 應用程式, db2dsdriver.cfg 關鍵字 Anonyblksqlexec 及 Db2® 登錄變數 DB2_ANONYMOUS_ESQL_EXECUTION_BLOCK 可讓您在 USING 及 INTO 子句中使用 INPUT 及 OUTPUT 參數,以取得輸出中的正確值。例如,當變數設為 TRUE 或 1 (或關鍵字設為 1) 時,您可以在 USING 及 INTO 子句中指定 INPUT 及 OUTPUT 參數:
如果未設定 DB2_ANONYMOUS_ESQL_EXECUTION_BLOCK 變數,或設為 FALSE 或 0 (或關鍵字設為 0) ,則只能在 USING 子句中指定 INPUT 參數,並在 INTO 子句中只指定 OUTPUT 參數。EXEC SQL EXECUTE db2strm1 INTO :h_name_in INDICATOR:h_name_in_ind, :h_name_out INDICATOR:h_name_out_ind USING :h_name_in, :h_name_out;注意: Db2 11.5.6 以及更新版本中提供 Anonyblksqlexec 關鍵字及 DB2_ANONYMOUS_ESQL_EXECUTION_BLOCK 登錄變數。
範例
h1 - h4 對應於 TDEPT 格式。 strcpy (s,"INSERT INTO TDEPT VALUES(?,?,?,?)");
EXEC SQL PREPARE DEPT_INSERT FROM :s;
.
.
(Check for successful execution and put values into :h1, :h2, :h3, :h4)
.
.
EXEC SQL EXECUTE DEPT_INSERT USING :h1, :h2,
:h3, :h4; EXECUTE S3 USING DESCRIPTOR :sqlda3 CREATE PROCEDURE GIVE_BONUS (IN EMPNO INTEGER,
IN DEPTNO INTEGER,
OUT CHECK INTEGER,
INOUT BONUS DEC(6,0))
...從 C 應用程式動態呼叫程序。 此程序會採用下列主變數作為輸入:- employee,員工的 ID 號碼
- dept,部門號碼
- 紅利,要決標給員工的紅利
- check_no,來自檢查的 ID 號碼
- 紅利: 實際紅利金額 (在任何調整之後)
strcpy (s, "CALL GIVE_BONUS(?, ?, ?, ?)");
EXEC SQL PREPARE DO_BONUS FROM :s;
.
.
/* Check for successful execution and put values into
:employee, :dept, and :bonus */
.
.
EXEC SQL EXECUTE DO_BONUS INTO :check_no, :bonus
USING :employee, :dept, :bonus;
.
.
/* Check for successful execution and process the
values returned in :check_no and :bonus */