Sql-Server

不熟悉的語法 - 在開始時使用大括號中的參數進行查詢

  • September 5, 2019

我使用以下語法在我們的一台伺服器上執行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

引用自:https://dba.stackexchange.com/questions/225905