我有一些表用于存储不同的文件信息,如拇指,图像,数据表......
我正在编写一个存储过程来检索特定ID的文件名。类似的东西:
CREATE PROCEDURE get_file_name(
@id int,
@table nvarchar(50)
)as
if @table='images'
select [filename] from images
where id = @id
if @table='icons'
select [filename] from icons
where id = @id
....
如何使用case when
语句重写此过程,还是只使用表名作为变量?
答案 0 :(得分:5)
你不能使用case ..何时在FROM子句中的表之间切换(就像在conditional ORDER BY
中一样)。即如下:
select * from
case when 1=1
then t1
else t2
end;
无效。
所以你需要使用动态SQL。最好尽可能参数化查询,例如@id
值可以参数化:
-- Validate @table is E ['images', 'icons', ... other valid names here]
DECLARE @sql NVARCHAR(MAX)
SET @sql = 'select [filename] from **TABLE** where id = @id';
SET @sql = REPLACE(@sql, '**TABLE**', @table);
sp_executesql @sql, N'@id INT', @id = @id;
与所有动态Sql一样,请注意,替换为查询的unparameterized
值(如@table
)会使查询容易受到Sql Injection攻击。因此,我建议您确保@table
来自受信任的来源,或者更好的是,@table
的值与执行查询之前的允许表的白名单进行比较。
答案 1 :(得分:3)
只需在另一个变量中构建SQL字符串并执行它
DECLARE @sql AS NCHAR(500)
SET @sql=
'SELECT [filename] '+
' FROM '+@table+
' WHERE id = @id'
EXECUTE(@sql)
答案 2 :(得分:1)
CREATE PROCEDURE get_file_name(
@id int,
@table nvarchar(50)
)as
DECLARE @SQL nvarchar(max);
SET @SQL = 'select [filename] from ' + @table + ' where id = ' + @id
EXECUTE (@SQL)