C# - 无法将数据插入MySQL数据库

时间:2015-05-11 17:42:18

标签: c# mysql .net database winforms

我正在申请某个网站。该网站有很多玩家,我抓了他们的个人资料页面。他们的个人资料页面包含姓名,级别,世界和上次登录日期等信息。

所以我创建了一个名为Player的对象。然后我将所有数据添加到列表中。

public static List<Player> Players = new List<Player> { };

public class Player
    {
        public string Name { get; set; }
        public string Sex { get; set; }
        public string Vocation { get; set; }
        public int Level { get; set; }
        public int Achievements { get; set; }
        public string World { get; set; }
        public string LastLogin { get; set; }
        public string AccountStatus { get; set; }
        public int OnlineStatus { get; set; }
    }

我添加如下数据:

new Player { Name = playerName, Sex = playerSex, Vocation = playerVocation, Level = playerLevel, Achievements = playerAchievements, World = playerWorld, LastLogin = playerLastLogin, AccountStatus = playerAccountStatus, OnlineStatus = playerOnlineStatus };

我现在想将所有播放器添加到我的MySQL数据库中,但我似乎无法理解如何插入数据。

我建立了一个连接,我尝试SELECT数据,它工作正常。所以我的联系也不错。但插入似乎不起作用。

这是我添加的代码,用于将数据插入表格中:

string connString = "Server=localhost;Port=3306;Database=rookstat;Uid=XXXXXXX;password=XXXXXX;";
MySqlConnection conn = new MySqlConnection(connString);
MySqlCommand command = conn.CreateCommand();

foreach (Player rooker in Players)
{
command.CommandText = "Insert into rookstayers (id, name, sex, vocation, level, achievements, world, lastlogin, accountstatus, onlinestatus) values('', rooker.Name, rooker.Sex, rooker.Vocation, rooker.Level, rooker.Achievements, rooker.World, rooker.LastLogin, rooker.AccountStatus, rooker.OnlineStatus)";
conn.Open();
command.ExecuteNonQuery();
}

conn.Close();

我做错了什么?我不确定我插入的值。它应该是rooker.Name还是什么?

3 个答案:

答案 0 :(得分:6)

构建查询的方式会创建一个字符串,并将变量名称视为文字字符串。

相反,您需要像这样的参数化查询

string connString = "Server=localhost;Port=3306;Database=rookstat;Uid=XXXXXXX;password=XXXXXX;";
using(MySqlConnection conn = new MySqlConnection(connString))
using(MySqlCommand command = conn.CreateCommand())
{
    conn.Open();
    command.CommandText = @"Insert into rookstayers 
             (id, name, sex,   vocation, level, achievements, 
              world, lastlogin, accountstatus, onlinestatus) 
       values('', @name, @sex, @vocation, @level, @Achievements,
              @World, @LastLogin, @AccountStatus, @OnlineStatus)";

    command.Parameters.Add("@name", MySqlDbType.VarChar);
    command.Parameters.Add("@sex", MySqlDbType.VarChar);
    command.Parameters.Add("@vocation", MySqlDbType.VarChar);
    command.Parameters.Add("@level", MySqlDbType.Int32);
    .... and so on for all the parameters placeholders

    command.Prepare();
    foreach (Player rooker in Players)
    {
          command.Parameters["@name"].Value = rooker.Name;
          command.Parameters["@sex"].Value = rooker.Sex;
          command.Parameters["@vocation"].Value = rooker.Vocation;
          command.Parameters["@level"].Value = rooker.Level;

          ... and so on for the other parameters defined
          command.ExecuteNonQuery();
    }
}

这样,在进入循环之前,您可以定义sql命令并在MySqlCommand Parameters集合中创建参数而不设置值。并且,如下所述,Mr先添加了对命令的调用.Prepare可以提高性能。

在循环内部,对于定义的每个参数,您可以设置其值并调用命令来执行。

我还希望指向using语句,确保正确关闭和处理对象,并使用Add为每个参数设置适当的参数类型而不是AddWithValue。 AddWithValue是一个有许多缺点的快捷方式,您可以在本文Can we stop using AddWithValue already?

中阅读

最后一条建议,如果对象和数据之间的这种转换经常发生,那么你应该投入一点时间来学习使用像Dapper这样的ORM工具

编辑:看看你的整个代码,你似乎错过了一个重要的步骤。您需要将播放器添加到播放器列表

private async void insertTimer_Tick(object sender, EventArgs e)
{
     if (onlineList.Items.Count > 0)
     {
         for (int i=0; i<onlineList.Items.Count; i++)
         {
              CurrentPlayer = onlineList.Items[i].ToString();
              var playerProfile = await GetData();
              foreach (var row in playerProfile)
              {
                  .... gets player data ....
              }

              // Creates a new Player and add to the insertion list
              Players.Add(new Player 
              { 
                    Name = playerName, 
                    Sex = playerSex, 
                    Vocation = playerVocation, 
                    Level = playerLevel, 
                    Achievements = playerAchievements, 
                    World = playerWorld, 
                    LastLogin = playerLastLogin, 
                    AccountStatus = playerAccountStatus, 
                    OnlineStatus = playerOnlineStatus 
               };
          }

          // And now the inserts goes here
          .......

答案 1 :(得分:4)

您正在将字符串文字传递给查询,而不是变量值:

尝试将您的查询调整为:

command.CommandText = "Insert into rookstayers (id, name, sex, vocation) values('', @name, @sex, @vocation)";

然后Parameters.AddWithValue如下所示:

command.Parameters.AddWithValue("@name", rooker.Name);
command.Parameters.AddWithValue("@sex", rooker.Sex);
command.Parameters.AddWithValue("@vocation", rooker.Vocation);

这也有助于防止SQL注入。

答案 2 :(得分:2)

尝试以下方法:

*4

请注意差异:

  1. 包装一次性物品(即MySQLConnection和MySQLCommand) 在使用语句。
  2. 更新了SQL insert命令以使用SQL参数。在这种情况下,&#34; @ name&#34;执行命令时,将替换为rooker.Name的值。
  3. 插入语句中排除的id列,因为我认为是 标识栏,因此您不必明确包含该标识。
  4. 最后,使用command.Prepare()。正如MySQL .NET中所指定的那样     连接器文档here,它可以提供重要的     对多次执行的查询的性能改进。