MySQL表名作为参数

我正在尝试设置,以便将表名作为参数传递给命令文本,但我没有让它工作。 我环顾了一下,发现了这样的问题: 用C#对MySQL进行参数化查询 ,但我没有运气。

这是相关代码(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写入控制台以进行检查)。 所以我很确定问题只是以错误的方式使用参数function。 有什么指针吗?

另外,如果我错了,请纠正我,但使用参数function应该提供完全的SQL注入保护,对吧?

无法参数化表名,列名或任何其他数据库对象。 您只能参数化您的值。

您需要在sql查询中将其作为字符串连接传递,但在此之前,我建议使用validation或白名单(只有固定的可能正确值集)。

另外,如果我错了,请纠正我,但使用参数function应该提供完全的SQL注入保护,对吧?

如果你的意思是带有“参数function”的参数化语句 ,是的,这是正确的。

顺便说一下,请注意,有一个名为动态SQL的概念支持SELECT * FROM @tablename但不建议这样做。

正如我们所看到的,我们可以在动态SQL的帮助下使这个过程工作,但是也应该清楚我们在存储过程中生成动态SQL没有任何优势。 您也可以从客户端发送动态SQL。 所以,好的:1)如果SQL语句非常复杂,您可以节省一些网络流量并进行封装。 2)正如我们所看到的,从SQL 2005开始,有一些方法可以处理权限。 然而,这是一个坏主意。

人们想要参数化表名似乎有几个原因 。 一个阵营似乎是不熟悉SQL编程的人,但有其他语言的经验,例如C ++,VB等参数化是一件好事。 参数化表名以实现通用代码并提高可维护性似乎是良好的程序员优点。

但是,就数据库对象而言,旧的真相并不成立。 在适当的数据库设计中,每个表都是唯一的,因为它描述了一个唯一的实体。 (或者至少它应该!)当然,最终会有十几个或更多的查找表都具有id,名称列和一些审计列,这种情况并不少见。 但他们确实描述了不同的实体,他们的外表应该被视为机会,未来的要求可能会使表格更加不同。

使用表的名称作为参数是不正确的。 SQL中的参数仅适用于值而不是列或表的标识符。

一个选项可以使用SqlCommandBuilder Class ,这将转义您的表名并且不易受SQL注入攻击:

 SqlCommandBuilder cmdBuilder = new SqlCommandBuilder(); string tbName = cmdBuilder.QuoteIdentifier(tableName); 

您可以在语句中使用tbName ,因为它现在不容易受到SQL注入攻击。