Reading a comma-delimited text file in C # DataTable, columns truncated to 255 characters

We import from CSV to SQL. To do this, we read the CSV file and write to a temporary .txt file using schema.ini. (I'm still not sure why they are written to this temporary file, but how this code works). From there, we load the DataTable through OleDB using the following connection string (for ASCII files).

"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + sPath + ";Extended Properties=\"text;HDR=Yes;FMT=Delimited\""; 

The problem we are facing is that fields with more than 255 characters are truncated. I read online about this issue, and it seems that by default text fields are truncated this way.

I set my registry settings ImportMixedTypes=Majority Type and TypeGuessRows=0 in HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Jet\4.0\Engines\Excel , hoping that mycolumns will no longer be interpreted as text. After that, the temporary txt file is written correctly from the CSV file, but when I call dataAdapter.Fill , the resulting DataTable still has a truncated value.

Here is the column definition. CommaDelimited # txt Notes 2 false 234 true 130 0 0

Any help would be greatly appreciated. I'm currently not interested in using any kind of 3d code to solve this problem, there should be a way to use the built-in tools.

Here is the table definition:

 <Columns> <TABLE_NAME>CommaDelimited#txt</TABLE_NAME> <COLUMN_NAME>Notes</COLUMN_NAME> <ORDINAL_POSITION>2</ORDINAL_POSITION> <COLUMN_HASDEFAULT>false</COLUMN_HASDEFAULT> <COLUMN_FLAGS>234</COLUMN_FLAGS> <IS_NULLABLE>true</IS_NULLABLE> <DATA_TYPE>130</DATA_TYPE> <CHARACTER_MAXIMUM_LENGTH>0</CHARACTER_MAXIMUM_LENGTH> <CHARACTER_OCTET_LENGTH>0</CHARACTER_OCTET_LENGTH> </Columns> 

Thanks,

Greg


I tried editing the schema.ini specification with a width, and that didn't help (it was tagged before)

[CommaDelimited.txt] Format = CSVDelimited DecimalSymbol =. Col1 = 5000 text width

+4
source share
6 answers

The Jet database engine truncates memo fields if you ask to process memo-based data: aggregation, duplicate removal, formatting, etc.

http://allenbrowne.com/ser-63.html

+1
source

Here is a simple class for reading a delimited file and returning a DataTable (all rows) that does not truncate rows. It has an overloaded method for specifying column names if they are not in the file. Maybe you can use it?

Imported Namespaces

 using System; using System.Text; using System.Data; using System.IO; 

code

 /// <summary> /// Simple class for reading delimited text files /// </summary> public class DelimitedTextReader { /// <summary> /// Read the file and return a DataTable /// </summary> /// <param name="filename">File to read</param> /// <param name="delimiter">Delimiting string</param> /// <returns>Populated DataTable</returns> public static DataTable ReadFile(string filename, string delimiter) { return ReadFile(filename, delimiter, null); } /// <summary> /// Read the file and return a DataTable /// </summary> /// <param name="filename">File to read</param> /// <param name="delimiter">Delimiting string</param> /// <param name="columnNames">Array of column names</param> /// <returns>Populated DataTable</returns> public static DataTable ReadFile(string filename, string delimiter, string[] columnNames) { // Create the new table DataTable data = new DataTable(); data.Locale = System.Globalization.CultureInfo.CurrentCulture; // Check file if (!File.Exists(filename)) throw new FileNotFoundException("File not found", filename); // Process the file line by line string line; using (TextReader tr = new StreamReader(filename, Encoding.Default)) { // If column names were not passed, we'll read them from the file if (columnNames == null) { // Get the first line line = tr.ReadLine(); if (string.IsNullOrEmpty(line)) throw new IOException("Could not read column names from file."); columnNames = line.Split(new string[] { delimiter }, StringSplitOptions.RemoveEmptyEntries); } // Add the columns to the data table foreach (string colName in columnNames) data.Columns.Add(colName); // Read the file string[] columns; while ((line = tr.ReadLine()) != null) { columns = line.Split(new string[] { delimiter }, StringSplitOptions.None); // Ensure we have the same number of columns if (columns.Length != columnNames.Length) { string message = "Data row has {0} columns and {1} are defined by column names."; throw new DataException(string.Format(message, columns.Length, columnNames.Length)); } data.Rows.Add(columns); } } return data; } } 

Required Namespaces

 using System; using System.Data; using System.Windows.Forms; using System.Data.SqlClient; using System.Diagnostics; 

Here is an example of calling and loading into an SQL database:

  Stopwatch sw = new Stopwatch(); TimeSpan tsRead; TimeSpan tsTrunc; TimeSpan tsBcp; int rows; sw.Start(); using (DataTable dt = DelimitedTextReader.ReadFile(textBox1.Text, "\t")) { tsRead = sw.Elapsed; sw.Reset(); rows = dt.Rows.Count; string connect = @"Data Source=.;Initial Catalog=MyDB;Integrated Security=SSPI"; using (SqlConnection cn = new SqlConnection(connect)) using (SqlCommand cmd = new SqlCommand("TRUNCATE TABLE dbo.UploadTable", cn)) using (SqlBulkCopy bcp = new SqlBulkCopy(cn)) { cn.Open(); sw.Start(); cmd.ExecuteNonQuery(); tsTrunc = sw.Elapsed; sw.Reset(); sw.Start(); bcp.DestinationTableName = "dbo.UploadTable"; bcp.ColumnMappings.Add("Column A", "ColumnA"); bcp.ColumnMappings.Add("Column D", "ColumnD"); bcp.WriteToServer(dt); tsBcp = sw.Elapsed; sw.Reset(); } } string message = "File read:\t{0}\r\nTruncate:\t{1}\r\nBcp:\t{2}\r\n\r\nTotal time:\t{3}\r\nTotal rows:\t{4}"; MessageBox.Show(string.Format(message, tsRead, tsTrunc, tsBcp, tsRead + tsTrunc + tsBcp, rows)); 
+6
source

You can fix this by specifying your schema.ini file . I believe that there are two options - either set the column to Memo type, or set Width> 255.

0
source

My tendency would be to create a DataTable directly when reading a CSV file, instead of going through the extra step of writing data to another text file, just to read it back into memory a second time.

In this regard, how do you end up getting data from a DataTable into an SQL database? If you are just browsing a DataTable and doing a bunch of INSERT statements, why not skip the two intermediaries and invoke the same INSERT statements when you initially read the CSV file?

0
source

I think the best way to do this is to use CSVReader on the following blog: http://ronaldlemmen.blogspot.com/2008/03/stopping-and-continuing-save-event.html

0
source

I ran into a similar problem with my .NET code, and I was able to get it working by simply changing the registry settings to Majortity Type, as indicated in the original post. What I did differently in my case: Since we are trying to import from CSV, not from Excel. Therefore, I had to change the settings for text in the registry (not in Excel).

Try to do this and I think it should work

-1
source

All Articles