我正在尝试设置,以便将表名作为参数传递给命令文本,但我没有让它工作。我看了一下,发现了这样的问题:Parameterized Query for MySQL with C#,但我没有运气。
这是相关代码(connection ==包含连接字符串的MySqlConnection
):
public static DataSet getData(string table)
{
DataSet returnValue = new DataSet();
try
{
MySqlCommand cmd = connection.CreateCommand();
cmd.Parameters.AddWithValue("@param1", table);
cmd.CommandText = "SELECT * FROM @param1";
connection.Open();
MySqlDataAdapter adap = new MySqlDataAdapter(cmd);
adap.Fill(returnValue);
}
catch (Exception)
{
}
finally
{
if (connection.State == ConnectionState.Open)
connection.Close();
}
return returnValue;
}
如果我改变:
cmd.CommandText = "SELECT * FROM @param1";
为:
cmd.CommandText = "SELECT * FROM " + table;
作为一种测试方式,并且可行(我正在将数据集中的xml写入控制台以进行检查)。所以我很确定问题只是以错误的方式使用参数功能。有什么指针吗?
另外,如果我弄错了,请纠正我,但是使用参数功能应该提供针对SQL注入的完全保护,对吗?
答案 0 :(得分:5)
您可以不参数化您的表名,列名或任何其他数据库对象。您只能 参数化您的值。
您需要在sql查询中将其作为字符串连接传递,但在此之前,我建议使用强验证或白名单(仅限固定的可能正确的值)。
另外,如果我弄错了,请使用参数来纠正我 功能应该提供针对SQL注入的完全保护, 正确?
如果你的意思是parameterized statements带有“参数功能”,是的,这是正确的。
顺便说一下,请注意,有一个名为dynamic SQL支持SELECT * FROM @tablename
的概念,但不建议这样做。
正如我们所看到的,我们可以在动态的帮助下使这个程序工作 SQL,但也应该清楚我们没有获得任何优势 在存储过程中生成动态SQL。你可以 以及从客户端发送动态SQL。那么,好的:1)如果SQL 声明非常复杂,你可以节省一些网络流量 封装。 2)正如我们所看到的,从SQL 2005开始有 处理权限的方法。 然而,这是一个坏主意。
似乎有几个原因让人们想要参数化 表名。一个阵营似乎是不熟悉SQL的人 编程,但有其他语言的经验,如C ++,VB 参数化是一件好事。参数化表格 似乎可以实现通用代码和增加可维护性的名称 喜欢优秀的程序员美德。
但是,当涉及到数据库对象时,它就是旧的真相 不成立。在适当的数据库设计中,每个表都是唯一的,如 它描述了一个独特的实体。 (或者至少它应该!)当然,它 最终得到十几个或更多查找表并不罕见 有一个id,一个名称列和一些审核列。但他们这样做 描述不同的实体,它们的外表应该被视为 仅仅是机会,未来的要求可能使表格更多 相异。
答案 1 :(得分:2)
使用表名作为参数不正确。 SQL中的参数仅适用于值而不是列或表的标识符。
一个选项可以使用SqlCommandBuilder Class
,这将转义您的表名,不易受SQL注入攻击:
SqlCommandBuilder cmdBuilder = new SqlCommandBuilder();
string tbName = cmdBuilder.QuoteIdentifier(tableName);
您可以在语句中使用tbName
,因为它现在不容易受到SQL注入攻击。