Команда OracleCommand, проблема ExecuteNonQuery

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

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 был бы очень хорошим решением, однако у меня нет на это прав!


person ChickSentMeHighE    schedule 21.03.2011    source источник
comment
любое окончательное решение с полным образцом исходного кода, работающим над этим?   -  person Kiquenet    schedule 28.10.2013


Ответы (4)


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

person Mike Atlas    schedule 21.03.2011

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

person Daniel Hilgarth    schedule 21.03.2011
comment
Вы не можете быть уверены, что OP действительно нуждается в возможности отмены, которая недоступна, когда trunc используется для очистки таблицы. - person Mike Atlas; 21.03.2011
comment
@Mike: Как можно отменить delete после commit? - person Daniel Hilgarth; 21.03.2011
comment
Сценарии восстановления можно пройти с помощью функции ОТМЕНЫ. download.oracle.com/docs/cd/B19306_01/ сервер.102/b14196/ - person Mike Atlas; 21.03.2011
comment
@Mike: Спасибо за ссылку. К сожалению, я думаю, что не понимаю, как это связано с отменой совершенных удалений. - person Daniel Hilgarth; 21.03.2011
comment
В производственной среде весьма вероятно, что удаляемые данные должны быть доступны для ручного восстановления (flasback в документе) до определенного момента. Усечение таблиц исключает эту возможность. Вы не указали причину, по которой вы предложили TRUNCATE вместо DELETE. - person Mike Atlas; 21.03.2011
comment
@Mike: Спасибо за объяснение. Я не разделяю вашего взгляда на то, что весьма вероятно, что флэшбэк активируется в производственной среде. Несколько крупных компаний, в которых я работал, не активировали его. Причина моего предложения: В основном, потому что это быстрее. - person Daniel Hilgarth; 21.03.2011
comment
Я предполагаю, что они не были в строго регулируемых отраслях? Впрочем, вся эта ветка уже не по теме... - person Mike Atlas; 21.03.2011

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

truncate table YourTable

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

delete from YourTable where rownum < 100

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

person Andomar    schedule 21.03.2011

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

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

person Tim    schedule 21.03.2011