как улучшить этот код - PullRequest
       4

как улучшить этот код

1 голос
/ 18 декабря 2010
            // conn is read from handydrive
            //conn2 read from C:\

этот код предназначен для записи новой записи в БД в C: \ путем проверки существуют в первую очередь.моя проблема слишком медленная для многих записей.и как его улучшить чтобы быстрее ...

        SqlCeCommand cmd1 = new SqlCeCommand("Select * from bill_discount  ", conn);

        SqlCeDataReader dr1 = cmd1.ExecuteReader();

        while (dr1.Read() != false)
        {
            SqlCeCommand cmd4 = new SqlCeCommand("Select * from bill_discount where bill_no='" + dr1.GetInt32(0) + "' AND bill_shopdc='" + dr1.GetString(2) + "'  ", conn2);

            SqlCeDataReader dr4 = cmd4.ExecuteReader();
            if (dr4.Read() == false)
            {
                SqlCeCommand cmd2 = new SqlCeCommand("INSERT INTO bill_discount (bill_no,bill_value,bill_shopdc) VALUES ('" + dr1.GetInt32(0) + "','" + dr1.GetDouble(1) + "','" + dr1.GetString(2) + "') ", conn2);

               // SqlCeDataReader dr2 = cmd2.ExecuteReader();
                cmd2.ExecuteNonQuery();

            }

        }
        //-------------------------------------------------------------------

Ответы [ 3 ]

3 голосов
/ 18 декабря 2010

Я бы взглянул на SqlBulkCopy Class :

Позволяет эффективно загружать SQL Таблица сервера с данными из другого источник.

BTW : В приведенном выше коде выбор всей таблицы bill_discount не очень хорошая идея, особенно если таблица большая.

[Кроме того, похоже, что вы могли бы выполнить один оператор TSQL вместо того, чтобы циклически проходить по каждой строке и выполнять циклическое переключение в базу данных.]

Этот пример должен помочь: SqlBulkCopy - Копировать данные таблицы между серверами SQL с высокой скоростью - ADO.NET 2.0 Новая функция

1 голос
/ 19 декабря 2010

Я вижу, вы используете SqlCe, который имеет ряд ограничений при вставке объемных данных. Основным ограничением является действительный SqlCe Engine. Однако вы можете обойти это, используя прямую вставку таблицы:

using (var command = connection.CreateCommand())
                     {
                         command.Transaction = transaction;
                         command.CommandType = CommandType.TableDirect;
                         command.CommandText = TABLE_NAME_IN_SQL;

                         using (var rs = command.ExecuteResultSet(ResultSetOptions.Updatable))
                         {
                             var rec = rs.CreateRecord();
                             rec.SetInt32(0, value0); // the index represents the column numbering
                             rec.SetString(1, value1);
                             rec.SetInt32(2, value2);
                             rs.Insert(rec);
                         }
}
1 голос
/ 18 декабря 2010

Давайте начнем с того, что сделаем код более читабельным. Вот результат:

SqlCeCommand getAllBills = new SqlCeCommand("select * from bill_discount", primaryConnection);
SqlCeDataReader allBillsReader = getAllBills.ExecuteReader();
while (allBillsReader.Read())
{
    SqlCeCommand getBill = new SqlCeCommand("select * from bill_discount where bill_no = '" + allBillsReader.GetInt32(0) + "' and bill_shopdc = '" + allBillsReader.GetString(2) + "'  ", secondaryConnection);
    SqlCeDataReader billReader = getBill.ExecuteReader();
    if (!billReader.Read())
    {
        SqlCeCommand addMissingBill = new SqlCeCommand("insert into bill_discount (bill_no, bill_value, bill_shopdc) values ('" + allBillsReader.GetInt32(0) + "', '" + allBillsReader.GetDouble(1) + "', '" + allBillsReader.GetString(2) + "')", secondaryConnection);
        addMissingBill.ExecuteNonQuery();
    }
}

Одноразовые предметы должны быть утилизированы. Давай сделаем это.

Давайте также удалим SQL-инъекции.

Наконец, давайте оптимизируем второй запрос: вам не нужно выбирать что-то и выполнять программу чтения, если вы просто хотите проверить, существует ли значение в базе данных.

using (SqlCeCommand getAllBills = new SqlCeCommand("select bill_no, bill_value, bill_shopdc from [bill_discount]", primaryConnection))
{
    using (SqlCeDataReader allBillsReader = getAllBills.ExecuteReader())
    {
        while (allBillsReader.Read())
        {
            using (SqlCeCommand getBill = new SqlCeCommand("if exists(select * from [bill_discount] where [bill_no] = @billNumber and bill_shopdc = @billShop) select 1 else select 0", secondaryConnection))
            {
                getBill.Parameters.AddWithValue("@billNumber", allBillsReader["bill_no"]);
                getBill.Parameters.AddWithValue("@billShop", allBillsReader["bill_shopdc"]);

                bool billExists = Convert.ToBoolean(getBill.ExecuteScalar());
                if (!billExists)
                {
                    using (SqlCeCommand addMissingBill = new SqlCeCommand("insert into [bill_discount] ([bill_no], [bill_value], [bill_shopdc]) values (@billNumber, @billValue, @billShop)", secondaryConnection))
                    {
                        addMissingBill.Parameters.AddWithValue("@billNumber", allBillsReader["bill_no"]);
                        addMissingBill.Parameters.AddWithValue("@billValue", allBillsReader["bill_value"]);
                        addMissingBill.Parameters.AddWithValue("@billShop", allBillsReader["bill_shopdc"]);

                        int countAffectedRows = addMissingBill.ExecuteNonQuery();
                        Debug.Assert(countAffectedRows == 1, "The data was not inserted.");
                    }
                }
            }
        }
    }
}

Итак, мы здесь.

Теперь это решение с низкой производительностью. Чтобы быть более эффективным, вы можете сделать то же самое в отдельном запросе SQL с объединениями . Поскольку две таблицы, вероятно, расположены на разных серверах, вы можете посмотреть на связанных серверов : возможность, позволяющая выполнить один запрос для нескольких таблиц с нескольких серверов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...