Import Text File into SQL Server Database using C# - c#

I am trying to import text file into sql server database and the import is working fine but the problem is that all the columns in the text file is being inserted into one column.
I need the columns from the text file to map the columns in the sql table.
here is my code
Console.WriteLine(s);
string fileName = s.ToString();
string fullPath = path + fileName.ToString();
DataTable dt = new DataTable();
dt.Columns.AddRange(new DataColumn[3] { new DataColumn("Environment", typeof(string)),
new DataColumn("Job_Name", typeof(string)),
new DataColumn("Occurs",typeof(string)) });
string csvData = File.ReadAllText(fullPath);
foreach (string row in csvData.Split('\n'))
{
if (!string.IsNullOrEmpty(row))
{
dt.Rows.Add();
int i = 0;
foreach (string cell in row.Split(','))
{
dt.Rows[dt.Rows.Count - 1][i] = cell;
i++;
}
}
}
string consString = ConfigurationManager.ConnectionStrings["myConn"].ConnectionString;
using (SqlConnection con = new SqlConnection(consString))
{
using (SqlBulkCopy sqlBulkCopy = new SqlBulkCopy(con))
{
//Set the database table name
sqlBulkCopy.DestinationTableName = "[dbo].[test2]";
con.Open();
sqlBulkCopy.WriteToServer(dt);
con.Close();
}
}

You are splitting your rows on comma when your data is tab separated. Instead do this:
row.Split('\t')
Also, don't split your entire file on \n, use File.ReadAllLines, for example:
foreach (string row in File.ReadAllLines(fullPath))
{
if (!string.IsNullOrEmpty(row))
{
dt.Rows.Add();
int i = 0;
foreach (string cell in row.Split('\t'))
{
dt.Rows[dt.Rows.Count - 1][i] = cell;
i++;
}
}
}

Below c# function import comma delimited file into C# dataTable. After getting data into dataTable you can apply your desired methods(Bulk Insert / Row by row) to take in DB :
public static DataTable ImportDataFromCSVFile(string filePath)
{
DataTable dataTable = new DataTable();
try
{
using (StreamReader readFile = new StreamReader(filePath))
{
string line;
StringBuilder sb = new StringBuilder();
string[] row;
int counter = 0;
int length = 0;
while ((line = readFile.ReadLine()) != null)
{
row = line.Split(',');
if (counter == 0)
{
length = row.Length;
DataRow dr1 = dataTable.NewRow();
for (int i = 0; i < length; i++)
{
try
{
//dataTable.Columns.Add("Col_" + i.ToString());
dataTable.Columns.Add(Convert.ToString(row[i]));
}
catch (Exception ex)
{
}
}
// dataTable.Rows.Add(dr1);
}
else
{
if (row.Length == dataTable.Columns.Count)
{
DataRow dr = dataTable.NewRow();
for (int i = 0; i < length; i++)
{
if (row[i].ToString().Contains('"'))
{
row[i] = row[i].Replace('"', ' ');
}
dr[i] = Convert.ToString(row[i]);
}
dataTable.Rows.Add(dr);
}
else
{
}
}
counter++;
}
}
}
catch (Exception ex)
{
}
return dataTable;
}

Related

Reading a text file and an xml file using one button click C#

i am trying to read an xml file and a txt file using one button click i currently have this code in my button, i don't know what it is that i'm doing wrong any help or advice of sort would be great.
try
{
XmlReader file;
file = XmlReader.Create("c:/CSAIO4D/BK01/CH01/ReadFiles/ReadFiles/XMLFile1.xml", new XmlReaderSettings());
DataSet ds = new DataSet();
ds.ReadXml(file);
dataGridView1.DataSource = ds.Tables[0];
StreamReader files = new StreamReader("c:/CSAIO4D/BK01/CH01/ReadFiles/ReadFiles/People.txt");
string[] columnnames = files.ReadLine().Split(',');
DataTable dt = new DataTable();
foreach (string c in columnnames)
{
dt.Columns.Add(c);
}
string newline;
while ((newline = files.ReadLine()) != null)
{
DataRow dr = dt.NewRow();
string[] values = newline.Split(',');
for (int i = 0; i < values.Length; i++)
{
dr[i] = values[i];
}
dt.Rows.Add(dr);
}
file.Close();
dataGridView1.DataSource = dt;
dataGridView1.Visible = true;
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
can someone please help me out, i am new to web forms, the issue that i am having is that it only reads the text file and return it to the DataGridView and does not read the xml
Here is How to read XML File
XmlDocument doc = new XmlDocument();
doc.Load("c:\\temp.xml");
Here is how to read XML in the dataset
// Here your xml file
string xmlFile = "Data.xml";
DataSet dataSet = new DataSet();
dataSet.ReadXml(xmlFile, XmlReadMode.InferSchema);
// Then display informations to test
foreach (DataTable table in dataSet.Tables)
{
Console.WriteLine(table);
for (int i = 0; i < table.Columns.Count; ++i)
Console.Write("\t" + table.Columns[i].ColumnName.Substring(0, Math.Min(6, table.Columns[i].ColumnName.Length)));
Console.WriteLine();
foreach (var row in table.AsEnumerable())
{
for (int i = 0; i < table.Columns.Count; ++i)
{
Console.Write("\t" + row[i]);
}
Console.WriteLine();
}
}
And here is
how you can read a text file
string[] lines = System.IO.File.ReadAllLines(#"C:\Users\Public\TestFolder\WriteLines2.txt");
// Display the file contents by using a foreach loop.
System.Console.WriteLine("Contents of WriteLines2.txt = ");

Skip first line File.ReadAllText for SqlBulkCopy

I have been working on this code to create a CSV Import that can be done through a webapp now what I am running into is the first row of the CSV file has headers and when I do the import I was that first line to not be in the SqlBulkCopy. Here is the code.
public partial class CS : System.Web.UI.Page
{
protected void Upload(object sender, EventArgs e)
{
//Upload and save the file
string csvPath = Server.MapPath("~/Files/") + Path.GetFileName(FileUpload1.PostedFile.FileName);
FileUpload1.SaveAs(csvPath);
DataTable dt = new DataTable();
dt.Columns.AddRange(new DataColumn[15] { new DataColumn("ORGANIZATION_ID", typeof(int)),
new DataColumn("INVENTORY_ITEM_ID", typeof(int)),
new DataColumn("ITEM_CODE", typeof(char)),
new DataColumn("SUBINVENTORY_CODE", typeof(char)),
new DataColumn("LOCATOR_ID", typeof(int)),
new DataColumn("LOCATOR_CODE", typeof(char)),
new DataColumn("QTY", typeof(int)),
new DataColumn("FLOWRACK", typeof(char)),
new DataColumn("LOCATOR_POSITION", typeof(char)),
new DataColumn("LOCATOR_BIN_LEVEL", typeof(char)),
new DataColumn("PICKING_ORDER", typeof(int)),
new DataColumn("ITEM_BOX_QUANTITY", typeof(int)),
new DataColumn("AVAILABLE_BOX_QTY", typeof(int)),
new DataColumn("AVAILABLE_MOD_QTY", typeof(int)),
new DataColumn("CreateTime", typeof(DateTime)) });
string csvData = File.ReadAllText(csvPath);
foreach (string row in csvData.Split('\n'))
{
if (!string.IsNullOrEmpty(row) )
{
dt.Rows.Add();
int i = 0;
foreach (string cell in row.Split(','))
{
dt.Rows[dt.Rows.Count - 1][i] = cell;
i++;
}
}
}
string consString = ConfigurationManager.ConnectionStrings["constr"].ConnectionString;
using (SqlConnection con = new SqlConnection(consString))
{
using (SqlBulkCopy sqlBulkCopy = new SqlBulkCopy(con))
{
//Set the database table name
sqlBulkCopy.DestinationTableName = "dbo.Inventory";
con.Open();
sqlBulkCopy.WriteToServer(dt);
con.Close();
}
}
}
}
Now the error I get is
Exception Details: System.FormatException: Input string was not in a correct format.
Source Error:
Line 46: foreach (string cell in row.Split(','))
Line 47: {
Line 48: dt.Rows[dt.Rows.Count - 1][i] = cell;
Line 49: i++;
Line 50:
I am also using sql server 2008
Can someone help me out?
Use File.ReadAllLines() instead for File.ReadAllText(csvPath). Which helps you to skip the Split operation as well as the First line; See the code below:
List<string> csvDataList = File.ReadAllLines(csvPath).Skip(1).ToList();
Now the csvDataList is a list of rows except the first row, you can iterate through those rows and do the same functions:
Iteration Example:
foreach (string Csv in csvDataList)
{
DataRow dRow = dt.NewRow();
int i = 0;
foreach (string cell in Csv.Split(','))
{
if (dRow[i].GetType() == typeof(int))
{
int cellValue = 0;
if (Int32.TryParse(cell, out cellValue))
{
dRow[i++] = cellValue;
}
}
else if (dRow[i].GetType() == typeof(char) && cell.Length == 1)
{
dRow[i++] = cell[0];
}
else // Which means that the cell is of type int
dRow[i++] = (int)Char.GetNumericValue(cell[0]);
}
dt.Rows.Add(dRow);
}

Don't Save csv first line as header

I'm using the following code to load my CSV file into a DataTable object. The problem is that the first line from the CSV file is loaded into the DataTable as the header row and not as a data row. How can I make all lines from the CSV file load as data rows and make datatable header row empty or any thing. This is my code
private DataTable ConvertCSVtoDataTable()
{
DataTable dataTable = new DataTable();
using (StreamReader sr = new StreamReader(csvfilename))
{
string[] headers = sr.ReadLine().Split(',');
foreach (string header in headers)
{
dataTable.Columns.Add(header);
}
while (!sr.EndOfStream)
{
string[] rows = sr.ReadLine().Split(',');
DataRow dr = dataTable.NewRow();
for (int i = 0; i < headers.Length; i++)
{
dr[i] = rows[i];
}
dataTable.Rows.Add(dr);
}
}
return dataTable;
}
The problem is that you use the first ReadLine statement to add the Header objects. You only use the second ReadLine to populate rows in the DataTable. Try this:
private DataTable ConvertCSVtoDataTable()
{
bool firstRow = true;
DataTable dataTable = new DataTable();
using (StreamReader sr = new StreamReader(csvfilename))
{
while (!sr.EndOfStream)
{
string[] values = sr.ReadLine().Split(',');
if (firstRow)
{
firstRow = false;
for (int i = 0;i < values.Length; i++)
{
dataTable.Columns.Add("Column" + i);
}
}
DataRow dr = dataTable.NewRow();
for (int i = 0; i < values.Length; i++)
{
dr[i] = values[i];
}
dataTable.Rows.Add(dr);
}
}
return dataTable;
}
EDITED:
Sorry about that I forgot to add the column headers... This should "workish". Unfortunately I dont have a C# debugger in front of me to get the syntax exact, but I believe you can figure out what I am trying to do.
You are explicitly reading the "Header". If I am understanding you correctly you simply need to remove the header management. This will leave you with columns with no header though or a null header.
private DataTable ConvertCSVtoDataTable()
{
DataTable dataTable = new DataTable();
using (StreamReader sr = new StreamReader(csvfilename))
{
while (!sr.EndOfStream)
{
string[] rows = sr.ReadLine().Split(',');
DataRow dr = dataTable.NewRow();
for (int i = 0; i < rows.Length; i++)
{
dr[i] = rows[i];
}
//IF the dataTable column count is less than the row column count add some columns.
if (dataTable.Columns.size() < dr.Columns.size()){
for(int i = 0; i < dr.Columns.size(); i++){
dataTable.Columns.add("");
}
}
dataTable.Rows.Add(dr);
}
}
return dataTable;
}

importing CSV file to database not working asp

I am trying to import an CSV file into the database using asp, this code is from http://www.aspsnippets.com/Articles/Import-Upload-CSV-file-data-to-SQL-Server-database-in-ASPNet-using-C-and-VBNet.aspx
try
{
//Upload and save the file
string csvPath = Server.MapPath("/upload/") + Path.GetFileName(FileUpload2.PostedFile.FileName);
FileUpload2.SaveAs(csvPath);
DataTable dt = new DataTable();
dt.Columns.AddRange(new DataColumn[3] { new DataColumn("Id", typeof(int)),
new DataColumn("Name", typeof(string)),
new DataColumn("Country",typeof(string)) }
);
string csvData = File.ReadAllText(csvPath);
foreach (string row in csvData.Split('\n'))
{
if (!string.IsNullOrEmpty(row))
{
dt.Rows.Add();
int i = 0;
foreach (string cell in row.Split(','))
{
dt.Rows[dt.Rows.Count - 1][i] = cell;
i++;
}
}
}
string consString = ConfigurationManager.ConnectionStrings["TOP2000_IAO4B_GROEP5ConnectionString"].ConnectionString;
using (SqlConnection con = new SqlConnection(consString))
{
using (SqlBulkCopy sqlBulkCopy = new SqlBulkCopy(con))
{
//Set the database table name
sqlBulkCopy.DestinationTableName = "[Customers]";
con.Open();
sqlBulkCopy.WriteToServer(dt);
con.Close();
}
}
}
catch(Exception ex)
{
Response.Write(ex);
}
However, when i go into debug mode and i look what the value of string csvData is, it's an empty string :/ I'm wondering what causes this, because obviously no data is inserted this way.
this is the CSV
1,John Hammond,United States
2,Mudassar Khan,India
3,Suzanne Mathews,France
4,Robert Schidner,Russia
the CSV is really simple to make it easy, can anyone help me with this?
Since you mentioned on debug you see CsvData, I suspect the problem lies on csvData.Split('\n') statement.
I just modified that particular logic, should work for you.
try
{
//Upload and save the file
string csvPath = Server.MapPath("/upload/") + Path.GetFileName(FileUpload2.PostedFile.FileName);
FileUpload2.SaveAs(csvPath);
DataTable dt = new DataTable();
dt.Columns.AddRange(new DataColumn[3] { new DataColumn("Id", typeof(int)),
new DataColumn("Name", typeof(string)),
new DataColumn("Country",typeof(string)) });
foreach (string row in File.ReadAllLines(csvPath))
{
if (!string.IsNullOrEmpty(row))
{
dt.Rows.Add();
int i = 0;
foreach (string cell in row.Split(','))
{
dt.Rows[dt.Rows.Count - 1][i] = cell;
i++;
}
}
}
string consString = ConfigurationManager.ConnectionStrings["TOP2000_IAO4B_GROEP5ConnectionString"].ConnectionString;
using (SqlConnection con = new SqlConnection(consString))
{
using (SqlBulkCopy sqlBulkCopy = new SqlBulkCopy(con))
{
//Set the database table name
sqlBulkCopy.DestinationTableName = "[Customers]";
con.Open();
sqlBulkCopy.WriteToServer(dt);
con.Close();
}
}
}
catch(Exception ex)
{
Response.Write(ex);
}
I guess your issue is with Splitting CSV data.
Try this code working code :
private string[] SplitString(string inputString)
{
System.Text.RegularExpressions.RegexOptions options = ((System.Text.RegularExpressions.RegexOptions.IgnorePatternWhitespace | System.Text.RegularExpressions.RegexOptions.Multiline)
| System.Text.RegularExpressions.RegexOptions.IgnoreCase);
Regex reg = new Regex("(?:^|,)(\\\"(?:[^\\\"]+|\\\"\\\")*\\\"|[^,]*)", options);
MatchCollection coll = reg.Matches(inputString);
string[] items = new string[coll.Count];
int i = 0;
foreach (Match m in coll)
{
items[i++] = m.Groups[0].Value.Trim('"').Trim(',').Trim('"').Trim();
}
return items;
}

How to insert a column with a specific value in sql bulk copy

I am populating a table with the values in excel using sql bulk copy in c#.
DataTable dt = new DataTable();
string line = null;
int i = 0;
using (StreamReader sr = File.OpenText(#"c:\temp\table1.csv"))
{
while ((line = sr.ReadLine()) != null)
{
string[] data = line.Split(',');
if (data.Length > 0)
{
if (i == 0)
{
foreach (var item in data)
{
dt.Columns.Add(new DataColumn());
}
i++;
}
DataRow row = dt.NewRow();
row.ItemArray = data;
dt.Rows.Add(row);
}
}
}
using (SqlConnection cn = new SqlConnection(ConfigurationManager.ConnectionStrings["ConsoleApplication3.Properties.Settings.daasConnectionString"].ConnectionString))
{
cn.Open();
using (SqlBulkCopy copy = new SqlBulkCopy(cn))
{
copy.ColumnMappings.Add(0, 0);
copy.ColumnMappings.Add(1, 1);
copy.ColumnMappings.Add(2, 2);
copy.ColumnMappings.Add(3, 3);
copy.ColumnMappings.Add(4, 4);
copy.DestinationTableName = "Censis";
copy.WriteToServer(dt);
}
}
In the above code, I am inserting the records from excel into the table. But, I have one more column "ProcessID" in the Censis table. For each time run, I need to generate a GUID and populate this column with this.
Can any one help me how to populate the ProcessID column when I do bulk copy as above with a generated GUID for all the rows for that run?
When you do your insert into the database use the function newsequentialid
Thanks JonH. But, I found an answer for my problem. I can use something like this. I can add a new DataColumn with a default value to the datatable which I use for bulk copy.
DataTable dt = new DataTable();
string line = null;
int i = 0;
using (StreamReader sr = File.OpenText(#"c:\temp\table1.csv"))
{
while ((line = sr.ReadLine()) != null)
{
string[] data = line.Split(',');
if (data.Length > 0)
{
if (i == 0)
{
foreach (var item in data)
{
dt.Columns.Add(new DataColumn());
}
i++;
}
DataRow row = dt.NewRow();
row.ItemArray = data;
dt.Rows.Add(row);
}
}
DataColumn col = new DataColumn("BatchId", typeof(System.Guid));
col.DefaultValue = Guid.NewGuid();
dt.Columns.Add(col);
}
using (SqlConnection cn = new SqlConnection(ConfigurationManager.ConnectionStrings["ConsoleApplication3.Properties.Settings.daasConnectionString"].ConnectionString))
{
cn.Open();
using (SqlBulkCopy copy = new SqlBulkCopy(cn))
{
copy.ColumnMappings.Add(0, 0);
copy.ColumnMappings.Add(1, 1);
copy.ColumnMappings.Add(2, 2);
copy.ColumnMappings.Add(3, 3);
copy.ColumnMappings.Add(4, 4);
copy.DestinationTableName = "Censis";
copy.WriteToServer(dt);
}
}

Categories