c#中使用MySQL命令动态创建表

本文关键字:动态 创建 命令 MySQL | 更新日期: 2023-09-27 18:17:50

我想动态创建表并填充随机数字,但是当执行代码时,MySQL抛出一个关于语法的错误。

 for (int i = 0; i < 100; i++)
        {
            //gameSession is int, i tried use Parameters.AddWithValue but still have same problem.
            MySqlCommand dice = new MySqlCommand("INSERT INTO "+gameSession.ToString()+" (Dice1,Dice2) Values (@dice1,@dice2)", myConnection);

            Random dice1 = new Random();
            dice.Parameters.AddWithValue("@dice1", dice1.Next(1, 7));
            Random dice2 = new Random();
            dice.Parameters.AddWithValue("@dice2", dice2.Next(1, 7));
            if (myConnection.State == ConnectionState.Closed)
            {
                myConnection.Open();
            }
            dice.ExecuteNonQuery();
        }

你的SQL语法有错误;查看对应MySQL服务器版本的手册,在INSERT INTO '7571877…附近使用正确的语法

c#中使用MySQL命令动态创建表

语法错误的一个主要原因是表没有引号。查看MySQL手册中的标识符(包括表名)。

就像默认情况下你不能使用数字来表示变量一样,如果不转义标识符,你也不能对表做同样的事情。有两种解决方案,一种是在表名前加上字母,另一种是使用单个表。

回答题目中的问题:

如果表不存在,可以使用" if NOT EXISTS"子句创建。SQL语句看起来像这样:

CREATE TABLE table_name IF NOT EXISTS (
    dice1 INTEGER,
    dice2 INTEGER
);

如果您坚持采用这种方法,则应该使用标准的前缀字母创建表名:

"s" + gameSession.ToString()

请注意,为每个会话创建单独的表会使数据库维护需求复杂化,特别是在处理废弃会话时。删除单个表中的行要比查找所有被放弃的表容易得多。

另一个严重的问题与数据库安全有关。在针对数据库构建应用程序时,只向用户授予插入和更新权限要比授予他们在数据库中创建和删除任何表的权限要好得多。由于表名是动态创建的,因此无法真正轻松地维护每个表的特权。如果这是面向web的,那么你将为很少的收益而承担一些严重的责任。

满足需求:

一个更好的设计是用一个会话id创建一个表。否则,您将有任意数量的表,每个表有一条记录。您可以像这样创建一次表:

CREATE TABLE DiceRolls IF NOT EXISTS (
    session INTEGER,
    dice1 INTEGER,
    dice2 INTEGER
);

你的插入只需要改变一点点:

 for (int i = 0; i < 100; i++)
    {
        //gameSession is int, i tried use Parameters.AddWithValue but still have same problem.
        MySqlCommand dice = new MySqlCommand("INSERT INTO DiceRolls (Session, Dice1,Dice2) Values (@session,@dice1,@dice2)", myConnection);
        dice.Parameters.AddWithValue("@session", gameSession);
        Random dice1 = new Random();
        dice.Parameters.AddWithValue("@dice1", dice1.Next(1, 7));
        Random dice2 = new Random();
        dice.Parameters.AddWithValue("@dice2", dice2.Next(1, 7));
        if (myConnection.State == ConnectionState.Closed)
        {
            myConnection.Open();
        }
        dice.ExecuteNonQuery();
    }

这使得清理变得容易得多,因为你可以批处理一些东西,删除所有不是当前会话的东西。

问题出在表名上。确保表名正确,然后使用这个函数:

void InsertDiece(string connectionString, string tableName, int count)
{
    var commandText = String.Format("INSERT INTO `{0}` (Dice1, Dice2) Values (@dice1, @dice2)", tableName);
    var random = new Random(DateTime.Now.Milliseconds);
    using(var connection = new MySqlConnection(connectionString))
    using(var command = connection.CreateCommand())
    {
        connection.Open();
        command.CommandText = commandText;
        for(int i = 0; i < count; i++)
        {
            command.Parameters.AddWithValue("@dice1", random.Next(1, 7));
            command.Parameters.AddWithValue("@dice2", random.Next(1, 7));
            command.ExecuteNonQuery();
            command.Parameters.Clear();
        }
    }
}