Sql server select语句中的变量表名称

Sql server select语句中的变量表名称,sql-server,tsql,stored-procedures,Sql Server,Tsql,Stored Procedures,我有一些用于存储不同文件信息的表格,如拇指、图像、数据表等 我正在编写一个存储过程来检索特定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'

我有一些用于存储不同文件信息的表格,如拇指、图像、数据表等

我正在编写一个存储过程来检索特定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
语句重写此过程,还是只使用表名作为变量?

只需在另一个变量中构建SQL字符串并执行它

DECLARE @sql AS NCHAR(500)
SET @sql=
    'SELECT [filename] '+
    ' FROM '+@table+
    ' WHERE id = @id'
EXECUTE(@sql)

您不能使用用例。。何时在FROM子句中的表之间切换(就像在中一样)。i、 e.因此,应采取以下措施:

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一样,请注意,被替换到查询中的
未参数化的
值(如
@table
)使查询容易受到Sql注入攻击。因此,我建议您确保
@table
来自受信任的来源,或者更好的是,在执行查询之前,将
@table
的值与允许的表的白名单进行比较。

为了获得更好的设计解决方案,我建议移动“文件”实体到另一个表,并使用外键引用相关引用。那么,您就不需要对SQL求值进行任何修改了。您的意思是,我有一个文件表和相关的所有图像、图标,。。。有桌子吗?是的。然后连接将帮助您获取任何与相关文件数据相关的内容:
SELECT icons.Name,file.Filename FROM icons INNER JOIN files.Id=icons.FileId WHERE icons.Id=1
如果我应该为每个select语句编写if子句,那么我自己的解决方案看起来不是更好吗?我问这个问题的原因是,如果我添加更多这样的表,我不希望存储过程需要更改,在这种情况下,我的会need@AshkanMobayenKhiabani-说得好,我想你不想重复你的问题(干)。我已经用标记化/替换模式进行了更新。我确实想指出的是,通过参数化
@id
,您会感觉更好-它比简单的字符串链接具有sql注入安全性和查询计划缓存优势。另外,请记住验证@table,因为它不能参数化为OFC。
-- 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;