如何在执行期间获取查询计划

时间:2016-04-05 21:41:20

标签: sql-server sql-server-2014

是否可以从它调用的视图中捕获整个RPC SELECT语句的查询文本?我正在SQL Server 2014中开发一个企业数据库,它必须支持提交复杂SELECT语句的商业应用程序,其中外部WHERE子句是关键的。此语句还包括针对同一对象(在我的示例中为视图)的子查询,这些子查询不包含该条件。这会产生一个巨大的问题,因为调用应用程序正在将这些子查询连接到另一个字段上的过滤结果,从而产生ID重复,从而在其他地方引发错误。

调用应用程序假定它正在查询表(而不是视图),并且只能将其配置为使用简单的WHERE子句。我的任务是在这个相当天真的应用程序背后实现更复杂的安全模型。我无法重写有问题的查询,但我曾希望从缓存的查询计划中检索丢失的信息。这是我提出的解决方案的超简化伪观点:

CREATE VIEW schema.important_data AS
WITH a AS (SELECT special_function() AS condition),
     b AS (SELECT c.criteria 
           FROM a, lookup_table AS c 
           WHERE a.condition IS NULL OR c.criteria = a.condition)
SELECT d.field_1, d.field_2, d.filter_field 
FROM b, underlying_table AS d
WHERE d.filter_field = b.criteria;

我的特殊功能"读取RPC的查询计划,提取WHERE条件并抢先过滤视图,以便它始终只返回它应该返回的内容。不幸的是,查询计划似乎不会被缓存,直到执行之后。如果多次进行RPC,我的解决方案可以完美地工作 - 但仅限于第二次和后续的调用。

我目前正在使用 dm_exec_cached_plans dm_exec_query_stats dm_exec_sql_text ,通过搜索spid,计划创建时间和时间来获取RPC的全文具体的话。如果我能够以某种方式获得当前正在执行的计划,那将会好得多。我相信 dm_exec_requests 会这样做,但它只会返回当前的语句 - 这只是我函数的定义。

扩展事件看起来很有前途,但不熟悉,有很多要消化的。我还没有找到任何关于它们是否适合这一特定挑战,是否可以实时获取通知或如何确保事件会话始终运行的指导。我现在正在进行这项调查,并希望得到任何建议或意见。还有什么我可以做的吗?

1 个答案:

答案 0 :(得分:0)

这是一个站不住脚的想法,我通过重构视图本身设计了一个不那么优雅的解决方案。存在性能损失,但避免了下游错误。我的基本问题是客户端应用程序生成其SQL语句的方式,我没有做任何事情 - 因此,用户只需接受可能产生的任何限制。