要在sql查询中传递的动态表名

时间:2015-07-16 12:50:54

标签: c# sql-server

我想使用动态表名执行sql查询。

我尝试了以下代码,但这些代码都不适用于我,并引发语法错误。

exec sp_executesql N'SELECT * FROM  @Table1 D WITH (NOLOCK)',
    N'@Table1 nvarchar(40)',@Table1=N'master.dbo.ABCD_data'

OR

exec sp_executesql N'SELECT * FROM  master.dbo.+@Variable1+_data D WITH (NOLOCK)',
    N'@Variable1 nvarchar(4),',@Variable1=N'ABCD'

有人可以帮我创建这个动态表名吗?

我从sql profiler获得此查询。实际上我在c#代码中执行它并在分析器中得到它。

我的C#代码很简单,就是这样:

string query = @"SELECT * FROM master.dbo.+@Variable1+_data D WITH (NOLOCK)";
SqlCommand cmd = new SqlCommand();
cmd.CommandText = query;
cmd.CommandType = CommandType.Text;
cmd.Parameters.AddWithValue("@Variable1", "ABCD");
DataTable dt = new DataTable();
using (SqlDataAdapter adapter = new SqlDataAdapter(cmd))
{
    adapter.Fill(dt);
}

1 个答案:

答案 0 :(得分:-1)

您不能将表名或列名作为参数传递。

通常的方法称为“动态SQL”:

declare @sql nvarchar(max);
set @sql = 'select * from ' + quotename(@tablename);
exec (@sql);

或者传递表名和参数值:

declare @sql nvarchar(max);
set @sql = 'select * from ' + quotename(@tablename) + ' where col1 = @par1';
exec sp_executesql @sql, N'@par1 nvarchar(4)', @par1='val1';

从C#运行它的一种天真的方法(易受SQL注入):

SqlCommand cmd = new SqlCommand();
cmd.CommandText = @"
    declare @sql nvarchar(max);
    set @sql = 'select * from " + "ABCD" + @"_data d with (nolock)';
    exec (@sql);
    ";
cmd.CommandType = CommandType.Text;
DataTable dt = new DataTable();
using (SqlDataAdapter adapter = new SqlDataAdapter(cmd))
    adapter.Fill(dt);

要在仍然使用quotename功能的情况下从C#运行此功能:

SqlCommand cmd = new SqlCommand();
cmd.CommandText = @"
    declare @sql nvarchar(max);
    set @sql = 'select * from ' + quotename(@tablename) + '_data d with (nolock)';
    exec (@sql);
    ";
cmd.CommandType = CommandType.Text;
cmd.Parameters.AddWithValue("@tablename", "ABCD");
DataTable dt = new DataTable();
using (SqlDataAdapter adapter = new SqlDataAdapter(cmd))
    adapter.Fill(dt);