How to use sp_executesql to avoid SQL Injection

时间秒杀一切 提交于 2019-12-02 02:03:54

You can enclose the table name in []

SET @sql= N'  select * from [' + @tblname + '] where name= @param1 and id= @param2'; 

However, if you use a two-part naming convention e.g dbo.tablename, you have to add additional parsing, since [dbo.tablename] will result to:

Invalid object name [dbo.tablename].

You should parse it so that it'll be equal to dbo.[tablename].

You could first check if the parameter value is indeed a table name:

ALTER PROC Test @param1  NVARCHAR(50), 
             @param2  INT, 
             @tblname NVARCHAR(100) 
AS 
BEGIN 
  DECLARE @sql NVARCHAR(1000) 

  IF EXISTS(SELECT 1 FROM sys.objects WHERE type = 'u' AND name = @tblname)
  BEGIN
      SET @sql= N'  select * from ' + @tblname 
                + ' where name= @param1 and id= @param2'; 

      PRINT @sql 

      EXEC Sp_executesql 
        @sql, 
        N'@param1 nvarchar(50), @param2 int', 
        @param1, 
        @param2; 
  END
END 

If the passed value is not a table name your procedure won't do anything; or you could change it to throw an error. This way you're safe if the parameter contains a query.

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