存儲過程怎么查看執行sql語句
MSSQL為我們提供了兩種動態執行SQL語句的命令,分別是EXEC和 sp_executesql;通常,sp_executesql則更具有優勢,它提供了輸入輸出接口,而EXEC沒有。
還有一個最大的好處就是利用 sp_executesql,能夠重用執行計劃,這就大大提供了執行性能,還可以編寫更安全的代碼。EXEC在某些情況下會更靈活。
除非您有令人信服的理 由使用EXEC,否側盡量使用sp_*的使用 EXEC命令有兩種用法,一種是執行一個存儲過程,另一種是執行一個動態的批處理。以下所講的都是第二種用法。
下面先使用EXEC演示一個例子,代碼1 代碼 DECLARE @TableName VARCHAR(50),@Sql NVARCHAR (MAX),@OrderID INT; SET @TableName = 'Orders'; SET @OrderID = 10251; SET @sql = 'SELECT * FROM '+QUOTENAME(@TableName) +'WHERE OrderID = '+ CAST(@OrderID AS VARCHAR(10))+' ORDER BY ORDERID DESC' EXEC(@sql); 注:這里的EXEC括號中只允許包含一個字符串變量,但是可以串聯多個變量,如果我們這樣寫EXEC:EXEC('SELECT TOP('+ CAST(@TopCount AS VARCHAR(10)) +')* FROM '+ QUOTENAME(@TableName) +' ORDER BY ORDERID DESC'); SQL編譯器就會報錯,編譯不通過,而如果我們這樣:EXEC(@sql+@sql2+@sql3); 編譯器就會通過; 所以最佳的做法是把代碼構造到一個變量中,然后再把該變量作為EXEC命令的輸入參數,這樣就不會受限制了。 EXEC的缺點是不提供接口,這里的接口是指,它不能執行一個包含一個帶變量符的批處理,如下 代碼 DECLARE @TableName VARCHAR(50),@Sql NVARCHAR(MAX),@OrderID INT; SET @TableName = 'Orders'; SET @OrderID = 10251; SET @sql = 'SELECT * FROM '+QUOTENAME(@TableName) + 'WHERE OrderID = @OrderID ORDER BY ORDERID DESC' EXEC(@sql); 關鍵就在SET @sql這一句話中,如果我們運行這個批處理,編譯器就會產生一下錯誤 Msg 137, Level 15, State 2, Line 1 必須聲明標量變量 "@OrderID"。
使用EXEC時,如果您想訪問變量,必須把變量內容串聯到動態構建的代碼字符串中,如:SET @sql = 'SELECT * FROM '+QUOTENAME(@TableName) + 'WHERE OrderID = '+CAST(@OrderID AS VARCHAR(10))+' ORDER BY ORDERID DESC' 串聯變量的內容也存在性能方面的弊端。SQL Server為每一個的查詢字符串創建新的執行計劃,即使查詢模式相同也是這樣。
為演示這一點,先清空緩存中的執行計劃 DBCC FREEPROCCACHE (這個不是本文所涉及的內容,您可以查看MS的MSDN) 將代碼1運行3次,分別對@OrderID 賦予下面3個值,10251,10252,10253。然后使用下面的代碼查詢 SELECT cacheobjtype,objtype,usecounts,sql FROM *heobjects WHERE sql NOT LIKE '%cach%' AND sql NOT LIKE '%sys.%' 點擊F5運行,我們可以看到,每執行一次都要產生一次的編譯,執行計劃沒有得到充分重用。
EXEC除了不支持動態批處理中的輸入參數外,他也不支持輸出參數。默認情況下,EXEC把查詢的輸出返回給調用者。
例如下面代碼返回Orders表中所有的記錄數 DECLARE @sql NVARCHAR(MAX) SET @sql = 'SELECT COUNT(ORDERID) FROM Orders'; EXEC(@sql); 然而,如果你要把輸出返回給調用批處理中的變量,事情就沒有那么簡單了。為此,你必須使用INSERT EXEC語法把輸出插入到一個目標表中,然后從這表中獲取值后賦給該變量,就像這樣:代碼 DECLARE @sql NVARCHAR(MAX),@RecordCount INT SET @sql = 'SELECT COUNT(ORDERID) FROM Orders'; CREATE TABLE #T(TID INT); INSERT INTO #T EXEC(@sql); SET @RecordCount = (SELECT TID FROM #T) SELECT @RecordCount DROP TABLE #*_executesql的使用 sp_executesql命令在SQL Server中引入的比EXEC命令晚一些,它主要為重用執行計劃提供更好的支持。
為了和EXEC作一個鮮明的對比,我們看看如果用代碼1的代碼,把EXEC換成sp_executesql,看看是否得到我們所期望的結果 代碼 DECLARE @TableName VARCHAR(50),@sql NVARCHAR(MAX),@OrderID INT ,@sql2 NVARCHAR(MAX); SET @TableName = 'Orders '; SET @OrderID = 10251; SET @sql = 'SELECT * FROM '+QUOTENAME(@TableName) + ' WHERE OrderID = '+CAST(@OrderID AS VARCHAR(50)) + ' ORDER BY ORDERID DESC' EXEC sp_executesql @sql 注意最后一行;事實證明可以運行;sp_executesql提供接口 sp_executesql命令比EXEC命令更靈活,因為它提供一個接口,該接口及支持輸入參數也支持輸出參數。這功能使你可以創建帶參數的查詢字符串,這樣就可以比EXEC更好的重用執行計劃,sp_executesql的構成與存儲過程非常相似,不同之處在于你是動態構建代碼。
它的構成包括:代碼快,參數聲明部分,參數賦值部分。說了這么多,還是看看它的語法:EXEC sp_executesql @stmt=
怎樣SQL存儲過程中執行動態SQL語句
MSSQL為我們提供了兩種動態執行SQL語句的命令,分別是EXEC和sp_executesql;通常,sp_executesql則更具有優勢,它提供了輸入輸出接口,而EXEC沒有。
還有一個最大的好處就是利用sp_executesql,能夠重用執行計劃,這就大大提供了執行性能,還可以編寫更安全的代碼。EXEC在某些情況下會更靈活。
除非您有令人信服的理由使用EXEC,否側盡量使用sp_*的使用 EXEC命令有兩種用法,一種是執行一個存儲過程,另一種是執行一個動態的批處理。以下所講的都是第二種用法。
下面先使用EXEC演示一個例子,代碼1代碼 DECLARE @TableName VARCHAR(50),@Sql NVARCHAR (MAX),@OrderID INT; SET @TableName = 'Orders'; SET @OrderID = 10251; SET @sql = 'SELECT * FROM '+QUOTENAME(@TableName) +'WHERE OrderID = '+ CAST(@OrderID AS VARCHAR(10))+' ORDER BY ORDERID DESC' EXEC(@sql);注:這里的EXEC括號中只允許包含一個字符串變量,但是可以串聯多個變量,如果我們這樣寫EXEC:EXEC('SELECT TOP('+ CAST(@TopCount AS VARCHAR(10)) +')* FROM '+ QUOTENAME(@TableName) +' ORDER BY ORDERID DESC'); SQL編譯器就會報錯,編譯不通過,而如果我們這樣:EXEC(@sql+@sql2+@sql3);編譯器就會通過; 所以最佳的做法是把代碼構造到一個變量中,然后再把該變量作為EXEC命令的輸入參數,這樣就不會受限制了。 EXEC的缺點是不提供接口,這里的接口是指,它不能執行一個包含一個帶變量符的批處理,如下代碼 DECLARE @TableName VARCHAR(50),@Sql NVARCHAR(MAX),@OrderID INT; SET @TableName = 'Orders'; SET @OrderID = 10251; SET @sql = 'SELECT * FROM '+QUOTENAME(@TableName) + 'WHERE OrderID = @OrderID ORDER BY ORDERID DESC' EXEC(@sql);關鍵就在SET @sql這一句話中,如果我們運行這個批處理,編譯器就會產生一下錯誤 Msg 137, Level 15, State 2, Line 1 必須聲明標量變量 "@OrderID"。
使用EXEC時,如果您想訪問變量,必須把變量內容串聯到動態構建的代碼字符串中,如:SET @sql = 'SELECT * FROM '+QUOTENAME(@TableName) + 'WHERE OrderID = '+CAST(@OrderID AS VARCHAR(10))+' ORDER BY ORDERID DESC'串聯變量的內容也存在性能方面的弊端。SQL Server為每一個的查詢字符串創建新的執行計劃,即使查詢模式相同也是這樣。
為演示這一點,先清空緩存中的執行計劃 DBCC FREEPROCCACHE (這個不是本文所涉及的內容,您可以查看MS的MSDN) 將代碼1運行3次,分別對@OrderID 賦予下面3個值,10251,10252,10253。然后使用下面的代碼查詢SELECT cacheobjtype,objtype,usecounts,sql FROM *heobjects WHERE sql NOT LIKE '%cach%' AND sql NOT LIKE '%sys.%' 點擊F5運行,我們可以看到,每執行一次都要產生一次的編譯,執行計劃沒有得到充分重用。
EXEC除了不支持動態批處理中的輸入參數外,他也不支持輸出參數。默認情況下,EXEC把查詢的輸出返回給調用者。
例如下面代碼返回Orders表中所有的記錄數DECLARE @sql NVARCHAR(MAX) SET @sql = 'SELECT COUNT(ORDERID) FROM Orders'; EXEC(@sql);然而,如果你要把輸出返回給調用批處理中的變量,事情就沒有那么簡單了。為此,你必須使用INSERT EXEC語法把輸出插入到一個目標表中,然后從這表中獲取值后賦給該變量,就像這樣:代碼DECLARE @sql NVARCHAR(MAX),@RecordCount INT SET @sql = 'SELECT COUNT(ORDERID) FROM Orders'; CREATE TABLE #T(TID INT); INSERT INTO #T EXEC(@sql); SET @RecordCount = (SELECT TID FROM #T) SELECT @RecordCount DROP TABLE #*_executesql的使用sp_executesql命令在SQL Server中引入的比EXEC命令晚一些,它主要為重用執行計劃提供更好的支持。
為了和EXEC作一個鮮明的對比,我們看看如果用代碼1的代碼,把EXEC換成sp_executesql,看看是否得到我們所期望的結果代碼DECLARE @TableName VARCHAR(50),@sql NVARCHAR(MAX),@OrderID INT ,@sql2 NVARCHAR(MAX); SET @TableName = 'Orders '; SET @OrderID = 10251; SET @sql = 'SELECT * FROM '+QUOTENAME(@TableName) + ' WHERE OrderID = '+CAST(@OrderID AS VARCHAR(50)) + ' ORDER BY ORDERID DESC' EXEC sp_executesql @sql注意最后一行;事實證明可以運行;sp_executesql提供接口sp_executesql命令比EXEC命令更靈活,因為它提供一個接口,該接口及支持輸入參數也支持輸出參數。這功能使你可以創建帶參數的查詢字符串,這樣就可以比EXEC更好的重用執行計劃,sp_executesql的構成與存儲過程非常相似,不同之處在于你是動態構建代碼。
它的構成包括:代碼快,參數聲明部分,參數賦值部分。說了這么多,還是看看它的語法:EXEC sp_executesql @stmt=
存儲過程與SQL語句是怎樣的
我的一位朋友說:他從臺灣知名技術作家李維先生的一本書中獲悉,如果用存儲過程封裝SQL語句,系統效率將有極大提升。
他做過實驗!!! --我相信朋友做過實驗,盡管非親眼所見。不過我估計他的實驗有問題,那樣的實驗不但蒙蔽了他,也蒙蔽了李維先生(如果他的著作中的內容沒有被誤會),甚至更多的人。
然而我必須拿出證據,方能使人信服。 后來遇到一個具體的問題:客戶端經常要向數據庫插入記錄。
在J2EE中,一個 Entity Bean Home 的 create 方法調用中,一般就沒用存儲過程。朋友立馬在觀點上持反對意見( 可能是因為他暫時有來得及否決J2EE ),認為要是J2EE能夠將“插入記錄”諸如此類動作改為對存儲過程的調用就好了。
我們因此再次發生爭論(我僅是反對朋友的看法,但也沒提出任何我自己的看法,因為要下一個結論是很不容易的)。最后我不得已而做了實驗,分別在 Oracle 10g 和 postgreSQL 8。
0。1 上。
實驗內容如下: A、建表腳本: create table ztest( fieldA integer primary key, fieldB varchar(128), fieldC varchar(128) ) B、客戶端請求 DBMS 執行的 insert SQL語句: insert into ztest values( ?1, ?2, ?3 ); -- ?1,?2,?3 將在運行時以合理的值替代之 C、客戶端調用的存儲過程(JDBC CallableStatement 調用): Oracle:(調用方式 call up_add(。 。
。),) create or replace procedure up_add( fieldA integer, fieldB varchar, fieldC varchar ) is begin insert into ztest values( fieldA, fieldB, fieldC); end; postgreSQL:(客戶端調用方式 select uf_add(。
。
) ) CREATE OR REPLACE FUNCTION uf_add (integer, varchar, varchar) RETURNS void AS' begin insert into ztest values($1,$2,$3); return; end; 'LANGUAGE 'plpgsql' VOLATILE RETURNS NULL ON NULL INPUT SECURITY INVOKER; D、環境: postgreSQL:數據庫服務器與客戶端程序“都在本機”并“同時運行” Oracle: 獨立數據庫服務器(測試時始終有人在慢慢打字,應該對機器性能無影響) 測試: 通過不同方式( 即 請求DBMS執行SQL語句 和 調用DBMS邏輯等價的存儲過程)向測試表中連續加入 1024 記錄 經多次反復測試,得結果如下 postgreSQL: 兩種方式下,測試時間均為 21- 24 seconds 之間 (每個結果的測試環境一致) Oracle: 8次 SQL 執行請求分別用時(ms) 5422 4750 3875 3812 5672 3531 3484 3547 6次 存儲過程調用分別用時(ms) 4578 4500 6297 4219 4547 5734 (每個結果的測試環境一致)由此可知,存儲過程封裝簡單的 SQL 語句,效率相當,且可能更低。 但很多朋友的確得出結論:存儲過程的確比SQL快。
為什么?---- 因為他們測試時寫了一個不具實際意義,同時也與SQL語句的“一次客戶端調用”不具可比性的測試用存儲過程。Oracle PL/SQL 描述方式如下,該方法一次調用就可以向數據表添加 1024 條記錄,連網絡通訊都省了。
怪不得性能有“千倍差異”! create or replace procedure up_add( ) is declare n:integer; begin n := 0; while( n 它與客戶端一次提交單條 SQL 語句沒有可比性:當一次只需要向DBMS提交一條新記錄,要這個存儲過程干什么呢?。
怎樣SQL存儲過程中執行動態SQL語句
*的使用
EXEC命令有兩種用法,一種是執行一個存儲過程,另一種是執行一個動態的批處理。以下所講的都是第二種用法。
下面先使用EXEC演示一個例子,代碼1
DECLARE @TableName VARCHAR(50),@Sql NVARCHAR (MAX),@OrderID INT;
SET @TableName = 'Orders';
SET @OrderID = 10251;
SET @sql =
'SELECT * FROM '+QUOTENAME(@TableName) +'WHERE OrderID = '+
CAST(@OrderID AS VARCHAR(10))+' ORDER BY ORDERID DESC'
EXEC(@sql);
sp_executesql命令在SQL Server中引入的比EXEC命令晚一些,它主要為重用執行計劃提供更好的支持。
為了和EXEC作一個鮮明的對比,我們看看如果用代碼1的代碼,把EXEC換成sp_executesql,看看是否得到我們所期望的結果
DECLARE @TableName VARCHAR(50),@sql NVARCHAR(MAX),@OrderID INT ,@sql2 NVARCHAR(MAX);
SET @TableName = 'Orders ';
SET @OrderID = 10251;
SET @sql = 'SELECT * FROM '+QUOTENAME(@TableName) + ' WHERE OrderID = '+CAST(@OrderID AS VARCHAR(50)) + ' ORDER BY ORDERID DESC'
EXEC sp_executesql @sql
使用SQL語句創建存儲過程
使用SQL語句創建存儲的具體過程如下:
1、首先,打開企業管理器,選擇【工具】-【查詢分析器】:
2、然后,輸入SQL語句。如下:
CREATE PROCEDURE byroyalty1 @percentage int
AS
select au_id from titleauthor
where *yper = @percentage
GO
3、然后,點擊確定之后,命令就會自動添加進查詢中:
4、然后執行一下剛輸入的命令:
5、最后,就可以在彈出的小窗口中查看存儲過程了:
數據庫存儲過程是在sql語句下執行的嗎
一般分為十種情況,每種語法各不相同:
1、 創建語法
create proc | procedure pro_name
[{@參數數據類型} [=默認值] [output],
{@參數數據類型} [=默認值] [output],
。.
]
as
SQL_statements
2、 創建不帶參數存儲過程
--創建存儲過程
if (exists (select * from *s where name = 'proc_get_student'))
drop proc proc_get_student
go
create proc proc_get_student
as
select * from student;
--調用、執行存儲過程
exec proc_get_student;
3、 修改存儲過程
--修改存儲過程
alter proc proc_get_student
as
select * from student;
4、 帶參存儲過程
--帶參存儲過程
if (object_id('proc_find_stu', 'P') is not null)
drop proc proc_find_stu
go
轉載請注明出處華閱文章網 » 執行存儲過程sql語句