Syf AK Ответов: 3

Как я могу использовать транзакции в C#


Привет, я написал простой запрос, который выбирает данные из БД, и эти данные я вставляю в разные таблицы. Я должен использовать транзакции здесь, если какой-либо один запрос не удалось выполнить, ни один из них не должен выполняться. Может ли кто-нибудь, пожалуйста, помочь мне, как я могу это сделать?

Что я уже пробовал:

DataTable dtInsertData = new DataTable();
try
{
   dLib = new DataLibrary("VillageMate", false);
   dtInsertData = dLib.GetDataTable("SELECT * FROM VillageMate_ESS  where LogID=(select  max(LogID) from [VillageMate_ESS])");
   if (dtInsertData.Rows.Count>0)
   {
     dLib = new DataLibrary("ESS", false);

     sqlQUERY =   "INSERT INTO  [MSTR_Employee] (FirstName, NationalID, EmployeeCode,CreatedDateTime,RecordStatus) VALUES ('"+dtInsertData.Rows[0]["Name"].ToString() + " ' , '" + dtInsertData.Rows[0]["IDNumber"].ToString() + "' , '" + dtInsertData.Rows[0]["RFID"].ToString()+"' , '"+DateTime.Now.ToString()+"' , '"+true+"')";

    sqlQUERY += "INSERT INTO  [MSTR_Employee_Optional] (TNAEnrollID, CreatedDateTime,RecordStatus) VALUES ('" + dtInsertData.Rows[0]["RFID"].ToString() + "' , '" + DateTime.Now.ToString() + "' , '" + true + "')";

    sqlQUERY+= "INSERT INTO  [ACS_Card] (CardNumber, StartDate,EndDate, GUIDCard, CreatedDateTime,RecordStatus) VALUES ('" + dtInsertData.Rows[0]["IDNumber"].ToString() +
                            " ' , '" + dtInsertData.Rows[0]["ValidFromDate"].ToString() + "' , '" + dtInsertData.Rows[0]["ValidToDate"].ToString() + "' ,'" + dtInsertData.Rows[0]["RFID"].ToString() + "', '" + DateTime.Now.ToString() + "' , '" + true + "')";

                   sqlQUERY+= "INSERT INTO  [ACS_CardOption] (IsVisitorCard,IsGuardCard, TraceAccess, CreatedDateTime,RecordStatus) VALUES ('" + true +
                            " ' , '" + false + "' , '" + false + "' , '" + DateTime.Now.ToString() + "' , '" + true + "')";

       sqlQUERY+= "INSERT INTO  [ACS_CardStatus] (CardStatus, CreatedDateTime,RecordStatus) VALUES ('" + 5 +
                            " ' , '" + DateTime.Now.ToString() + "' , '" + true + "')";

       sqlQUERY+="INSERT INTO  [ACS_ActivityTransaction] (ActivityStatus, ActivityFailCount,ActivitySource, CreatedDateTime,RecordStatus) VALUES ('" + true +
                            " ' , '"+0+"' , '"+0+"' , '" + DateTime.Now.ToString() + "' , '" + true + "')";

      int status = dLib.ExecuteNonQuery(sqlQUERY);
     }
        return dtInsertData;
   }
   catch (Exception ee)
   {
      WriteLogs.WriteErrorLogs(-1, 0, GetType().FullName + "." + MethodBase.GetCurrentMethod().Name, ee.ToString());
      return null;
   }

3 Ответов

Рейтинг:
2

Patrice T

 sqlQUERY =   "INSERT INTO  [MSTR_Employee] (FirstName, NationalID, EmployeeCode,CreatedDateTime,RecordStatus) VALUES ('"+dtInsertData.Rows[0]["Name"].ToString() + " ' , '" + dtInsertData.Rows[0]["IDNumber"].ToString() + "' , '" + dtInsertData.Rows[0]["RFID"].ToString()+"' , '"+DateTime.Now.ToString()+"' , '"+true+"')";

sqlQUERY += "INSERT INTO  [MSTR_Employee_Optional] (TNAEnrollID, CreatedDateTime,RecordStatus) VALUES ('" + dtInsertData.Rows[0]["RFID"].ToString() + "' , '" + DateTime.Now.ToString() + "' , '" + true + "')";

Не решение вашего вопроса, а еще одна проблема, которая у вас есть.
Никогда не создавайте SQL-запрос путем объединения строк. Рано или поздно вы сделаете это с помощью пользовательских вводов, и это откроет дверь к уязвимости под названием "SQL-инъекция", она опасна для вашей базы данных и подвержена ошибкам.
Одна кавычка в имени - и ваша программа выйдет из строя. Если пользователь вводит имя, например "Брайан О'Коннер", может привести к сбою вашего приложения, это уязвимость SQL-инъекции, и сбой-это наименьшая из проблем, вредоносный пользовательский ввод, и он продвигается к командам SQL со всеми учетными данными.
SQL-инъекция - Википедия[^]
SQL-инъекция[^]
Атаки SQL-инъекций на примере[^]
PHP: SQL-инъекция - руководство пользователя[^]
Шпаргалка по предотвращению инъекций SQL - OWASP[^]
Как я могу объяснить SQL-инъекцию без технического жаргона? - Обмен Стеками Информационной Безопасности[^]


Рейтинг:
2

Dave Kreskowiak

Во-первых, Google для "атаки SQL-инъекций", чтобы выяснить, почему запросы, которые вы написали, плохи. Вы также значительно усложнили отладку этого кода. Например, что делать, если в любом из этих полей есть символ'? Ваш запрос просто не удался, или еще хуже.

Затем Google для "параметризованных запросов C#", чтобы узнать, что делать, и сделать ваш код легче отлаживать и поддерживать в этом процессе.

Теперь вы можете перейти к транзакциям. Вы можете сделать это довольно легко с помощью класс TransactionScope[^].


Syf AK

Спасибо за предложение, сэр, не могли бы вы изменить любой запрос как параметризованный запрос, чтобы я мог ясно понять.@Дэйв Керсковяк

Dave Kreskowiak

Нет. Я точно сказал вам, что нужно ввести в Google. Это до вас, чтобы начать читать, так что вы можете действительно понять. То, что я просто переписываю твой код для тебя, этого не сделает.

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

Рейтинг:
2

MadMyche

Моя рекомендация состояла бы в том, чтобы взять все запросы и поместить их в хранимую процедуру. Помимо меньшей сложности кода и сетевого чата, исходный запрос не имеет параметров, поэтому не было бы никакой уязвимости SQL-инъекции.