2015-05-11 6 views
2

Я делаю приложение, где я очищаю определенный сайт. На веб-сайте есть группа игроков, и я очищаю каждую страницу своих профилей. Их страницы профиля содержат информацию, такую ​​как имя, уровень, мир и дата последнего входа.C# - Невозможно вставить данные в базу данных MySQL

Итак, я создал объект под названием 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, но я не могу понять, как вставить данные.

Я установил соединение, и я попытался выбрать данные, и он отлично работает. Так что моя связь неплохая. Но вставка, похоже, не работает.

Вот мой код, я добавить, чтобы вставить данные в таблицах:

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 или что?

+0

У вас есть строковые данные, в которых должны быть переменные. Вы должны посмотреть, как использовать параметры с вашим запросом, это решит вашу проблему. Как бы то ни было, у вас есть строка с именами переменных в ней, которая ничего не делает, потому что она не разыскивает внутренне в строке (по крайней мере, не в C# 5, C# 6, но синтаксис отличается) , –

+0

Я попытался вставить данные вручную, и я сделал это так: values ​​('1', 'hello'), и это сработало. не должен ли я просто вводить строки вместо ' – aliazik

+0

Нет, я не думаю, что вы получаете то, что я говорю ... '" INSERT (..) VALUES (myvariable) "' это не то же самое, что '" INSERT (..) VALUES ("+ myvariable +") "' –

ответ

2

Попробуйте следующее:

using(var connection = new MySqlConnection(connectionString)) 
{ 
    connection.Open(); 
    using(var command = new MySqlCommand()) 
    { 
     command.Connection = connection; 
     command.CommandText = @"INSERT INTO rookstayers (name, sex, vocation, level, achievements, world, lastlogin, accountstatus, onlinestatus) VALUES (@name, @sex, @vocation, @level, @achievements, @world, @lastLogin, @accountStatus, @onlineStatus)"; 
     command.Prepare(); 

     foreach(var rooker in Players) 
     { 
      command.Parameters.Clear(); 
      command.Parameters.AddWithValue("@name", rooker.Name); 
      command.Parameters.AddWithValue("@sex", rooker.Sex); 
      command.Parameters.AddWithValue("@vocation", rooker.Vocation); 
      command.Parameters.AddWithValue("@level", rooker.Level); 
      command.Parameters.AddWithValue("@achievements", rooker.Achievements); 
      command.Parameters.AddWithValue("@world", rooker.World); 
      command.Parameters.AddWithValue("@lastLogin", rooker.LastLogin); 
      command.Parameters.AddWithValue("@accountStatus", rooker.AccountStatus); 
      command.Parameters.AddWithValue("@onlineStatus", rooker.OnlineStatus); 
      command.ExecuteNonQuery(); 
     } 
    } 
} 

Обратите внимание на различие:

  1. Обертывание одноразовых предметов (т.е. MySQLConnection и MySQLCommand) в используя утверждения.
  2. Обновлена ​​команда SQL insert для использования SQL-параметров. В этом случае «@name» будет заменено значением rooker.Name при выполнении команды.
  3. Исключенный столбец id в инструкции insert, поскольку я предполагаю, что это столбец идентификации , поэтому вам не нужно явно включать это.
  4. И, наконец, использование command.Prepare(). Как указано в документации на MySQL .NET here, она может обеспечить значительные улучшения производительности при запросах, которые выполняются более одного раза.
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-инъекцию.

+0

Вы должны показать, как разместить '@ name' в запросе. –

+0

@RonBeyer - обновлен, чтобы отразить. –

+0

Где именно я должен добавить это? Как это? 'foreach (Player rooker in Players) { \t \t command.Parameters.AddWithValue (" @ name ", rooker.Name); \t \t \t \t command.Parameters.AddWithValue ("@ sex", rooker.Sex); \t \t \t \t command.Parameters.AddWithValue ("@ призвание", rooker.Vocation); command.CommandText = "Вставить в ладдеки (id, имя, пол, призвание, уровень, достижения, мир, lastlogin, accountstatus, onlinestatus) значения ('', @name, @sex, @vocation .....) conn.Open(); command.ExecuteNonQuery();!. } ' – aliazik

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 параметров без установки значения. И, как было предложено ниже, г-н добавляет призыв к команде. Prepare может повысить производительность.

Внутри цикла для каждого определяемого параметра вы можете установить его значение и вызвать команду для выполнения.

Я также хочу указать на инструкцию using, которая обеспечивает правильное закрытие и удаление объектов и использование Add с соответствующим параметром, установленным для каждого параметра, а не AddWithValue. AddWithValue - это ярлык с многочисленными недостатками, как вы можете прочитать в этой статье. Can we stop using AddWithValue already?

Последний совет, если такие преобразования между объектами и данными происходят очень часто, вы должны потратить немного времени, чтобы научиться использовать ORM инструмент, подобный Dapper

EDIT: Если вы посмотрите на весь ваш код, вам кажется, что вы пропустите важный шаг в ваших выскабливаниях.Вам нужно добавить плеер в свой список игроков

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 
      ....... 
+0

попробует, держись! – aliazik

+0

Я просто не могу заставить его работать. Я буквально понятия не имею, что я делаю неправильно. Я попытался распечатать значения в Player (имя/призвание/уровень и т. Д.), И он печатает правильные значения. Но всякий раз, когда я пытаюсь вставить их в базу данных, это похоже на то, что они равны нулю, ничего не происходит – aliazik

+0

Вы видели их с помощью отладчика? Вы проверили, выполняется ли цикл? Не могли бы вы изменить вставку на этот «int rowsAdded = command.ExecuteNonQuery();», а затем распечатать значение rowsAdded? – Steve

Смежные вопросы