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);
}
Related
This is the button which I press in order the csv-s to be imported:
private void btnOpen_Click_1(object sender, EventArgs e)
{
using (var fbd = new FolderBrowserDialog())
{
DialogResult result = fbd.ShowDialog();
if (result == DialogResult.OK && !string.IsNullOrWhiteSpace(fbd.SelectedPath))
{
// string[] files = Directory.GetFiles(fbd.SelectedPath);
string[] csvFiles = Directory.GetFiles(#"D:\CSV", "*.csv");
foreach (string filePath1 in csvFiles)
{
BindData(filePath1);
}
}
}
}
This is the method that is called for each csv. The problem is that it makes the datagridview each time the last csv is imported. I want a way that adds all the records not only my last imported csv:
private void BindData(string filePath)
{
DataTable dt = new DataTable();
using (TextFieldParser parser = new TextFieldParser(filePath))
{
// configure your parser to your needs
parser.TextFieldType = FieldType.Delimited;
parser.Delimiters = new string[] { ";" };
parser.HasFieldsEnclosedInQuotes = false; // no messy code if your data comes with quotes: ...;"text value";"another";...
// read the first line with your headers
string[] fields = parser.ReadFields();
// add the desired headers with the desired data type
dt.Columns.Add(fields[0], typeof(string));
dt.Columns.Add(fields[1], typeof(string));
dt.Columns.Add(fields[6], typeof(float));
dt.Columns.Add(fields[7], typeof(float));
dt.Columns.Add(fields[8], typeof(string));
dt.Columns.Add(fields[9], typeof(string));
// read the rest of the lines from your file
while (!parser.EndOfData)
{
// all fields from one line
string[] line = parser.ReadFields();
// create a new row
DataRow row = dt.NewRow();
// put data values; cast if needed - this example uses string type columns
row[0] = line[0];
row[1] = line[1];
row[2] = line[6];
row[3] = line[7];
row[4] = line[8];
row[5] = line[9];
// add the newly created and filled row
dt.Rows.Add(row);
}
}
this.dataGridView1.DataSource = dt;
// asign to DGV
}
Change this line
DataTable dt = new DataTable();
So it says:
DataTable dt = (this.dataGridView1.DataSource as DataTable) ?? new DataTable();
So that you either reuse your existing data source or make a new one if it is not set
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;
}
So, I have a table called Curr. My primary key is CurrID (auto-increment) and I have Foreign Key CouID. My csv file looks like this:
|1|12345|
|2|23456|
Everytime I add values to my csv file, I will upload it in the database. Ex:
|1|12345|
|2|23456|
|3|12345|
|4|93821|
Now the problem is that I don't want it to be added because it's already in the database. The database should look like this:
|1|12345|
|2|23456|
|4|93821|
Please help me. Here's my code.
string csvPath = Server.MapPath("~/Files/") + Path.GetFileName(Curr_Upload.PostedFile.FileName);
Curr_Upload.SaveAs(csvPath);
DataTable dt = new DataTable();
dt.Columns.AddRange(new DataColumn[2] {new DataColumn("CurrID", typeof(int))
new DataColumn("CouID", typeof(int)) });
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(','))
{
lbl_status.Text = row;
dt.Rows[dt.Rows.Count - 1][i] = cell;
i++;
}
}
}
using (connection = new SqlConnection(constring))
{
using (SqlBulkCopy sqlBulkCopy = new SqlBulkCopy(constring))
{
sqlBulkCopy.DestinationTableName = "dbo.Curr";
connection.Open();
sqlBulkCopy.WriteToServer(dt);
connection.Close();
}
}
}
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;
}
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);
}
}