c#mysql参数addwithvalue on select ip,estado from@table不起作用

rqqzpn5f  于 2021-06-21  发布在  Mysql
关注(0)|答案(1)|浏览(275)

我在c#类中有一个方法“leertabla”,它在mysql数据库中给出表名,然后返回ip和estado列,我尝试了一些参数,但没有成功:
首先使用addwithvalue,使用“secot”调用方法 obj.LeerTabla("secot") :

public void LeerTabla(string NombreTabla)
    {
        string SQLCmdStr;
        try
        {
            SQLCmdStr = "SELECT ip, estado FROM @tabla";
            MySqlCommand SQLcmd = new MySqlCommand(SQLCmdStr, SqlDBconn);
            SQLcmd.Prepare();
            SQLcmd.Parameters.AddWithValue("@tabla", NombreTabla);
            MySqlDataReader SQLReader = SQLcmd.ExecuteReader();

            while(SQLReader.Read())
            {
                TablaDeIP.Add(SQLReader["ip"].ToString());
                ListaDeEstado.Add(SQLReader["estado"].ToString());
            }
        }
        catch (MySql.Data.MySqlClient.MySqlException ex)
        {
            MessageBox.Show(ex.Message);
        }
    }

然后加上:

public void LeerTabla(string NombreTabla)
{
    string SQLCmdStr;
    try
    {
        SQLCmdStr = "SELECT ip, estado FROM @tabla";
        MySqlCommand SQLcmd = new MySqlCommand(SQLCmdStr, SqlDBconn);
        MySqlParameter parametro = new MySqlParameter();
        parametro.ParameterName = "@tabla";
        parametro.Value = NombreTabla;
        SQLcmd.Parameters.Add(parametro);
        MySqlDataReader SQLReader = SQLcmd.ExecuteReader();

        while(SQLReader.Read())
        {
            TablaDeIP.Add(SQLReader["ip"].ToString());
            ListaDeEstado.Add(SQLReader["estado"].ToString());
        }
    }
    catch (MySql.Data.MySqlClient.MySqlException ex)
    {
        MessageBox.Show(ex.Message);
    }
}

他们都给了我同样的解释:“你的sql语法有错误;检查与mysql服务器版本相对应的手册,以获得在第1行“secot”附近使用的正确语法“。。。
但如果我不使用参数,它可以工作:

public void LeerTabla(string NombreTabla)
    {
        string SQLCmdStr;
        try
        {
            SQLCmdStr = "SELECT ip, estado FROM secot";
            MySqlCommand SQLcmd = new MySqlCommand(SQLCmdStr, SqlDBconn);
            SQLcmd.Prepare();
            MySqlDataReader SQLReader = SQLcmd.ExecuteReader();

            while(SQLReader.Read())
            {
                TablaDeIP.Add(SQLReader["ip"].ToString());
                ListaDeEstado.Add(SQLReader["estado"].ToString());
            }
        }
        catch (MySql.Data.MySqlClient.MySqlException ex)
        {
            MessageBox.Show(ex.Message);
        }
    }

我做错了什么?任何帮助都会很好。

qlckcl4x

qlckcl4x1#

参数用于值,而不是表名。因此,不能像值那样参数化查询字符串中的表名。
提供动态表名最常用的方法是将表名连接到查询字符串中,但这种方法仍然容易导致sql注入:

SQLCmdStr = string.Format("SELECT ip, estado FROM {0}", NombreTabla);

如果要对表名使用白名单,请使用将表名作为参数传递的存储过程,并通过检查表名来执行白名单 information_schema.tables :

DELIMITER //

CREATE PROCEDURE RunSQLWithDynamicTableName(@tableName varchar(50))
AS
BEGIN 
    DECLARE @validTableName varchar(50)
    DECLARE @queryString varchar(100)

    SET @validTableName = SELECT table_name FROM information_schema.tables
                          WHERE table_schema = '[database_name]' 
                          AND table_name = @tableName LIMIT 1

    IF @validTableName IS NULL
        # table name does not exist, throw exception here

    # concatenate table name and prepared query string
    SET @queryString = SELECT CONCAT('SELECT * FROM ', @validTableName) 

    PREPARE stmt FROM @queryString
    EXECUTE stmt
END //

DELIMITER ;

然后调用程序 MySqlCommand 查询字符串:

SQLCmdStr = "CALL RunSQLWithDynamicTableName(@tableName)"

MySqlCommand SQLcmd = new MySqlCommand(SQLCmdStr, SqlDBconn);
cmd.Parameters.Add("@tableName", MySqlDbType.VarChar).Value = NombreTabla;

相关问题