SEa*_*986 6 sql-server syntax parameter sql-server-2016 sp-whoisactive
我已使用以下语法在我们的一台服务器上运行sp_WhoIsActive:
sp_whoisactive @get_plans = 1, @show_sleeping_spids = 0, @get_outer_command = 1, @get_locks = 1
Run Code Online (Sandbox Code Playgroud)
并用sql_command(显示的列@get_outer_command设置为1)找到了一个spid,如下所示
(@p1 int,@p2 int)
Exec MyDatabase.MyProc @p1 @p2
Run Code Online (Sandbox Code Playgroud)
当我尝试在我的测试 Adventureworks 数据库上使用此语法运行查询时:
(@be int)
SELECT *
FROM Person.Person
WHERE BusinessEntityID = @be
Run Code Online (Sandbox Code Playgroud)
我收到错误
消息 1050,级别 15,状态 1,第 1 行 此语法仅适用于参数化查询。消息 137,级别 15,状态 2,第 4 行 必须声明标量变量“@FN”。
所以这似乎与参数化查询有关。这是有道理的,因为变量 @be 永远不会被设置为一个值
这里发生了什么?
你是对的,显示的 (@be int) 适用于参数化查询。应用程序通常使用 参数化查询sp_executesql,然后将它们发送到 sql 服务器。
查询将被缓存为(variables)QueryText 。当然,这些值不会缓存在文本中,因为查询是参数化的。
参数化查询示例
测试数据
CREATE SCHEMA PERSON;
CREATE TABLE Person.Person( BusinessEntityID int );
INSERT INTO Person.Person(BusinessEntityID)
VALUES(1),(2),(3);
Run Code Online (Sandbox Code Playgroud)
询问
exec sp_executesql N'SELECT * FROM Person.Person WHERE BusinessEntityID = @be',N'@be int',@be=2
Run Code Online (Sandbox Code Playgroud)
使用此查询查看缓存中的结果
select text from sys.dm_exec_query_stats
cross apply sys.dm_exec_sql_text(sql_handle)
where text like '%Person%';
Run Code Online (Sandbox Code Playgroud)
或者
(@be int)SELECT * FROM Person.Person WHERE BusinessEntityID = @be
Run Code Online (Sandbox Code Playgroud)
使用一个程序,缓存会有所不同
创建程序
use test
go
create procedure dbo.myproc @dbname varchar(255)
as
select * from sys.databases where name = @dbname
Run Code Online (Sandbox Code Playgroud)
运行过程
exec dbo.myproc @dbname= 'master';
Run Code Online (Sandbox Code Playgroud)
缓存中的结果
select text from sys.dm_exec_query_stats
cross apply sys.dm_exec_sql_text(sql_handle)
where text like '%myproc%';
Run Code Online (Sandbox Code Playgroud)
或者
create procedure dbo.myproc @dbname varchar(255) as select * from sys.databases where name = @dbname
Run Code Online (Sandbox Code Playgroud)
启用强制参数化时也会发生这种情况
启用强制参数化
ALTER DATABASE test SET PARAMETERIZATION FORCED
Run Code Online (Sandbox Code Playgroud)
相同的查询,不带参数
SELECT *
FROM Person.Person
WHERE BusinessEntityID = 5
Run Code Online (Sandbox Code Playgroud)
缓存中的结果
select text from sys.dm_exec_query_stats
cross apply sys.dm_exec_sql_text(sql_handle)
where text like '%Person%'
Run Code Online (Sandbox Code Playgroud)
(@0 int)select * from Person . Person where BusinessEntityID = @0
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
949 次 |
| 最近记录: |