Skip to content

Offer to put parameter values back when copying a statement out of a plan #467

Description

@erikdarlingdata

Out of #466, where @joshdbe copied a statement out of a plan and got @0, @1 … @6 where his literals had been.

That text is correct — it is what SQL Server compiled, because the database has PARAMETERIZATION FORCED — but it is not what anyone wants on the clipboard. You copy a statement out of a plan to run it, and a query full of undeclared @0 will not run.

The values are right there

Forced parameterization keeps every literal in the plan's ParameterList, with both compiled and runtime values. From a local repro of #466:

<ColumnReference Column="@0" ParameterDataType="varchar(8000)" ParameterCompiledValue="'123456'" ParameterRuntimeValue="'123456'" />
<ColumnReference Column="@1" ParameterDataType="int" ParameterCompiledValue="(5)" ParameterRuntimeValue="(5)" />
...
<ColumnReference Column="@6" ParameterDataType="varchar(8000)" ParameterCompiledValue="'2026-05-28 10:28:07.3132561'" />

ShowParameters already parses and displays all of this. Nothing new needs reading — the substitution just is not offered anywhere.

What to add

On the statement context menu, alongside the existing Copy Query Text and Open in Query Editor, a variant that puts the parameter values back:

  • Substitute ParameterRuntimeValue where present, falling back to ParameterCompiledValue. Values arrive pre-quoted ('123456', (5)) — the parens on numerics need stripping, the quotes on strings do not.
  • Match on whole tokens. @1 must not match inside @11, and a @0 inside a string literal must be left alone.
  • Only offer it when the statement actually has parameters. A statement with none should not grow a dead menu item.
  • Worth considering whether this should be the default behavior of the existing two items rather than a third and fourth item, with the raw form as the variant. The parameterized text is the honest record of what was compiled, but the substituted text is what people want to run, and a context menu with four near-identical entries is its own problem.

This is equally useful for procedure parameters and sp_executesql, not just forced parameterization — any plan whose statement text carries @name and whose ParameterList carries the value.

Note for whoever picks this up

Do not reach for the query editor's buffer as the source of truth. It only holds the original text in the one case where the user just executed it from that tab, and it is wrong for a plan opened from a file, from Query Store, or from another session.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions