如何将SQL列别名指定为SqlParameter?

时间:2018-09-26 16:06:05

标签: c# sql-server

是否可以将列的别名作为SqlParameter添加到SQL命令?如果是这样,如何指定?

作为一个简化的示例,假设我有一个这样构造的SQL命令:

SqlCommand GetCommand(string columnName)
{
    string filter = String.Format("SELECT MyColumn1 AS '{0}' FROM MyTable", columnName);

    return new SqlCommand(filter);
}

此命令对阻止SQL注入攻击没有任何作用,因此我想遵循标准过程并对命令进行参数设置。

我习惯将WHERE子句中的语句转换为使用参数。这些语句类似于上面的语句,例如:

SqlCommand command("SELECT * FROM MyTable WHERE name = '{0}'", name);

当我转换它时,它变成:

SqlCommand command("SELECT * FROM MyTable WHERE name = @name");
command.Parameters.Add(new SqlParameter("name", SqlDbType.NVarChar) { Value = name });

那很好。在此处使用GetCommand()方法使用相同的方法可以得出:

SqlCommand GetCommand(string columnName)
{
    string filter = "SELECT MyColumn1 AS @columnName FROM MyTable";

    SqlCommand command = new SqlCommand(filter);
    command.Parameters.Add(new SqlParameter("columnName", SqlDbType.NVarChar) 
        { Value = columnName });

    return command;
}

但是,执行命令后,结果为:

  

MyApplication.exe中发生了'System.Data.SqlClient.SqlException'类型的异常,但未在用户代码中处理

     

其他信息:“ @ columnName”附近的语法不正确。

我看到SO和Web上普遍存在关于SqlParameter的使用的许多问题,但似乎没有一个问题涉及它们与列别名的使用。

Microsoft's SqlParameter documention中也没有任何指示。由此,我注意到SqlParameter.Direction属性默认为ParameterDirection.Input;列别名用于输出,因此我尝试了InputOutputOutput,但对结果没有影响。

4 个答案:

答案 0 :(得分:2)

简短答案: 您不能

列别名不可参数化。它们是SQL语言中的标识符,而不是值-就像列名本身或表名一样。

“从表Y中获取X列,并在结果集中将其命名为Z”。 X,Y或Z均不可参数化。

请注意,这不是对SqlParameter的限制,而是对由Sql Server实现的SQL语言的限制。

答案 1 :(得分:2)

参数不是为别名TSQL列而设计的。如果需要别名,只需在TSQL中给它一个别名即可。此外,参数的输入/输出方面适用于查询在运行期间修改参数的情况。例如存储过程的输出参数。

实际上,您要尝试执行的操作是获取一个数据集,其中返回的列名基于输入的值。

我将使用数据适配器填充数据表,然后将列重命名为所需值。

dataTable.Columns["MyColumn1"].ColumnName = columnName;

答案 2 :(得分:0)

您无法参数化架构名称和别名。如果必须具有动态别名,则需要保护自己免受应用程序层中的SQL注入。

考虑创建有效别名的白名单,并且仅从白名单中进行选择。

如果别名来自用户输入,则必须验证/清除输入。

编辑:依赖应用程序层来防止SQL注入攻击是一种不好的做法。但是有时业务驱动因素或其他原因迫使这种情况发生。我的建议是在被迫执行此操作时减轻SQL注入风险的方法。

答案 3 :(得分:0)

要做的事情很奇怪,但是您可以使用参数构建一些sql,然后执行它。

Declare @sql VarChar(255)
Set @sql = 'SELECT ClientNumber AS ' + @columnName + ' FROM Ib01'
Exec(@sql)