What is the advantage of using @ParmDefinition in sp_executesql

余生颓废 提交于 2019-12-31 03:29:08

问题


DECLARE @id int
DECLARE @name nvarchar(20)
SET @id = 5
SET @name = 'Paul'

What is the difference between these two options:

Set @SQLQueryInnen = 'SELECT * FROM someTable WHERE ID = ' + @id + ' AND NAME = ''' + @name + ''''
Execute sp_Executesql @SQLQueryInnen

and

Set @SQLQueryInnen = 'SELECT * FROM someTable WHERE ID = @id AND NAME = @name'
Set @ParmDefinition = '@id int, @name nvarchar(20)'
Execute sp_Executesql @SQLQueryInnen, @ParmDefinition, @id

So far I only see the overhad for declaring the data type of @id and @name twice, when using @ParmDefinition. On the other hand, the "string-building" seems a bit easier with @ParamDefinition.


回答1:


You avoid having stringly-typed code - where you have to convert everything into a string so that you can shove it into the @SQLQueryInnen parameter, and then introduce issues because you have to work out how to safely and unambiguously perform the conversions to and from the strings back into the correct original data types.

For ints, the conversion issues aren't very apparent. But if you look at the number of issues people report (here, and on other forums) where they have issues converting between datetimes and strings, you'll realise that it does cause real issues. Best to keep the data as its natural type throughout.




回答2:


First case is SQL injection prone and a security risk. The discussion stops here.




回答3:


I see no one mentioned one of most important things. When you're using parameterized query, your execution plans are cached.

Your query, which is:

SELECT *
FROM someTable
WHERE ID = @id
    AND NAME = @name;

Its execution plan will be stored im memory and it will be reused each time you query it (which is a great benefit). Meanwhile if you're generating your code using string concatenation like that:

Set @SQLQueryInnen = 'SELECT * FROM someTable WHERE ID = ' + @id + ' AND NAME = ''' + @name + ''''
Execute sp_Executesql @SQLQueryInnen

Your code will generate execution plan for each parameter combination (unless it's repeating) and cached plan will not be reused. Imagine that you're passing @Id = 1 and @Name = 'Paul', Your generated query will look like:

SELECT *
FROM someTable
WHERE ID = 5
    AND NAME = 'Paul';

If you change your name to 'Rob', your generated query will look like and SQL Server will have to create a new plan for it:

SELECT *
FROM someTable
WHERE ID = 5
    AND NAME = 'Rob';

Meaning plans won't be reused. Hope it helps.

This is an article explaing this in a bit more detail: EXEC vs. sp_executeSQL (Don't rely on article title, it explains exact differences you asked on your question). Quote from it:

The TSQL string is built only one time, after that every time same query is called with sp_executesql, SQL Server retrieves the query plan from cache and reuses it



来源:https://stackoverflow.com/questions/31670688/what-is-the-advantage-of-using-parmdefinition-in-sp-executesql

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!