Sql-Server
不熟悉的語法 - 在開始時使用大括號中的參數進行查詢
我使用以下語法在我們的一台伺服器上執行sp_WhoIsActive :
sp_whoisactive @get_plans = 1, @show_sleeping_spids = 0, @get_outer_command = 1, @get_locks = 1
並找到了一個帶有 sql_command 的 spid(設置為 1 時顯示的列
@get_outer_command
)如下(@p1 int,@p2 int) Exec MyDatabase.MyProc @p1 @p2
當我嘗試在我的測試 Adventureworks 數據庫上使用此語法執行查詢時:
(@be int) SELECT * FROM Person.Person WHERE BusinessEntityID = @be
我得到錯誤
Msg 1050, Level 15, State 1, Line 1 此語法僅允許用於參數化查詢。Msg 137, Level 15, State 2, Line 4 必須聲明標量變數“@FN”。
所以它似乎與參數化查詢有關。這是有道理的,因為變數 @be 永遠不會被設置為一個值
這裡發生了什麼?
沒錯,顯示的 (@be int) 適用於參數化查詢。應用程序經常使用 參數化查詢
sp_executesql
,然後將它們發送到 sql server。查詢將被記憶體為*(變數)QueryText* 。當然,這些值不會記憶體在文本中,因為查詢是參數化的。
參數化查詢範例
測試數據
CREATE SCHEMA PERSON; CREATE TABLE Person.Person( BusinessEntityID int ); INSERT INTO Person.Person(BusinessEntityID) VALUES(1),(2),(3);
詢問
exec sp_executesql N'SELECT * FROM Person.Person WHERE BusinessEntityID = @be',N'@be int',@be=2
使用此查詢查看記憶體中的結果
select text from sys.dm_exec_query_stats cross apply sys.dm_exec_sql_text(sql_handle) where text like '%Person%';
或者
(@be int)SELECT * FROM Person.Person WHERE BusinessEntityID = @be
使用過程記憶體會有所不同
創建過程
use test go create procedure dbo.myproc @dbname varchar(255) as select * from sys.databases where name = @dbname
執行過程
exec dbo.myproc @dbname= 'master';
記憶體中的結果
select text from sys.dm_exec_query_stats cross apply sys.dm_exec_sql_text(sql_handle) where text like '%myproc%';
或者
create procedure dbo.myproc @dbname varchar(255) as select * from sys.databases where name = @dbname
啟用強制參數化時也會發生這種情況
啟用強制參數化
ALTER DATABASE test SET PARAMETERIZATION FORCED
相同的查詢,沒有參數
SELECT * FROM Person.Person WHERE BusinessEntityID = 5
記憶體中的結果
select text from sys.dm_exec_query_stats cross apply sys.dm_exec_sql_text(sql_handle) where text like '%Person%'
(@0 int)select * from Person . Person where BusinessEntityID = @0