2016-07-06 4 views
3

Я обрабатываю большое количество встреч для отправки уведомлений csv пользователям и т. Д. То, что я хочу сделать, это установить флаг isProcessed, чтобы сказать, что текущая строка уже обработана. Я не уверен, как это сделать. что в моем текущем цикле.Batch Экспорт в CSV

public void DumpTableToFile(SqlConnection connection, string tableName, string destinationFile) 
    { 
     using (var command = new SqlCommand("select LineType,CustomerFirstName AS 'Forename' ,CustomerLastName,Age,dob as 'Date of Birth',maritalStatus AS 'Marital Status',homePhone AS 'Home', mobileNumber AS Mobile,emailAddress AS Email,Address1 + Address2 + PostCode AS 'Address' ,employmentStatus AS Employment,occupation AS Occupation,propertyValue AS 'Property Value',mortgageBalance AS 'Mortgage Balance',balanceOnSecuredDebt AS 'Balance on secured Debt',mortgageType as 'Mortgage Type' from " + tableName, connection)) 
     using (var reader = command.ExecuteReader()) 
     using (var outFile = File.CreateText(destinationFile)) 
     { 
      string[] columnNames = GetColumnNames(reader).ToArray(); 
      int numFields = columnNames.Length; 
      outFile.WriteLine(string.Join(",", columnNames)); 
      if (reader.HasRows) 
      { 
       while (reader.Read()) 
       { 
        string[] columnValues = 
         Enumerable.Range(0, numFields) 
            .Select(i => reader.GetValue(i).ToString()) 
            .Select(field => string.Concat("\"", field.Replace("\"", "\"\""), "\"")) 
            .ToArray(); 

        outFile.WriteLine(string.Join(",", columnValues)); 
       } 
      } 
     } 

Флаг называется isProcessed, и я хочу, чтобы установить его в true раз его прошла через экспорт CSV. Это значит, что я могу выполнять экспорт партии. Он существует в тех же сервировки

Edit 1

Извините за не о том, я хотел этот флаг, чтобы записать обратно в таблицу назначений для curent записи она выплевывая в CSV экспорт CSV экспортные работы Мне просто нужен способ определения того, что его экспортировали, чтобы он не обрабатывался во второй раз.

+0

Что вы хотите этот флаг, чтобы сделать? Предполагается, что это часть файла, который вы выписываете? Статус в памяти? –

+0

@EricJ. сделал редактирование там, чтобы объяснить себя, пожалуйста, см. править 1 – rogue39nin

+0

Спасибо большое за то, что голосовали там, оценили, что – rogue39nin

ответ

2

Do шаги представлены следующим образом:

  1. Добавить в критериума к вашему запросу: WHERE NOT isProcessed, так Затем вы делаете экспорт только записи, которые не обрабатываются, будут обработаны.
  2. После завершения экспорта отправьте эту команду в базу данных: "UPDATE " + tableName + " SET isProcessed=true WHERE <exact same criteria as the select statement>". Таким образом, все записи теперь помечены как обработанные.
  3. Оберните TransactionScope arround export-mechane incl. обновление. Таким образом, когда что-то не удается, вся операция будет отброшена.
  4. Оберните пробную ложь вокруг TransactionScope, поэтому при сбое экспорта CSV-файл будет удален, поэтому у вас никогда не будет половины экспортированной партии.

Ваш код станет что-то вроде этого (я не проверял):

public void DumpTableToFile(SqlConnection connection, string tableName, string destinationFile) 
{ 
    try 
    { 
     using(var transaction = new TransactionScope()) 
     { 
      // Select all non-processed records. 
      using (var command = new SqlCommand("select LineType,CustomerFirstName AS 'Forename' ,CustomerLastName,Age,dob as 'Date of Birth',maritalStatus AS 'Marital Status',homePhone AS 'Home', mobileNumber AS Mobile,emailAddress AS Email,Address1 + Address2 + PostCode AS 'Address' ,employmentStatus AS Employment,occupation AS Occupation,propertyValue AS 'Property Value',mortgageBalance AS 'Mortgage Balance',balanceOnSecuredDebt AS 'Balance on secured Debt',mortgageType as 'Mortgage Type' from " + tableName 
       + " WHERE NOT isProcessed", connection)) 
      using(var reader = command.ExecuteReader()) 
      using(var outFile = File.CreateText(destinationFile)) 
      { 
       string[] columnNames = GetColumnNames(reader).ToArray(); 
       int numFields = columnNames.Length; 
       outFile.WriteLine(string.Join(",", columnNames)); 
       if (reader.HasRows) 
       { 
        while(reader.Read()) 
        { 
         string[] columnValues = 
          Enumerable.Range(0, numFields) 
           .Select(i => reader.GetValue(i).ToString()) 
           .Select(field => string.Concat("\"", field.Replace("\"", "\"\""), "\"")) 
           .ToArray(); 

         outFile.WriteLine(string.Join(",", columnValues)); 
        } 
       } 
      } 

      // Update the same records that were just exported. 
      using (var command = new SqlCommand("UPDATE " + tableName + " SET isProcessed=true WHERE NOT isProcessed", connection)) 
       command.ExecuteNonQuery(); 

      transaction.Complete(); 
     } 
    } 
    catch 
    { 
     // If something went wrong, delete the export file. 
     File.Delete(destinationFile); 
     throw; 
    } 
} 
+0

привет, откуда берется TransactionScope? его вообще не разрешаю – rogue39nin

+0

Вы сделали ссылку на System.Transactions.dll. –

+0

Это хороший ответ, но он уязвим для атак SQL-инъекций, если пользователь когда-либо может влиять на содержимое «tableName» (как и код OP). @david, пожалуйста, убедитесь, что это невозможно. При построении запроса с пользовательским вводом обязательно и используйте параметризованные запросы. –