-1

Table called Emp contain id,name,lname,birthdate,address and salery .I want to select from emp. Basic query : select * from emp If pass the value for lname ,query : select * from emp where lname = 'fgfg' like this. So I created following sp.

create Procedure Proc_selectEmp
(
@name varchar(10) = null,
@lname varchar(10) = null,
@id varchar(10) = null

)
as
begin

select * from Emp
where 
(@name is null or name = @name) 
and (@lname is null or lname = @lname) 
and (@id is null or id = @id)
end

Like emp,there are 13 table having same column name. So my tablenmae is also dynamic.That's why, I choose execute sp_executesql.Can I create like this

create Procedure Proc_selectEmp
(
@name varchar(10) = null,
@lname varchar(10) = null,
@id varchar(10) = null
@tableName varchar(30)
)
as
begin
declare @query nvarchar(1000) 
set @query = @query +'select * from '+@tableName+'
where ('+@name+' is null or name = '+@name+') 
and ('+@lname+' is null or lname = '+@lname+') 
and ('+@id+' is null or id = '+@id+')
end'

execute sp_executesql @query
StuartLC
  • 104,537
  • 17
  • 209
  • 285
pinky
  • 193
  • 2
  • 3
  • 12

2 Answers2

1

It will work, although is pretty smelly, given that it requires that it requires that table name is a variable and thus tables must have the same column definitions.

Also, rather than including the @param is null or column = @param, rather, leave out unnecessary filters entirely, which is easy to do since you are using dynamic sql. This will avoid the parameter sniffing problem.

Lastly, instead of appending the column filters into the string, rather use the parameterized overload of sp_executesql, which will protect your from SQL injection attacks, and handle the escaping of quotes etc for you. Unfortunately, @tablename can't be parameterized, but hopefully? this isn't a user or foreign-supplied variable (in which case you will need to do some more thinking about design and or validation techniques).

i.e.

declare @query nvarchar(max) 
set @query = N'select * from ' + @tableName + N` where (1=1)`

if (@name is not null)
  set @query = @query + N'and name = @name'

-- ... same for @id and @lname

exec sp_executesql @SQL, 
     N'@name varchar(10),
       @lname varchar(10),
       @id varchar(10)',
       @name = @name,
       @lname = @lname,
       @id = @id

Edit Re : securing un-parameterizable inputs like table or column names in dynamic sql - see this post here for ideas - use of QUOTENAME and white-listing column / table names are prominent.

Community
  • 1
  • 1
StuartLC
  • 104,537
  • 17
  • 209
  • 285
-4

Yes you can but you have to write

EXECUTE(@query)    

Instead of

execute sp_executesql @query
Hassan
  • 1,413
  • 1
  • 10
  • 12