MySQL表名作为参数

时间:2015-10-21 08:45:01

标签: c# mysql

我正在尝试设置,以便将表名作为参数传递给命令文本,但我没有让它工作。我看了一下,发现了这样的问题: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注入的完全保护,对吗?

2 个答案:

答案 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注入攻击。