2016-03-31 3 views
2

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

Индекса находился вне границ массива

Я полагаю, что это потому, что у меня есть несколько ЗЕЬЕСТА , однако я не могу запустить это с помощью соединения, поскольку между этими таблицами нет ссылки.

enter image description here

Внизу строка соединения и оригинальный Выберите оператор

using (var importConnection = new OleDbConnection(
      connectionString: @"Provider=vfpoledb.1; 
      Exclusive=false; 
      data source=C:\Users\Joshua.cameron\Desktop\PCHomesImportTestBlank\PCHomesServer\DATABASE\pchomes.dbc") 
    ) 
     using (OleDbCommand CodeChange = new OleDbCommand(
       @"select NUM   
       from SYSTEMNUMBERS; 
       select PROPCODE from PROPERTY order by PROPCODE", importConnection)) 

И код для вызова и обновления.

importConnection.Open(); 

      Console.WriteLine("Visual Foxpro connection open"); 

      // Initiate the reader to SQL 
      var exportReader = CodeChange.ExecuteReader(); 

      // Start reading 
      while (exportReader != null && exportReader.Read()) 
      { 
       // Set parameter values whilst reading from SQL 
       Int32 currentNum = Int32.Parse(exportReader.GetInt32(0).ToString()); 
       string propcode = exportReader.GetValue(1).ToString(); 
       currentNum = currentNum + 1; 
       string padprop = currentNum.ToString().PadLeft(3); 
       string propcode2 = "BIDME_" + padprop; 
       // insert into VFP 
       var propins = new OleDbCommand(@"update PROPERTY set PROPCODE=" + propcode2 + "where PROPCODE=" + propcode); 
       var clientins = new OleDbCommand(@"update CLIENT set PROPCODET="+ propcode2 + "where PROPCODET=" + propcode); 
       try 
       { 
        propins.ExecuteNonQuery(); 
       } 
       catch (Exception p) 
       { 
        Console.Write("Error!"); 
        Console.Write(p); 
        Console.Read(); 
       } 
       try 
       { 
        clientins.ExecuteNonQuery(); 
       } 
       catch (Exception c) 
       { 
        Console.Write("Error!"); 
        Console.Write(c); 
        Console.Read(); 
       } 


       try 
       { 
        CodeChange.ExecuteNonQuery(); 
       } 
       catch (Exception e) 
       { 
        Console.Write("Error Writing to database"); 
        Console.Write(e); 
        Console.ReadKey(); 
       } 
      } 

      // done 
      Console.WriteLine("Complete!"); 
      importConnection.Close(); 
     } 
+0

Какова взаимосвязь между два стола? У вас есть запись в SYSTEMNUMBERS для каждой записи в таблице PROPERTY? – Steve

+0

Джошуа, вам нужно объяснить это лучше, чего вы пытаетесь достичь. Это почти невозможно понять, проверяя ваш код. Вы можете присоединиться к двум таблицам, даже если они не имеют никакого отношения, но я предполагаю, что это не то, что вы имели в виду. Вместо этого вы могли бы получить данные на локальном компьютере и «присоединиться» (.Zip) к ним со своими позициями строк (это можно сделать с помощью функции recno() для VFP, которой вы можете доверять, только если она используется в одной таблице, но не доверяет ей лучше). Если вы можете опробовать свои данные и что вы хотите достичь, мы могли бы помочь лучше. Комментарии не позволяют писать больше :( –

+0

Извинения По существу, есть две таблицы VFP, уже заполненные данными, это таблицы свойств и клиента. В каждой таблице я хочу обновить: PROPCODE в PROPERTY и PROPCODET в КЛИЕНТЕ эти два столбца соединяют две таблицы. Мне нужно обновить обе эти записи до нового значения «Propcode2», определенного в коде. SYSTEMNUMBERS не важны для этого, так как я могу определить это вручную, если необходимо. –

ответ

1

Точной причиной вашей ошибки является строка, которая пытается прочитать поле в индексе 1 DataReader. Кажется, вы предполагаете, что у вас есть два поля, потому что у вас есть два выбора. Но это не так, как работает OleDbDataReader. Ваша команда создает два разных набора данных, каждый из которых имеет только одно поле. Первый выбор производит ваш первый результат, и это набор, который вы зацикливаете.

Вы не можете объединить два результата вместе и использовать их значения в одном цикле. Сначала вам нужно будет использовать все первый результат, а затем перейти ко второму, используя метод NextResult OleDbDataReader и запустить другой цикл, который вызывает Read().

ВНИМАНИЕ Я не уверен, поддерживает ли оператор visual-foxpro несколько операторов select в той же команде. Если нет, то у вас нет выбора, кроме двух отдельных команд.

Однако, глядя на ваш код, кажется, что у вас одинаковое количество записей для каждой таблицы и без видимых связей между этими двумя таблицами.
В этом случае (и при условии, что у вас нет больших результирующих для обработки) я мог бы просто загрузить два DataTables, а затем работать на ваши обновления, используя DataRows двух таблиц

using (var importConnection = new OleDbConnection(....)) 
using (OleDbCommand CodeChange = new OleDbCommand(
    @"select NUM from SYSTEMNUMBERS; 
    select PROPCODE from PROPERTY order by PROPCODE", importConnection)) 
{ 
    importConnection.Open(); 
    DataTable sysNum = new DataTable(); 
    DataTable props = new DataData(); 
    Console.WriteLine("Visual Foxpro connection open"); 
    var exportReader = CodeChange.ExecuteReader(); 
    sysNum.Load(exportReader); 
    exportReader.NextResult(); 
    props.Load(exportReader); 
    for (int x = 0; x < sysNum.Rows.Count; x++) 
    { 
     // Set parameter values whilst reading from SQL 
     Int32 currentNum = Int32.Parse(sysNum.Rows[i][0]); 
     string propcode = props.Rows[i][0].ToString(); 

     .... continue with your current code .... 
     .... but remove this part..... 
//   try 
//   { 
//    CodeChange.ExecuteNonQuery(); 
//   } 
//   catch (Exception e) 
//   { 
//    Console.Write("Error Writing to database"); 
//    Console.Write(e); 
//    Console.ReadKey(); 
//   } 


    } 
} 

// done 
Console.WriteLine("Complete!"); 
+0

Стив, ваш код не будет работать с VFP, точка с запятой - символ продолжения команды, а VFP не понимает, что вы имели в виду. Он также не поддерживает множество наборов результатов. И еще нечисто, если ему даже нужно сделать выбор. –

+0

@CetinBasoz наверняка много путаницы здесь .... Я буду ждать ясного объяснения от OP – Steve