How to get Excel to reliably execute sp_executesql

2019-07-19 02:02发布

问题:

In MS Excel, if you create a QueryTable with Microsoft Query, and your SQL query cannot be visually presented by Microsoft Query, then you are not allowed to provide parameters for that query. Which is a shame, so there is this awesome technique that allows parameters anyway:

{CALL sp_executesql (N'select top (@a) * from mytable', N'@a int', ?)}

You provide the query in the ODBC CALL form and it works with parameters.

Unless it does not.

While on some computers it works flawlessly, on other computers Excel throws an error when trying to refresh the query table:

  • For SQL Native Client 10: Invalid parameter number
  • For SQL Native Client 11: Procedure or function sp_executesql has too many arguments specified.

With a profiler I can see Excel (actually, the native client when poked by Excel) is doing this before actually executing sp_executesql:

exec sp_describe_undeclared_parameters N' EXEC sp_executesql N''<actual query>;'',N''<declared parameters>'',@P1  '

Here @p1 is the parameter placeholder that is supposed to go to sp_executesql later, and that is where sp_describe_undeclared_parameters fails. It does not expect any custom parameters for sp_executesql -- only the two intrinsic ones, @stmt and @params. If I manually remove the ,@p1 bit from the query, it executes fine in all cases.

So that is the problem: On some computers the above auto-generated sp_describe_undeclared_parameters works with the unnecessary/wrong ,@P1 bit, on some it fails.
We need to make it work on all computers.

Weird things to consider:

  • I fail to see anything common in computers that don't have the problem. Bitness or the Windows version do not seem to matter.
  • I fail to manually execute the said query with the ,@P1 bit attached - whatever tool I use, I get the "too many arguments" error, and yet, Excel is able to execute it no problem when it feels like. I can see with the profiler that is the exact query that hits the server. Maybe it has something to do with a very peculiar combination of connection settings, but they appear to be same on all computers (the data source is an ODBC system data source using SQL Server Native Client 11, and all parameters are same on all tabs across the computers).