Escribir de datatable a foxpro a través de oledb falla después de X records

Excepción no controlada: System.Data.OleDb.OleDbException: SQL: la columna 'Q578P5' no se encuentra …

Escribí una aplicación en VS2010 C # .net que lee datos de una tabla SQL en datatable y luego los escribe en tablas foxpro.

En la tabla de Inventario si falla como se indica arriba en el logging 578. En la tabla Cliente falla en la grabación 'Q617P78'

He probado problemas de datos al eliminar algunos loggings de la tabla SQL, pero el error aún ocurre en el mismo número de logging a pesar de que ese número de logging no es el mismo logging.

Intenté escribir los loggings de tabla de datos en CSV y eso funciona bien. Parece ser un problema con las tablas de FoxPro.

Los loggings de deviseio son más cortos que los loggings del cliente. Por lo tanto, sospecho que hay un problema de memory. Todo funciona como se esperaba hasta el número de logging X.

Cualquier sugerencia apreciada

namespace PLADO { class Program { static void Main(string[] args) // CUSTOMERS { // Create 2 tables - one for SQL and one for Vision DataTable VisionCustomerResultSet = new DataTable(); DataTable SQLCustomerResultSet = new DataTable(); // read data from INI string INIFilePath = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) + "\\DBCS\\PLExe.ini"; var ThisAppINIFile = new IniFile(INIFilePath.Trim()); var SQLServer = ThisAppINIFile.Read("Glo:SQLServerInstance", "Preserved"); var SQLDatabase = ThisAppINIFile.Read("Glo:SQLDatabase", "Preserved"); var SQLTrustedConnection = ThisAppINIFile.Read("Glo:TrustedConnection", "Preserved"); var SQLUsername = ThisAppINIFile.Read("Glo:SQLUsername", "Preserved"); var SQLUserPassword = ThisAppINIFile.Read("Glo:SQLUserPassword", "Preserved"); var SQLConnectionString = "Server=" + SQLServer + ";Database=" + SQLDatabase + ";User ID=" + SQLUsername + ";Password=" + SQLUserPassword + ";"; var ADOConnectionString = ThisAppINIFile.Read("Glo:ADOConnectionString", "Preserved"); // Open the SQL database SqlConnection sqlCon = new SqlConnection(SQLConnectionString); sqlCon.Open(); // Open the Foxpro database OleDbConnection oleDbConnection1 = new OleDbConnection(ADOConnectionString); oleDbConnection1.Open(); // read the SQL values into DataTAble string commandString = "SELECT [uniqueid],[ledgerno],[accountno],[sortcode],(clipped for readability)...[zgrouping],[zclegacy],[zmarket] FROM [PrimeLaundry].[dbo].[Vision_Customer]"; SqlCommand sqlCmd = new SqlCommand(commandString, sqlCon); SqlDataAdapter sda = new SqlDataAdapter(sqlCmd); sda.Fill(SQLCustomerResultSet); // read the select statement results into the dataTable // cycle through DataTable foreach (DataRow row in SQLCustomerResultSet.Rows) { // read a matching record from Foxpro Console.WriteLine(row["AccountNo"]); string selectStatement = "select accountno from Customer where accountno = '" + row["AccountNo"] + "'"; string insertStatement = "INSERT INTO CUSTOMER ([uniqueid],[ledgerno],[accountno],[sortcode],[title], (clipped for readability)...,[zclegacy],[zmarket])" + " Values(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)"; string updateStatement = "UPDATE CUSTOMER SET sortcode = ?,title = ?,periods = ?,groupno = ? (clipped for readability)... ?,ordnoreq = ?,zrunno = ?,zgrouping = ?,zclegacy = ?,zmarket = ? where Accountno = '" + row["AccountNo"] + "'"; OleDbCommand selectCommand = new OleDbCommand(selectStatement, oleDbConnection1); OleDbCommand insertCommand = new OleDbCommand(insertStatement, oleDbConnection1); OleDbCommand updateCommand = new OleDbCommand(updateStatement, oleDbConnection1); String selectQueryResult = (String)selectCommand.ExecuteScalar(); if (string.IsNullOrEmpty(selectQueryResult)) { insertCommand.Parameters.Add("uniqueid", OleDbType.VarChar).Value = row["uniqueid"]; insertCommand.Parameters.Add("ledgerno", OleDbType.Numeric).Value = row["ledgerno"]; insertCommand.Parameters.Add("accountno", OleDbType.VarChar).Value = row["accountno"]; insertCommand.Parameters.Add("sortcode", OleDbType.VarChar).Value = row["sortcode"]; (Clipped for readability) row["zgrouping"]; insertCommand.Parameters.Add("zclegacy", OleDbType.VarChar).Value = row["zclegacy"]; insertCommand.Parameters.Add("zmarket", OleDbType.VarChar).Value = row["zmarket"]; int count = insertCommand.ExecuteNonQuery(); } else { updateCommand.Parameters.Add("Sortcode", OleDbType.VarChar, 2).Value = row["sortcode"]; updateCommand.Parameters.Add("title", OleDbType.VarChar).Value = row["title"]; updateCommand.Parameters.Add("periods", OleDbType.Numeric).Value = row["periods"]; updateCommand.Parameters.Add("groupno", OleDbType.Numeric).Value = row["groupno"]; (Clipped for readability) updateCommand.Parameters.Add("zclegacy", OleDbType.VarChar).Value = row["zclegacy"]; updateCommand.Parameters.Add("zmarket", OleDbType.VarChar).Value = row["zmarket"]; int count = updateCommand.ExecuteNonQuery(); } // end of if (string.IsNullOrEmpty... } // end of foreach look // INVENTORY // Create 2 tables - one for SQL and one for Vision DataTable VisionInventoryResultSet = new DataTable(); DataTable SQLInventoryResultSet = new DataTable(); // read the SQL values into DataTAble commandString = "SELECT [uniqueid],[ledgerno],[accountno],[sortcode],[title],[periods],[groupno],[taxcode],[taxcode2],[leadtime],[reorder],[binno],[alternate],[remarks],[salesunit],[purchunit],[weight],[ctryorigin],[commodity],[spratio],[price1],(Clipped for readability)...[kitcomp],[usenetworkingit],[lastdeldat],[maxreorder],[zprodgroup] FROM [PrimeLaundry].[dbo].[Vision_Inventory]"; sqlCmd = new SqlCommand(commandString, sqlCon); sda = new SqlDataAdapter(sqlCmd); sda.Fill(SQLInventoryResultSet); // read the select statement results into the dataTable // cycle through DataTable foreach (DataRow row in SQLInventoryResultSet.Rows) { // read a matching record from Foxpro string selectStatement = "select accountno from Inventry where accountno = '" + row["AccountNo"] + "'"; string insertStatement = "INSERT INTO INVENTRY ([uniqueid],[ledgerno],[accountno],[sortcode],[title],[periods],[groupno],[taxcode],[taxcode2],[leadtime],[reorder],[binno],[alternate],(Clipped for readability)...,[zprodgroup],[zilegacy])" + " Values(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,' ')"; string updateStatement = "UPDATE INVENTRY SET sortcode = ?,title = ?,periods = ?,groupno = ?,taxcode = ?,taxcode2 = ?,leadtime = ?,reorder = ?,binno = ?,alternate = ?,remarks = ?,salesunit = ?,purchunit = ?(Clipped for readability)...maxreorder = ?,zprodgroup = ? where Accountno = '" + row["AccountNo"] + "'"; OleDbCommand selectCommand = new OleDbCommand(selectStatement, oleDbConnection1); OleDbCommand insertCommand = new OleDbCommand(insertStatement, oleDbConnection1); OleDbCommand updateCommand = new OleDbCommand(updateStatement, oleDbConnection1); string selectQueryResult = (String)selectCommand.ExecuteScalar(); if (string.IsNullOrEmpty(selectQueryResult)) { insertCommand.Parameters.Add("uniqueid", OleDbType.VarChar).Value = row["uniqueid"]; insertCommand.Parameters.Add("ledgerno", OleDbType.Numeric).Value = row["ledgerno"]; insertCommand.Parameters.Add("accountno", OleDbType.VarChar).Value = row["accountno"]; insertCommand.Parameters.Add("sortcode", OleDbType.VarChar).Value = row["sortcode"]; (Clipped for readability)... insertCommand.Parameters.Add("maxreorder", OleDbType.Numeric).Value = row["maxreorder"]; insertCommand.Parameters.Add("zprodgroup", OleDbType.VarChar).Value = row["zprodgroup"]; int count = insertCommand.ExecuteNonQuery(); } else { updateCommand.Parameters.Add("Sortcode", OleDbType.VarChar, 2).Value = row["sortcode"]; updateCommand.Parameters.Add("title", OleDbType.VarChar).Value = row["title"]; updateCommand.Parameters.Add("periods", OleDbType.Numeric).Value = row["periods"]; (Clipped for readability)... updateCommand.Parameters.Add("zprodgroup", OleDbType.VarChar).Value = row["zprodgroup"]; int count = updateCommand.ExecuteNonQuery(); } } oleDbConnection1.Close(); sqlCon.Close(); } } 

}

Según lo que proporcionó, podría estar fallando en los problemas de recolección de basura. Está creando el command y los parameters repetidamente, lo que podría simplificarse al crear previamente el command y los parameters UNA VEZ, luego, para cada logging, simplemente reinicie el parámetro VALOR para cada vez que pase … He reestructurado y he hecho genérico pero bajo un SIMILAR acercamiento a lo que tuviste Al hacerlo de la manera que tengo, estoy construyendo los commands y los parameters UNA VEZ, preparando los PARÁMETROS una vez, luego recorro los loggings. Muy pocos problemas de recolección de basura / problemas de pérdida de memory que pueda encontrar …

 string ins = "insert into MyTable ( ColA, ColB, ColC, ..., ColZ ) values ( ?, ?, ?, ..., ? )" string upd = "update MyTable set ColA = ?, ColB = ?, ColC = ?, ..., ColZ = ? where pkColumn = ?" OleDbCommand insCmd = new OleDbCommand(ins, oleDbConnection1); OleDbCommand updCmd = new OleDbCommand(upd, oleDbConnection1); 

De esta manera, las columnas son IDENTICAS en order secuencial, con la exception de la actualización donde la columna WHERE siempre es LAST. Ahora, después de consultar la database SQL, obtenga una sola fila como muestra … ENTONCES, llame a la function con el command Y la fila para representar los parameters fuente de origen, como

 DataRow tmpRow = SQLCustomerResultSet.Rows[0]; prepParameters( insCmd, tmpRow, false ); prepParameters( updCmd, tmpRow, true ); private void prepParameters( OleDbCommand oCmd, DataRow oSampleRow, bool IsUpdate ) { oCmd.Parameters.Add("ColA", OleDbType.VarChar).Value = oSampleRow["ColA"]; oCmd.Parameters.Add("ColB", OleDbType.Numeric).Value = oSampleRow["ColB"]; oCmd.Parameters.Add("ColC", OleDbType.VarChar).Value = oSampleRow["ColC"]; ... oCmd.Parameters.Add("ColZ", OleDbType.VarChar).Value = oSampleRow["ColZ"]; if( IsUpdate ) oCmd.Parameters.Add("PKCol", OleDbType.VarChar).Value = oSampleRow["PKCol"]; } 

Finalmente, creé una function para preparar cualquiera de los commands de inserción o actualización de una manera similar al pasar el command y la fila para no omitir el order, perder una columna, etc.

 private void AssignParameters( OleDbCommand oCmd, DataRow oSampleRow, bool IsUpdate ) { oCmd.Parameters[0].Value = oSampleRow["ColA"]; oCmd.Parameters[1].Value = oSampleRow["ColB"]; oCmd.Parameters[2].Value = oSampleRow["ColC"]; ... oCmd.Parameters[n].Value = oSampleRow["ColZ"]; if( IsUpdate ) oCmd.Parameters[extra].Value = oSampleRow["PKColumn"]; } 

Y mi ciclo final para pasar y procesar sería algo así como …

 foreach (DataRow row in SQLCustomerResultSet.Rows) { // read a matching record from Foxpro Console.WriteLine(row["AccountNo"]); // Just update the respective command parameter for the select... selectCommand.Parameters[0].Value = row["AccountNo"]; // NOW, execute since we changed the parameter above before executing it. String selectQueryResult = (String)selectCommand.ExecuteScalar(); if (string.IsNullOrEmpty(selectQueryResult)) { // with my simplified approach... AssignParameters( insCmd, row, false ); // and now execute it... int count = insCmd.ExecuteNonQuery(); } else { // with my simplified approach... AssignParameters( updCmd, row, true ); // and now execute it... int count = updCmd.ExecuteNonQuery(); } // end of if (string.IsNullOrEmpty... } // end of foreach look 

Parece poco probable en function de la cantidad de loggings de los que está hablando, pero ¿hay alguna posibilidad de que llegue al límite de 2 GB por file en VFP?