T-SQL EXEC versus sp_exec

2019-08-30 22:53发布

问题:

I tried the following:

declare @var2 nvarchar(30)
declare @qsql nvarchar(100)

set @var2 = N'iddelegat'

exec ('select max('+ @var2 + ') as IDexec from delegat');

set @qsql = 'select max(@varsp) as IDspexec from delegat';

exec sp_executesql @qsql, N'@varsp nvarchar(30)', @var2;

And the result:

IDexec        IDspexec
-----------------------    
500038       iddelegat

I could not understand why sp_executesql does not return the same result as EXECUTE. The right returned values are only in EXECUTE statement. It seems that sp_executesql does not evaluate the string 'iddelegat' to return the column.

回答1:

You cannot parameterize column names or table names when using sp_executesql. So, when you plug in the value iddelegat in the exec(), you are getting the column. When you have it as a parameter to sp_executesql, you are getting 'iddelegat' -- a string with the name of the column.

The issue of what you can parameterize is not well explained in the SQL documentation. If you dig far enough, you will get this:

Where You Can Use Parameters

You can use parameters as placeholders for literal values — for either text or numeric values. Most commonly, parameters are used as placeholders in search conditions for individual rows or for groups (that is, in the WHERE or HAVING clauses of an SQL statement).

This is in an obscure part of the documentation, but it has the correct general idea.

To help further understand this, the SQL engine can compile queries with parameters to get the execution plan. To do this, it needs to know the actual columns and tables in the query. Extra values -- parameters -- can be plugged in after the compilation step.



回答2:

You can't parameterise column names.

Your attempt is basically the same as doing MAX(N'iddelegat') not MAX(iddelegat)

The only way of using these in dynamic SQL is to concatenate them into the string directly.

You should use the quotename function if doing so to mitigate against SQL injection possibilities.

See The curses and blessings of dynamic SQL