【问题标题】:Create table dynamically with MySQL command in c#在 C# 中使用 MySQL 命令动态创建表
【发布时间】:2015-10-15 17:17:43
【问题描述】:

我想动态创建表并用随机数填充,但是在执行代码时,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 附近使用的正确语法 ...

【问题讨论】:

  • 什么是7571877?是真的表吗?正确的语法是INSERT INTO [TABLE_NAME] ...
  • 让我猜猜。一堂一桌?它看起来像糟糕的设计
  • 是的,它的表名。
  • 扩展我博学的同事的想法,为什么每次会议都有单独的表格?您正在击败存在关系数据库的主要原因。创建一个包含 SessionId 字段的 Sessions
  • 不,你不需要。你认为你需要一个。假设您想要发挥最大的游戏分析性能。一张桌子可以超快地实现这一点。使用无限数量的表:一旦实现,实施和性能就会非常缓慢

标签: c# mysql


【解决方案1】:

语法错误的一个主要原因是该表没有被引用。查看MySQL manual for identifiers(包括表名)。

就像默认情况下您不能真正使用数字来表示变量一样,如果不转义标识符,您也不能对表执行相同的操作。一些解决方案是在表名前加上一个字母或使用单个表。

回答标题中的问题:

如果它不存在,您可以使用“IF NOT EXISTS”子句create a table。 SQL 如下所示:

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

如果你坚持走这条路,你应该用标准的前缀字母创建你的表名:

"s" + gameSession.ToString()

请注意,为每个会话设置一个单独的表确实会使您的数据库维护需求变得复杂,尤其是在处理废弃会话时。删除单个表中的行比查找所有废弃的表要容易得多。

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

满足需求:

更好的设计是创建一个带有会话 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();
    }

这使得清理工作变得更加容易,因为您可以批处理作业,删除所有不是当前会话的内容。

【讨论】:

  • 所以我改变了在我的程序中使用会话作为字段的方式,谢谢。
【解决方案2】:

问题在于您的表名。确保表名正确,然后使用此函数:

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();
        }
    }
}

【讨论】:

  • 正确。这失败了:create table 93827 (i int not null); 而这成功了create table X93827 (i int not null); ...加上他的插入语句无论如何都不应该有单引号
  • 您的 SQL 语法有错误;检查与您的 MySQL 服务器版本相对应的手册,以在第 1 行的“{0} (Dice1, Dice2) Values (1, 1)”附近使用正确的语法
  • @zex_rectooor 您是否提供了表格名称?表的名称是什么?还要确保您添加了我在第一版中忘记的String.Format 部分:P
猜你喜欢
  • 2017-10-05
  • 1970-01-01
  • 2017-05-28
  • 1970-01-01
  • 2021-03-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多