powered by simpleCommunicator - 2.0.51     © 2025 Programmizd 02
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / корректная обработка ошибки SQL в С#
15 сообщений из 15, страница 1 из 1
корректная обработка ошибки SQL в С#
    #39596825
Евгенич
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Добрый день! Никак не могу заставить процедуру работать в нужном режиме:

Есть csv-файл. Есть sql-процедура, выполняющая insert в таблицу. Необходимо в цикле по всем строкам файла присваивать параметрам процедуры вставки в таблицу данные из считанной строки (чтение строки вне вопроса) и запускать процедуру.

Проблема в том, что если в sql - процедуре возникает ошибка "Cannot insert dublicate value..." - (а она бывает периодически, т.к. файл создается по принципу append и мне нужно загрузить из него только новые строки) то валится код C# в блоке try.

Думал сделать try catch в самой процедуре SQL. Но теперь ругачка "Uncommitable transaction is detected at the end of the batch"

Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
//ищем csv файлы, начинающиеся на Z
string[] files = Directory.GetFiles(Common.import_folder, "Z*.csv");

foreach (string file in files)
{

      SqlTransaction trans = Common.conn.BeginTransaction();

      try
         {
                        
                        
             string[] order = new string[0];
             string[] orders = File.ReadAllLines(file, Encoding.GetEncoding(1251));
             for (int i = 0; i < orders.Length; i++)
             {


                  if (!String.IsNullOrEmpty(orders[i]))
                  {
                                
                       order = orders[i].Split('^');     

                       using (SqlCommand cm = new SqlCommand("spGisZhkh_OrderModify", Common.conn, trans))
                       {
                            cm.CommandType = CommandType.StoredProcedure;

                            cm.Parameters.Add("@Case", SqlDbType.VarChar).Value = 0;
                            cm.Parameters.Add("@SupplierID", SqlDbType.VarChar).Value = order[0];
                            cm.Parameters.Add("@SupplierName", SqlDbType.VarChar).Value = order[1];
                                    

                            cm.ExecuteNonQuery();                       


                        }

                   }

              }

                        
               trans.Commit();
               File.Delete(file);
          }
           catch (Exception ex)
          {          
             trans.Rollback();
           }
                        



Это процедура вставки в таблицу

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
create proc spGisZhkh_OrderModify
	 @case tinyint --0-импорт,1-insert,2-modify,3-delete
	,@OrderID numeric(32,0) = null	
	,@SupplierID  varchar(25) = null	
	…

as

BEGIN

--set XACT_ABORT ON;
set nocount on;

set @RowCount=0

if @case =0  --импорт
		
		
begin try 
		--формируем запись-уведомление
		insert tGisZhkh_Order	(
			 SupplierID 
			,SupplierName 
		…
		select 
							 
			@SupplierID 
			,@SupplierName 
		…
end try
begin catch

end catch
				
...
Рейтинг: 0 / 0
корректная обработка ошибки SQL в С#
    #39596827
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Евгенич,
Убери хранимку. Она у тебя ничего не делает. Или учеба?
...
Рейтинг: 0 / 0
корректная обработка ошибки SQL в С#
    #39596829
Евгенич
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Petro123, хранимка используется во многих местах, хотелось иметь стандартный код по модификации этой таблицы.
...
Рейтинг: 0 / 0
корректная обработка ошибки SQL в С#
    #39596888
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Евгенич,
Нельзя пустые try делать. На ветку субд за подробностями.
...
Рейтинг: 0 / 0
корректная обработка ошибки SQL в С#
    #39596890
Massa52
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Евгенич,
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
//ищем csv файлы, начинающиеся на Z
string[] files = Directory.GetFiles(Common.import_folder, "Z*.csv");

foreach (string file in files)
{

      //SqlTransaction trans = Common.conn.BeginTransaction();

      try
         {
                        
                        
             string[] order = new string[0];
             string[] orders = File.ReadAllLines(file, Encoding.GetEncoding(1251));
             for (int i = 0; i < orders.Length; i++)
             {


                  if (!String.IsNullOrEmpty(orders[i]))
                  {
                                
                       order = orders[i].Split('^');     

                       using (SqlCommand cm = new SqlCommand("spGisZhkh_OrderModify", Common.conn))  //, trans))
                       {
                            cm.CommandType = CommandType.StoredProcedure;

                            cm.Parameters.Add("@Case", SqlDbType.VarChar).Value = 0;
                            cm.Parameters.Add("@SupplierID", SqlDbType.VarChar).Value = order[0];
                            cm.Parameters.Add("@SupplierName", SqlDbType.VarChar).Value = order[1];
                                    

                            cm.ExecuteNonQuery();                       


                        }

                   }

              }

                        
               //trans.Commit();
               File.Delete(file);
          }
           catch (Exception ex)
          {          
             //trans.Rollback();
           }



Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
create proc spGisZhkh_OrderModify
	 @case tinyint --0-импорт,1-insert,2-modify,3-delete
	,@OrderID numeric(32,0) = null	
	,@SupplierID  varchar(25) = null	
	…

as

BEGIN

--set XACT_ABORT ON;
set nocount on;

set @RowCount=0

if @case =0  --импорт
		
		
begin try 
		--формируем запись-уведомление
		insert tGisZhkh_Order	(
			 SupplierID 
			,SupplierName 
		…
		select 
							 
			@SupplierID 
			,@SupplierName
                 where Not Exists ...-- инсерт - если такой записи не существует 
		…
end try
begin catch

end catch

...
Рейтинг: 0 / 0
корректная обработка ошибки SQL в С#
    #39596902
Ролг Хупин
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ЕвгеничДобрый день! Никак не могу



Имхую, что это - плохо
catch (Exception ex)
{
trans.Rollback();
}

как и само открытие транзакции для одной процедуры.

Процедура сама должна открывать и обрабатывать транзакции.
...
Рейтинг: 0 / 0
корректная обработка ошибки SQL в С#
    #39596935
Сон Веры Павловны
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Row by row is slow by slow.
Здесь нужно:
1. CSV залить в DataTable.
2. На одном коннекте создать временную таблицу, залить туда данные из DataTable c помощью SqlBulkLoad, одним инсертом перелить данные из временной таблицы в рабочую. И никаких транзакций не потребуется.
...
Рейтинг: 0 / 0
корректная обработка ошибки SQL в С#
    #39596938
Massa52
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Евгенич,
Конкретно для вашего примера - транзакция мне кажется лишней.
Ну обвалится инсерт - ну бог с ним. Мне, например, совершенно непонятно, что откатывать то взад если операция инсерт не прошла.
Файл csv не удалится. Значит следующим проходом по csv файлам он пройдет.
Если конечно запись с таким ключом не существует.
...
Рейтинг: 0 / 0
корректная обработка ошибки SQL в С#
    #39596966
Евгенич
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Всем спасибо! Убрал транзакцию, поставил where not exists условие в хранимку.
...
Рейтинг: 0 / 0
корректная обработка ошибки SQL в С#
    #39597035
fkthat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Я бы попробовал вот это . Хранимки с table-value параметрами из ADO.NET можно вызывать .
...
Рейтинг: 0 / 0
корректная обработка ошибки SQL в С#
    #39597179
Сон Веры Павловны
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
fkthatЯ бы попробовал вот это . Хранимки с table-value параметрами из ADO.NET можно вызывать .
Table-valued параметр по сути - табличная переменная, со всеми её нюансами в плане оценки оптимизатором cardinality, row estimations, итд. Плюс такие нюансы, как невозможность проальтерить UDTT - только drop/create. В общем, я бы сто раз подумал, прежде чем связываться с этим хозяйством. В то время как обычные временные таблицы этих недостатков лишены.
...
Рейтинг: 0 / 0
корректная обработка ошибки SQL в С#
    #39597848
Massa52
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Евгенич,
Забыл написать, хорошая практика не удалять(File.Delete(file); файл после успешной передачи данны, а перенести в какую-нить папку, например, Archive. Еще, для полноты картины, завести папку Reject - и туда собирать не отработанные файлы. Это как бы дополнительное логирование в системе.
...
Рейтинг: 0 / 0
корректная обработка ошибки SQL в С#
    #39598654
fkthat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Сон Веры ПавловныTable-valued параметр по сути - табличная переменная, со всеми её нюансами в плане оценки оптимизатором cardinality, row estimations, итд. Плюс такие нюансы, как невозможность проальтерить UDTT - только drop/create. В общем, я бы сто раз подумал, прежде чем связываться с этим хозяйством. В то время как обычные временные таблицы этих недостатков лишены.

Да, это понятно, я не бог весть какой DBA, точнее совсем не DBA. Я просто к тому, что TVP позволяют отправить кучу данных на сервер одним запросом вместо того чтобы дергать его отдельно для каждой записи. Мы как-то, в допотопные еще времена, когда TVP не было, XML параметры для этого использовали.
...
Рейтинг: 0 / 0
корректная обработка ошибки SQL в С#
    #39598661
Сон Веры Павловны
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
fkthatДа, это понятно, я не бог весть какой DBA, точнее совсем не DBA. Я просто к тому, что TVP позволяют отправить кучу данных на сервер одним запросом вместо того чтобы дергать его отдельно для каждой записи. Мы как-то, в допотопные еще времена, когда TVP не было, XML параметры для этого использовали.
Мы тоже использовали XML - на больших данных это сильно просаживает производительность. А как отправить кучу данных разом на сервер для последующей обработки, я писал выше: 21167520 - временная таблица +SqlBulkCopy. И по производительности это самый лучший вариант, т.к. SqlBulkCopy - это managed-обертка над bulk insert, делающая вставку данных с максимальной скоростью и минимальным журналированием. Плюс возможность потом обвесить эту временную таблицу нужными индексами (у табличных переменных, как и у UDTT, индексы возможны только как реализация primary key/unique constraint), плюс нормальное вычисление оптимизатором статистики по этой таблице, итд итп.
...
Рейтинг: 0 / 0
корректная обработка ошибки SQL в С#
    #39598854
fkthat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Сон Веры ПавловныА как отправить кучу данных разом на сервер для последующей обработки, я писал выше: 21167520 - временная таблица +SqlBulkCopy. И по производительности это самый лучший вариант, т.к. SqlBulkCopy - это managed-обертка над bulk insert, делающая вставку данных с максимальной скоростью и минимальным журналированием. Плюс возможность потом обвесить эту временную таблицу нужными индексами (у табличных переменных, как и у UDTT, индексы возможны только как реализация primary key/unique constraint), плюс нормальное вычисление оптимизатором статистики по этой таблице, итд итп.

Да, посмотрел в доки, прикольно, буду теперь знать. Я просто раньше что-то думал, что BULK INSERT может только с локального (для сервера) файла загружать. Оказывается, по крайней мере с .NET клиента можно в него запульнуть сразу массив данных с клиента.
...
Рейтинг: 0 / 0
15 сообщений из 15, страница 1 из 1
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / корректная обработка ошибки SQL в С#
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]