是否可以将列的别名作为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
;列别名用于输出,因此我尝试了InputOutput
和Output
,但对结果没有影响。
答案 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)