SQL Server:检测非参数化查询

use*_*179 5 sql sql-server security parameterization parameterized-query

我有一个由过去的开发人员执行过编程的客户。他们的代码最近变得可疑,我想知道他们是否在使用参数化查询。我希望可以通过SQL Server检测到非参数化的请求,但是我还没有找到一种方法来执行此操作。我了解并非所有查询都需要参数化,因为查询可能类似于

select count(*) from Customers
Run Code Online (Sandbox Code Playgroud)

但是,如果SQL Server可以通过编程方式告诉我哪些查询具有任何字符串常量输入而不是参数输入,那就太好了。顺便说一句,关闭所有SQL查询并用@符号删除所有行的操作已关闭,但是下面的查询将被视为合法:

select * from Users where Username='user' and Password=@Password
Run Code Online (Sandbox Code Playgroud)

因此,我确实需要SQL Server读入命令的内容并确定是否所有输入都已参数化。谢谢。

Mih*_*riu 2

事实上,您正在搜索即席查询(不是存储过程,也不是 sp_executesql)。

您可以先查看sys.dm_exec_cached_plansDMV:

SELECT
    CP.usecounts
    , CP.cacheobjtype
    , ST.text as sql_Statement    
    , QP.query_plan
FROM
    sys.dm_exec_cached_plans CP
    CROSS APPLY sys.dm_exec_sql_text(CP.plan_handle) ST
    CROSS APPLY sys.dm_exec_query_plan(CP.plan_handle) QP
WHERE
    ST.dbid = DB_ID()
    AND CP.objtype IN ( 'Adhoc')
ORDER BY
    CP.usecounts DESC
Run Code Online (Sandbox Code Playgroud)

请注意,关系引擎可以参数化简单查询(称为简单参数化的功能),因此您可能有相同的行

如果您希望通过不缓存即席查询的计划来提高性能,可以使用一个名为的服务器选项,该选项在optimize for ad hoc workloads第一次执行查询时向关系引擎发出信号 => 存储计划的较轻版本(计划存根) )。

计划缓存污染也可能是降低数据库性能的一个原因。检查此查询以检测是否也是您的情况。