Невозможно удалить апостроф из строки, чтобы заставить запрос MySQL работать в C # - PullRequest
0 голосов
/ 28 августа 2018

Я работаю над проектом, в котором я использую метаданные mp3-песен в классе струн. Это данные (например, исполнитель, название и т. Д.), Которые я хочу скопировать в базу данных mySQL (из списка, составленного из данных), для которого у меня есть следующий запрос:

SELECT * FROM database.tablename WHERE artist='"+song[i].artist+ "' AND title='" + song[i].title + "' AND genre='"+song[i].genre+"';

Код работает отлично (зная, что 12 строк успешно скопированы), пока цикл for не достигнет песни, содержащей апостроф ('), он завершается с синтаксической ошибкой для данного символа. Например: песня [я]. Название это я не она. Я перепробовал все, что мог себе представить:

  1. Я пытался заменить 'на string.empty
  2. Пытался заменить на ""
  3. Даже пытался заменить на "''" (2 апострофа), чтобы запрос мог распознать апостроф, но, похоже, ничего не помогло (всегда получалась одна и та же синтаксическая ошибка, как в случае, когда замены даже не было)

Вот строка, чтобы вы могли видеть, как я пытался: song[i].artist = song[i].artist.Replace("'","");

Итак, мой вопрос: есть ли какое-нибудь решение, чтобы избавиться от апострофа, или каким-либо образом заставить запрос работать?

РЕДАКТИРОВАТЬ: Вот мой оригинальный код (только для цикла) для лучшего понимания.

for (int i = 0; i < Array.Length; i++)
            {
                Command = @"SELECT * FROM database.tablename WHERE artist='"+song[i].artist+ "' AND title='" + song[i].title + "' AND genre='"+song[i].genre+"';";
                MySqlCommand myCommand = new MySqlCommand(Command);
                using (MySqlConnection mConnection = new MySqlConnection(ConnectionString.ToString()))
                {
                    adapter = new MySqlDataAdapter(Command,mConnection);
                    mConnection.Open();
                    adapter.Fill(dataset);
                    int adat = dataset.Tables[0].Rows.Count;
                    if (adat <= 0)       //if current data does not exist
                    {
                        song[i].artist = song[i].artist.Replace("'","\'");
                        song[i].title = song[i].title.Replace("'", "\'");
                        song[i].genre = song[i].genre.Replace("'", "\'");
                        myCommand = new MySqlCommand("INSERT INTO database.tablename (artist,title,length,genre) VALUES ('"+song[i].artist+"','"+song[i].title+"','"+song[i].length+"','"+song[i].genre+"');",mConnection);
                        myCommand.ExecuteNonQuery();
                        dataset.Clear();
                    }
                    mConnection.Close();
                }
            }

И вот что я "использую" (извините, не знаю, как сделать так, чтобы это выглядело правильно):

используя Систему; using System.Collections.Generic; using System.ComponentModel; используя System.Data; использование System.Drawing; использование System.Linq; используя System.Text; использование System.Threading.Tasks; использование System.Windows.Forms; используя System.IO; используя TagLib; используя TagLib.Id3v2; используя System.Configuration; using System.Data.SqlClient; используя MySql; используя MySql.Data; использование MySql.Data.MySqlClient; использование Programname.Properties;

Ответы [ 2 ]

0 голосов
/ 28 августа 2018

Просто добавьте в микстуру независимое от поставщика данных решение. Это подход, который вы можете использовать, чтобы отделить код от MySql.

ConnectionString можно установить в app / web.config:

<connectionStrings>
  <add name="Example" providerName="MySql.Data.MySqlClient" connectionString="Data Source=1.1.1.1"/>
</connectionStrings>

И код будет использовать System.Data.Common классы:

var connectionSettings = ConfigurationManager.ConnectionStrings["Example"];
var dbFactory = DbProviderFactories.GetFactory(connectionSettings.ProviderName);

using (DbConnection connection = dbFactory.CreateConnection(connectionSettings.ConnectionString))
using (DbCommand countCommand = connection.CreateCommand())
{
    string sql = @"
SELECT COUNT(*) 
FROM database.tablename 
WHERE artist=@artist AND title=@title 
AND genre=@genre";

    countCommand.CommandText = sql;
    countCommand.Parameters.Add(dbFactory.GetParameter("@artist", null));
    countCommand.Parameters.Add(dbFactory.GetParameter("@title", null));
    countCommand.Parameters.Add(dbFactory.GetParameter("@genre", null));

    for (int i = 0; i < songs.Length; i++)
    {
        var song = songs[i];

        countCommand.Parameters["@artist"].Value = song.artist;
        countCommand.Parameters["@title"].Value = song.title;
        countCommand.Parameters["@genre"].Value = song.genre;

        int matches = (int)countCommand.ExecuteScalar();
        if (matches == 0)
            continue;

        using (DbCommand insertCommand = connection.CreateCommand())
        {
            string insertSql = @"
INSERT INTO database.tablename(artist, title, length, genre) 
VALUES(@artist, @title, @length, @genre";

            insertCommand.CommandText = insertSql;
            insertCommand.Parameters.Add(dbFactory.GetParameter("@artist", song.artist));
            insertCommand.Parameters.Add(dbFactory.GetParameter("@title", song.title));
            insertCommand.Parameters.Add(dbFactory.GetParameter("@length", song.length));
            insertCommand.Parameters.Add(dbFactory.GetParameter("@genre", song.genre));

            int result = insertCommand.ExecuteNonQuery();
        }
    }
}

И вы можете создавать собственные расширения, которые предлагают несколько лучшие варианты, чем то, что выходит из DbProviderFactory:

public static class FactoryExtensions
{
    public static DbParameter GetParameter(this DbProviderFactory factory, string name, object value)
    {
        var param = factory.CreateParameter();
        param.Value = value ?? DBNull.Value;
        param.Name = name;
        return param;
    }

    public static DbConnection CreateConnection(this DbProviderFactory factory, string connectionString, bool open = true)
    {
        DbConnection connection = factory.CreateConnection();
        connection.ConnectionString = connectionString;

        if (open)
            connection.Open();

        return connection;
    }
}

Очевидно, ваш код сложнее, чем приведенный вами пример, но это отправная точка.

0 голосов
/ 28 августа 2018

Как упомянул @Chad, параметры - это путь.

Со стандартными классами System.Data вы, вероятно, будете выглядеть примерно так:

// set up command using @parameters
using (SqlCommand cmd = new SqlCommand("SELECT * FROM database.tablename WHERE artist=@artist AND title=@title AND genre=@genre", connection))
{
    // add parameter values to command
    cmd.Parameters.Add(new SqlParameter("@artist", song[i].artist));
    cmd.Parameters.Add(new SqlParameter("@title", song[i].title));
    cmd.Parameters.Add(new SqlParameter("@genre", song[i].genre));

    SqlDataReader reader = cmd.ExecuteReader();

    // do useful stuff here
}

Я нашел (а затем убил) учебник по MySQL Connector / NET из здесь , который может быть немного более специфичным для MySQL:

string connStr = "*** your connection string here ***";
MySqlConnection conn = new MySqlConnection(connStr);
conn.Open();

string sql = "SELECT * FROM database.tablename WHERE artist=@artist AND title=@title AND genre=@genre";
MySqlCommand cmd = new MySqlCommand(sql, conn);

cmd.Parameters.AddWithValue("@artist", song[i].artist);
cmd.Parameters.AddWithValue("@title", song[i].title);
cmd.Parameters.AddWithValue("@genre", song[i].genre);

MySqlDataReader rdr = cmd.ExecuteReader();

// do useful stuff here

rdr.Close();
conn.Close();
...