Команда OracleCommand, проблема ExecuteNonQuery - PullRequest
4 голосов
/ 21 марта 2011

Я должен очистить определенные таблицы в базе данных Oracle, однако, когда у меня возникают проблемы с запуском следующего кода

public static void ClearDataTables(IList<string> tableNames)
        {
            string connectionString = "CONNECTIONSTRING";
            using (OracleConnection connection = new OracleConnection())
            {
                connection.ConnectionString = connectionString;
                connection.Open();
                foreach (string table in tableNames)
                {
                    OracleCommand command = connection.CreateCommand();
                    string sql = String.Format("DELETE FROM TOA_REPORTING.{0}", table);
                    command.CommandText = sql;
                    command.ExecuteNonQuery();
                }
                connection.Close();
            }
        }

Я вызываю этот метод с этим списком

ClearDataTables(new List<string> { "GROUP_DEFINITION", "GROUP_REPORT_EMAIL_LIST", "GROUP_EQUIPMENT_GROUP_STN_XREF"});

Он отлично работает с первыми двумя таблицами, однако на третьей он застревает и приложение работает вечно ...

Забавно, когда я переключаю «GROUP_REPORT_EMAIL_LIST» и «GROUP_EQUIPMENT_GROUP_STN_XREF» Приложение запускается навсегда после того, как оно достигает второго имени таблицы.

Итак, в заключение, функция запускается вечно, когда нажимает «GROUP_EQUIPMENT_GROUP_STN_XREF». Я убедился, что сгенерированный SQL работает, протестировав его на жабе.

Кто-нибудь еще сталкивался с этой проблемой?

РЕДАКТИРОВАТЬ - Первые две таблицы действительно очищаются при запуске.

Решение

string connectionString = "CONNECTIONSTRING";
            using (OracleConnection connection = new OracleConnection(connectionString))
            {
                connection.Open();
                OracleCommand command = connection.CreateCommand();
                OracleTransaction trans = connection.BeginTransaction();
                command.Transaction = trans;
                foreach (string table in tableNames)
                {
                    string sql = String.Format("DELETE FROM TOA_REPORTING.{0}", table);
                    command.CommandText = sql;
                    command.ExecuteNonQuery();
                }
                trans.Commit();
            }

TRUNCATE было бы очень хорошим решением, однако у меня нет привилегий для этого!

Ответы [ 4 ]

10 голосов
/ 21 марта 2011

Вы забыли зафиксировать свои изменения в Toad (или любом другом клиенте)?Открытая транзакция заставит его ждать бесконечно.

3 голосов
/ 21 марта 2011

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

truncate table YourTable

Если вы это сделаете, разделите delete на транзакции небольшого размера.В основном запускайте:

delete from YourTable where rownum < 100

, пока таблица не станет пустой.Смотрите, например, это сообщение в блоге .

3 голосов
/ 21 марта 2011

Много ли в этой таблице данных? Это объясняет, почему удаление данных занимает так много времени.
В любом случае, я предлагаю использовать TRUNC для очистки таблиц.

2 голосов
/ 21 марта 2011

Я бы, вероятно, написал бы хранимую процедуру, которая выполняет все удаления или усечения и вызывал бы SP один раз, а не имел бы цикл на стороне клиента.

РЕДАКТИРОВАТЬ: Было бы также лучше не создаватьКомандный объект внутри цикла.Создайте его один раз вне цикла с параметром table-name, а затем вызовите его, передавая ему другое значение параметра на каждой итерации.Но SP должен быть предпочтительным.

...