2 回答

TA貢獻1828條經驗 獲得超4個贊
在ORACLE的PL/SQL里:
EXECUTE IMMEDIATE 代替了以前Oracle8i中DBMS_SQL package包.
它解析并馬上執行動態的SQL語句或非運行時創建的PL/SQL塊.動態創建和執行SQL語句性能超前,EXECUTE IMMEDIATE的目標在于減小企業費用并獲得較高的性能,較之以前它相當容易編碼.盡管DBMS_SQL仍然可用,但是推薦使用EXECUTE IMMEDIATE,因為它獲的收益在包之上。
-- 使用技巧
1. EXECUTE IMMEDIATE將不會提交一個DML事務執行,應該顯式提交
如果通過EXECUTE IMMEDIATE處理DML命令,
那么在完成以前需要顯式提交或者作為EXECUTE IMMEDIATE自己的一部分.
如果通過EXECUTE IMMEDIATE處理DDL命令,它提交所有以前改變的數據
2. 不支持返回多行的查詢,這種交互將用臨時表來存儲記錄(參照例子如下)或者用REF cursors.
3. 當執行SQL語句時,不要用分號,當執行PL/SQL塊時,在其尾部用分號.
4. 在Oracle手冊中,未詳細覆蓋這些功能。
下面的例子展示了所有用到Execute immediate的可能方面.希望能給你帶來方便.
5. 對于Forms開發者,當在PL/SQL 8.0.6.3.版本中,Forms 6i不能使用此功能.
EXECUTE IMMEDIATE -- 用法例子
1. 在PL/SQL運行DDL語句
begin
execute immediate 'set role all';
end;
2. 給動態語句傳值(USING 子句)
declare
l_depnam varchar2(20) := 'testing';
l_loc varchar2(10) := 'Dubai';
begin
execute immediate 'insert into dept values (:1, :2, :3)'
using 50, l_depnam, l_loc;
commit;
end;
3. 從動態語句檢索值(INTO子句)
declare
l_cnt varchar2(20);
begin
execute immediate 'select count(1) from emp'
into l_cnt;
dbms_output.put_line(l_cnt);
end;
4. 動態調用例程.例程中用到的綁定變量參數必須指定參數類型.
黓認為IN類型,其它類型必須顯式指定
declare
l_routin varchar2(100) := 'gen2161.get_rowcnt';
l_tblnam varchar2(20) := 'emp';
l_cnt number;
l_status varchar2(200);
begin
execute immediate 'begin ' || l_routin || '(:2, :3, :4); end;'
using in l_tblnam, out l_cnt, in out l_status;
if l_status != 'OK' then
dbms_output.put_line('error');
end if;
end;
5. 將返回值傳遞到PL/SQL記錄類型;同樣也可用%rowtype變量
declare
type empdtlrec is record (empno number(4),
ename varchar2(20),
deptno number(2));
empdtl empdtlrec;
begin
execute immediate 'select empno, ename, deptno ' ||
'from emp where empno = 7934'
into empdtl;
end;
6. 傳遞并檢索值.INTO子句用在USING子句前
declare
l_dept pls_integer := 20;
l_nam varchar2(20);
l_loc varchar2(20);
begin
execute immediate 'select dname, loc from dept where deptno = :1'
into l_nam, l_loc
using l_dept ;
end;
7. 多行查詢選項.對此選項用insert語句填充臨時表,
用臨時表進行進一步的處理,也可以用REF cursors糾正此缺憾.
declare
l_sal pls_integer := 2000;
begin
execute immediate 'insert into temp(empno, ename) ' ||
' select empno, ename from emp ' ||
' where sal > :1'
using l_sal;
commit;
end;
對于處理動態語句,EXECUTE IMMEDIATE 比以前可能用到的更容易并且更高效.
當意圖執行動態語句時,適當地處理異常更加重要.應該關注于捕獲所有可能的異常.

TA貢獻1886條經驗 獲得超2個贊
execute 為SQL命令,意為執行存儲過程,immediate 為執行的存儲過程名稱。
以下摘自MsSql幫助,別怪我復制哦,實在是幫助里描述的才最全面。
EXECUTE
執行標量值的用戶定義函數、系統過程、用戶定義存儲過程或擴展存儲過程。同時支持 Transact-SQL 批處理內的字符串的執行
若要喚醒調用函數,請使用 EXECUTE stored_procedure 中描述的語法。
語法
執行存儲過程:
[ [ EXEC [ UTE ] ]
{
[ @return_status = ]
{ procedure_name [ ;number ] | @procedure_name_var
}
[ [ @parameter = ] { value | @variable [ OUTPUT ] | [ DEFAULT ] ]
[ ,...n ]
[ WITH RECOMPILE ]
執行字符串:
EXEC [ UTE ] ( { @string_variable | [ N ] 'tsql_string' } [ + ...n ] )
參數
@return_status
是一個可選的整型變量,保存存儲過程的返回狀態。這個變量在用于 EXECUTE 語句前,必須在批處理、存儲過程或函數中聲明過。
在用于喚醒調用標量值用戶定義函數時,@return_status 變量可以是任何標量數據類型。
procedure_name
是擬調用的存儲過程的完全合法或者不完全合法的名稱。過程名稱必須符合標識符規則。有關更多信息,請參見使用標識符。無論服務器的代碼頁或排序方式如何,擴展存儲過程的名稱總是區分大小寫。
用戶可以執行在另一數據庫中創建的過程,只要該用戶擁有此過程或有在該數據庫中執行它的適當的權限。用戶可以在另一臺運行 Microsoft? SQL Server? 的服務器上執行過程,只要該用戶有適當的權限使用該服務器(遠程訪問),并能在數據庫中執行該過程。如果指定了服務器名稱但沒有指定數據庫名稱,SQL Server 會在用戶默認的數據庫中尋找該過程。
;number
是可選的整數,用于將相同名稱的過程進行組合,使得它們可以用一句 DROP PROCEDURE 語句除去。該參數不能用于擴展存儲過程。
在同一應用程序中使用的過程一般都以該方式組合。例如,在訂購應用程序中使用的過程可以 orderproc;1、orderproc;2 等來命名。DROP PROCEDURE orderproc 語句將除去整個組。在對過程分組后,不能除去組中的單個過程。例如,DROP PROCEDURE orderproc;2 是不允許的。有關過程組的更多信息,請參見 CREATE PROCEDURE。
@procedure_name_var
是局部定義變量名,代表存儲過程名稱。
@parameter
是過程參數,在 CREATE PROCEDURE 語句中定義。參數名稱前必須加上符號 (@)。在以 @parameter_name = value 格式使用時,參數名稱和常量不一定按照 CREATE PROCEDURE 語句中定義的順序出現。但是,如果有一個參數使用 @parameter_name = value 格式,則其它所有參數都必須使用這種格式。
默認情況下,參數可為空。如果傳遞 NULL 參數值,且該參數用于 CREATE 或 ALTER TABLE 語句中不允許為 NULL 的列(例如,插入至不允許為 NULL 的列),SQL Server 就會報錯。為避免將 NULL 參數值傳遞給不允許為 NULL 的列,可以在過程中添加程序設計邏輯或采用默認值(使用 CREATE 或 ALTER TABLE 語句中的 DEFAULT 關鍵字)。
value
是過程中參數的值。如果參數名稱沒有指定,參數值必須以 CREATE PROCEDURE 語句中定義的順序給出。
如果參數值是一個對象名稱、字符串或通過數據庫名稱或所有者名稱進行限制,則整個名稱必須用單引號括起來。如果參數值是一個關鍵字,則該關鍵字必須用雙引號括起來。
如果在 CREATE PROCEDURE 語句中定義了默認值,用戶執行該過程時可以不必指定參數。如果該過程使用了帶 LIKE 關鍵字的參數名稱,則默認值必須是常量,并且可以包含 %、_、[ ] 及 [^] 通配符。
默認值也可以為 NULL。通常,過程定義會指定當參數值為 NULL 時應該執行的操作。
@variable
是用來保存參數或者返回參數的變量。
OUTPUT
指定存儲過程必須返回一個參數。該存儲過程的匹配參數也必須由關鍵字 OUTPUT 創建。使用游標變量作參數時使用該關鍵字。
如果使用 OUTPUT 參數,目的是在調用批處理或過程的其它語句中使用其返回值,則參數值必須作為變量傳遞(即 @parameter = @variable)。如果一個參數在 CREATE PROCEDURE 語句中不是定義為 OUTPUT 參數,則對該參數指定 OUTPUT 的過程不能執行。不能使用 OUTPUT 將常量傳遞給存儲過程;返回參數需要變量名稱。在執行過程之前,必須聲明變量的數據類型并賦值。返回參數可以是 text 或 image 數據類型以外的任意數據類型。
DEFAULT
根據過程的定義,提供參數的默認值。當過程需要的參數值沒有事先定義好的默認值,或缺少參數,或指定了 DEFAULT 關鍵字,就會出錯。
n
是占位符,表示在它前面的項目可以多次重復執行。例如,EXECUTE 語句可以指定一個或者多個 @parameter、value 或 @variable。
WITH RECOMPILE
強制編譯新的計劃。如果所提供的參數為非典型參數或者數據有很大的改變,使用該選項。在以后的程序執行中使用更改過的計劃。該選項不能用于擴展存儲過程。建議盡量少使用該選項,因為它消耗較多系統資源。
@string_variable
是局部變量的名稱。@string_variable 可以是 char、varchar、nchar 或 nvarchar 數據類型,最大值為服務器的可用內存。如果字符串長度超過 4,000 個字符,則把多個局部變量串聯起來用于 EXECUTE 字符串。有關系統提供的 SQL Server 數據類型更多的信息,請參見數據類型。
[N]'tsql_string'
是一個常量,tsql_string 可以是 nvarchar 或 varchar 數據類型。如果包含 N,則該字符串將解釋為 nvarchar 數據類型,最大值為服務器的可用內存。如果字符串長度超過 4,000 個字符,則把多個局部變量串聯起來用于 EXECUTE 字符串。
注釋
如果過程名稱的前三個字符為 sp_,SQL Server 會在 Master 數據庫中尋找該過程。如果沒能找到合法的過程名稱,SQL Server 會尋找所有者名稱為 dbo 的過程。若要將存儲過程名稱解析為與系統存儲過程同名的用戶定義存儲過程,請提供一個完全合法的過程名稱。
參數可以通過利用 value 或 @parameter_name = value 來提供。參數不是事務的一個部分;因而如果事務中的參數值更改,且該事務在以后回滾,該參數值不會退回到以前的值。返回給調用方的值總是過程返回時的值。
當一個存儲過程調用另一個存儲過程時,會產生嵌套。當調用的過程開始執行時,嵌套級會增加,當調用過程執行結束時,嵌套級則會減少。嵌套級最高為32級,超過32級時,會導致整個調用過程鏈失敗。當前的嵌套級存儲在 @@NESTLEVEL 函數中。
SQL Server 目前使用返回值 0 到 -14 來表示存儲過程的執行狀態。值 –15 到 -99 留作后用。有關保留的返回狀態值的列表的更多信息,請參見 RETURN。
因為遠程存儲過程和擴展存儲過程不在事務的作用域中(除非在 BEGIN DISTRIBUTED TRANSACTION 語句中發出或者是和不同的配置選項一起使用),所以通過調用執行的命令不能回滾。有關更多信息,請參見系統存儲過程和 BEGIN DISTRIBUTED TRANSACTION。
當使用游標變量時,如果執行的過程傳遞一個分配有游標的游標變量,就會出錯。
在執行存儲過程時,如果語句是批處理中的第一個語句,則不一定要指定 EXECUTE 關鍵字。
使用帶字符串的 EXECUTE 命令
使用字符串串聯運算符 (+) 為動態執行創建長字符串。每個字符串表達式可以是 Unicode 與 non-Unicode 數據類型的混合。
盡管每個 [N] 'tsql_string' 或 @string_variable 不得超過 8,000 個字節,SQL Server 語法分析器中對這種串聯只進行邏輯處理而不占用物理內存。例如,該語句決不會生成長 16,000 個串聯起來的字符串:
EXEC('name_of_8000_char_string' + 'another_name_of_8000_char_string')
在 EXECUTE 語句執行前,不會編譯 EXECUTE 語句內的語句。
數據庫環境的更改只在 EXECUTE 語句結束前有效。例如,在這個例子的 EXEC 后,數據庫環境是 master:
USE master EXEC ("USE pubs") SELECT * FROM authors
權限
存儲過程的 EXECUTE 權限默認給該存儲過程的所有者,該所有者可以將此權限轉讓給其他用戶。當遇到 EXECUTE 語句時,即使 EXECUTE 語句是在存儲過程中,也會檢查在 EXECUTE 字符串內使用該語句的權限。當運行一個執行字符串的存儲過程時,系統會在執行該過程的用戶環境中,而不是在創建該過程的用戶環境中檢查權限。但是,如果某用戶擁有兩個存儲過程,并且第一個過程調用第二個過程,則在第二個過程中不進行 EXECUTE 權限檢查。
示例
A. 使用 EXECUTE 傳遞單個參數
showind 存儲過程需要參數 (@tabname),它是一個表的名稱。下面這個例子執行 showind 存儲過程,以 titles 為參數值。
說明 showind 存儲過程只是用來作為一個例子,pubs 數據庫并沒有此過程。
EXEC showind titles
在執行過程中變量可以顯式命名:
EXEC showind @tabname = titles
如果這是 isql 腳本或批處理中第一個語句,則 EXEC 語句可以省略:
showind titles
-或-
showind @tabname = titles
B. 使用多個參數與一個輸出參數
這個例子執行 roy_check 存儲過程,傳遞三個參數。第三個參數 @pc 是輸出參數。過程執行完后,返回變量可以從變量 @percent 得到。
說明 roy_check 存儲過程只是用作舉例,pubs 數據庫中并沒有此過程。
DECLARE @percent int
EXECUTE roy_check 'BU1032', 1050, @pc = @percent OUTPUT
SET Percent = @percent
C.使用帶一個變量的 EXECUTE 'tsql_string' 語句
這個例子顯示 EXECUTE 語句如何處理動態生成的、含有變量的字符串。這個例子創建 tables_cursor 游標來保存所有用戶定義表 (type = U) 的列表。
說明 此例子只用作舉例。
DECLARE tables_cursor CURSOR
FOR
SELECT name FROM sysobjects WHERE type = 'U'
OPEN tables_cursor
DECLARE @tablename sysname
FETCH NEXT FROM tables_cursor INTO @tablename
WHILE (@@FETCH_STATUS <> -1)
BEGIN
/* A @@FETCH_STATUS of -2 means that the row has been deleted.
There is no need to test for this because this loop drops all
user-defined tables. */.
EXEC ('DROP TABLE ' + @tablename)
FETCH NEXT FROM tables_cursor INTO @tablename
END
PRINT 'All user-defined tables have been dropped from the database.'
DEALLOCATE tables_cursor
D.使用帶遠程存儲過程的 EXECUTE 語句
這個例子在遠程服務器 SQLSERVER1 上執行 checkcontract 存儲過程,在 @retstat 中保存返回狀態,說明運行成功或失敗。
DECLARE @retstat int
EXECUTE @retstat = SQLSERVER1.pubs.dbo.checkcontract '409-56-4008'
E. 使用帶擴展存儲過程的 EXECUTE 語句
下例使用 xp_cmdshell 擴展存儲過程列出文件擴展名為 .exe 的所有文件的目錄。
USE master
EXECUTE xp_cmdshell 'dir *.exe'
F. 使用帶一個存儲過程變量的 EXECUTE 語句
這個例子創建一個代表存儲過程名稱的變量。
DECLARE @proc_name varchar(30)
SET @proc_name = 'sp_who'
EXEC @proc_name
G. 使用帶 DEFAULT 的 EXECUTE 語句
這個例子創建了一個存儲過程,過程中第一個和第三個參數為默認值。當運行該過程時,如果調用時沒有傳遞值或者指定了默認值,這些默認值就會賦給第一個和第三個參數。注意 DEFAULT 關鍵字有多種使用方法。
USE pubs
IF EXISTS (SELECT name FROM sysobjects
WHERE name = 'proc_calculate_taxes' AND type = 'P')
DROP PROCEDURE proc_calculate_taxes
GO
-- Create the stored procedure.
CREATE PROCEDURE proc_calculate_taxes (@p1 smallint = 42, @p2 char(1),
@p3 varchar(8) = 'CAR')
AS
SELECT *
FROM mytable
proc_calculate_taxes 存儲過程可以以多種組合方式執行:
EXECUTE proc_calculate_taxes @p2 = 'A'
EXECUTE proc_calculate_taxes 69, 'B'
EXECUTE proc_calculate_taxes 69, 'C', 'House'
EXECUTE proc_calculate_taxes @p1 = DEFAULT, @p2 = 'D'
EXECUTE proc_calculate_taxes DEFAULT, @p3 = 'Local', @p2 = 'E'
EXECUTE proc_calculate_taxes 69, 'F', @p3 = DEFAULT
EXECUTE proc_calculate_taxes 95, 'G', DEFAULT
EXECUTE proc_calculate_taxes DEFAULT, 'H', DEFAULT
EXECUTE proc_calculate_taxes DEFAULT, 'I', @p3 = DEFAULT
添加回答
舉報