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;
}
Related
I am trying to import an XML invoice to SQL database. After some research, I have managed to put it in SQL database but it has x rows whereas it should be a single row and x columns. Most of the sources I have read had examples of XML tables with multiple rows and XML files themselves were much simpler than this invoice file I am working with. I am aware the issue is probably related with columnMapping but could not figure how to fix it. Any help is appreciated.
Unfortunately I can't share the original invoice but I have found something similar: http://docs.oasis-open.org/ubl/os-UBL-2.2/xml/UBL-Invoice-2.1-Example.xml
private void buttonImport_Click(object sender, EventArgs e){
string XMlFile = textBoxBrowse.Text;
if (File.Exists(XMlFile))
{
DataTable dt = CreateDataTableXML(XMlFile);
if (dt.Columns.Count == 0)
dt.ReadXml(XMlFile);
string Query = CreateTableQuery(dt);
SqlConnection con = new SqlConnection(strcon);
con.Open();
cmd.ExecuteNonQuery();
// Table Creation
cmd = new SqlCommand(Query, con);
int check = cmd.ExecuteNonQuery();
if (check != 0)
{
// Copy Data from DataTable to Sql Table
using (var bulkCopy = new SqlBulkCopy(con.ConnectionString, SqlBulkCopyOptions.KeepIdentity))
{
foreach (DataColumn col in dt.Columns)
{
bulkCopy.ColumnMappings.Add(col.ColumnName, col.ColumnName); }
bulkCopy.BulkCopyTimeout = 600;
bulkCopy.DestinationTableName = dt.TableName;
bulkCopy.WriteToServer(dt);
}
MessageBox.Show("Table Created Successfully");
}
con.Close();
}
}
public DataTable CreateDataTableXML(string XmlFile) {
XmlDocument doc = new XmlDocument();
doc.Load(XmlFile);
DataTable Dt = new DataTable();
try
{
Dt.TableName = GetTableName(XmlFile);
XmlNode NodeStruct = doc.DocumentElement.ChildNodes.Cast<XmlNode>().ToList()[0];
foreach (XmlNode columna in NodeStruct.ChildNodes)
{
Dt.Columns.Add(columna.Name, typeof(String));
}
XmlNode Files = doc.DocumentElement;
foreach (XmlNode File in Files.ChildNodes)
{
List<string> Values = File.ChildNodes.Cast<XmlNode>().ToList().Select(x => x.InnerText).ToList();
Dt.Rows.Add(Values.ToArray());
}
}
catch (Exception ex)
{
}
return Dt;
}
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 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);
}
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);
}
}