当我使用C#将csv文件放入Sql Server时,某些字段写入错误?
您好,我在将csv文件导入sql server时遇到问题,此csv文件包含需要保存在sql server数据库中的文章。导入(使用下面编写的代码c#完成)完成后,作为导入的某些字段(descripione和CodArt)在数据库中写入不正确,并且具有奇怪的字符。下载csv文件 SqlServer在蓝线上的导入不正确: 导入C#代码:当我使用C#将csv文件放入Sql Server时,某些字段写入错误?,c#,sql-server,csv,C#,Sql Server,Csv,您好,我在将csv文件导入sql server时遇到问题,此csv文件包含需要保存在sql server数据库中的文章。导入(使用下面编写的代码c#完成)完成后,作为导入的某些字段(descripione和CodArt)在数据库中写入不正确,并且具有奇怪的字符。下载csv文件 SqlServer在蓝线上的导入不正确: 导入C#代码: using (var rd = new StreamReader(labelPercorso.Text)) { Articolo a = new Arti
using (var rd = new StreamReader(labelPercorso.Text))
{
Articolo a = new Articolo();
a.db = this.db;
while (!rd.EndOfStream)
{
//setto codean e immagine =null ad ogni giro
CodEAN = "";
Immagine = "";
try
{
var splits = rd.ReadLine().Split(';');
CodArt = splits[0];
Descrizione = splits[1];
String Price = splits[2];
Prezzo = decimal.Parse(Price);
}
catch (Exception ex)
{
Console.WriteLine("Non è presente nè immagine nè codean");
}
a.Prezzo = Prezzo;
a.CodiceArticolo = CodArt;
a.Descrizione = Descrizione;
a.Fornitore = fornitore;
//manca da controllare se l'articolo è presente e nel caso aggiornalo
a.InserisciArticoloCSV();
}
}
功能代码:InserisciArticoloCSV
try
{
SqlConnection conn = db.apriconnessione();
String query = "INSERT INTO Articolo(CodArt,Descrizione,Prezzo,PrezzoListino,Fornitore,Importato,TipoArticolo) VALUES(@CodArt,@Descrizione,@Prezzo,@PrezzoListino,@Fornitore,@Importato,@TipoArticolo)";
String Importato = "CSV";
String TipoArticolo = "A";
SqlCommand cmd = new SqlCommand(query, conn);
// MessageBox.Show("CodArt: " + CodiceArticolo + "\n Descrizione :" + Descrizione + "\n Prezzo: " + Prezzo);
cmd.Parameters.AddWithValue("@CodArt", CodiceArticolo.ToString());
cmd.Parameters.AddWithValue("@Descrizione", Descrizione.ToString());
cmd.Parameters.AddWithValue("@Prezzo", Prezzo);
cmd.Parameters.AddWithValue("@PrezzoListino", Prezzo);
cmd.Parameters.AddWithValue("@Fornitore", Fornitore.ToString());
cmd.Parameters.AddWithValue("@Importato", Importato.ToString());
cmd.Parameters.AddWithValue("@TipoArticolo", TipoArticolo.ToString());
cmd.ExecuteNonQuery();
db.chiudiconnessione();
conn.Close();
return true;
}
catch (Exception ex)
{
Console.WriteLine("Errore nell'inserimento dell'articolo " + ex);
//MessageBox.Show("Errore nel inserimento dell'articolo: " + ex);
return false;
}
您的CSV文件格式不好,中间有中间的回车符,这会破坏解析。在Notepad++中查看该文件并打开换行符,这就是您所发现的
因此,对于格式为的行,数据导入工作正常,而对于其他行,逻辑不工作。您的CSV文件格式不正确,中间有中间回车,这会导致解析出错。在Notepad++中查看该文件并打开换行符,这就是您所发现的
因此,对于格式为的行,数据导入工作正常,对于其他行,逻辑不工作。读取文件时,应指定正确的编码。是utf吗?它是带有特定代码页的ascii码吗?您还应该指定Sql参数的SqlDbType,特别是字符串参数,它们将是varchar或nvarchar,它们之间有很大的区别
// what is the encoding of your file? This is an example using code page windows-1252
var encoding = Encoding.GetEncoding("windows-1252");
using (var file = File.Open(labelPercorso.Text, FileMode.Open))
using (var reader = new StreamReader(file, encoding))
{
// rest of code unchanged
}
Sql代码。注意,我为实现IDisposable
的类型添加了,比如连接和命令
try
{
String query = "INSERT INTO Articolo(CodArt,Descrizione,Prezzo,PrezzoListino,Fornitore,Importato,TipoArticolo) VALUES(@CodArt,@Descrizione,@Prezzo,@PrezzoListino,@Fornitore,@Importato,@TipoArticolo)";
String Importato = "CSV";
String TipoArticolo = "A";
using(SqlConnection conn = db.apriconnessione())
using(SqlCommand cmd = new SqlCommand(query, conn))
{
// -1 indicates you used MAX like nvarchar(max), otherwise use the maximum number of characters in the schema
cmd.Parameters.Add(new SqlDbParameter("@CodArt", SqlDbType.NVarChar, -1)).Value = CodiceArticolo.ToString();
cmd.Parameters.Add(new SqlDbParameter("@Descrizione", SqlDbType.NVarChar, -1)).Value = Descrizione.ToString();
/*
Rest of your parameters created in the same manner
*/
cmd.ExecuteNonQuery();
db.chiudiconnessione();
}
return true;
}
catch (Exception ex)
{
Console.WriteLine("Errore nell'inserimento dell'articolo " + ex);
//MessageBox.Show("Errore nel inserimento dell'articolo: " + ex);
return false;
}
读取文件时,应指定正确的编码。是utf吗?它是带有特定代码页的ascii码吗?您还应该指定Sql参数的SqlDbType,特别是字符串参数,它们将是varchar或nvarchar,它们之间有很大的区别
// what is the encoding of your file? This is an example using code page windows-1252
var encoding = Encoding.GetEncoding("windows-1252");
using (var file = File.Open(labelPercorso.Text, FileMode.Open))
using (var reader = new StreamReader(file, encoding))
{
// rest of code unchanged
}
Sql代码。注意,我为实现IDisposable
的类型添加了,比如连接和命令
try
{
String query = "INSERT INTO Articolo(CodArt,Descrizione,Prezzo,PrezzoListino,Fornitore,Importato,TipoArticolo) VALUES(@CodArt,@Descrizione,@Prezzo,@PrezzoListino,@Fornitore,@Importato,@TipoArticolo)";
String Importato = "CSV";
String TipoArticolo = "A";
using(SqlConnection conn = db.apriconnessione())
using(SqlCommand cmd = new SqlCommand(query, conn))
{
// -1 indicates you used MAX like nvarchar(max), otherwise use the maximum number of characters in the schema
cmd.Parameters.Add(new SqlDbParameter("@CodArt", SqlDbType.NVarChar, -1)).Value = CodiceArticolo.ToString();
cmd.Parameters.Add(new SqlDbParameter("@Descrizione", SqlDbType.NVarChar, -1)).Value = Descrizione.ToString();
/*
Rest of your parameters created in the same manner
*/
cmd.ExecuteNonQuery();
db.chiudiconnessione();
}
return true;
}
catch (Exception ex)
{
Console.WriteLine("Errore nell'inserimento dell'articolo " + ex);
//MessageBox.Show("Errore nel inserimento dell'articolo: " + ex);
return false;
}
正如其他人指出的,您有许多问题,编码、回车和大量空白。此外,在数据库中使用单个插入,速度非常慢。我在下面展示了一些示例代码,它演示了如何处理所有这些问题
IFormatProvider fP = new CultureInfo("it");
DataTable tmp = new DataTable();
tmp.Columns.Add("CodArt", typeof(string));
tmp.Columns.Add("Descrizione", typeof(string));
tmp.Columns.Add("Prezzo", typeof(decimal));
using (var rd = new StreamReader("yourFileName", Encoding.GetEncoding("iso-8859-1")))
{
while (!rd.EndOfStream)
{
try
{
var nextLine = Regex.Replace(rd.ReadLine(), @"\s+", " ");
while (nextLine.Split(';').Length < 3)
{
nextLine = nextLine.Replace("\r\n", "") + Regex.Replace(rd.ReadLine(), @"\s+", " ");
}
var splits = nextLine.Split(';');
DataRow dR = tmp.NewRow();
dR[0] = splits[0];
dR[1] = splits[1];
string Price = splits[2];
dR[2] = decimal.Parse(Price, fP);
tmp.Rows.Add(dR);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
}
using (var conn = db.apriconnessione())
{
var sBC = new SqlBulkCopy(conn);
conn.Open();
sBC.DestinationTableName = "yourTableName";
sBC.WriteToServer(tmp);
conn.Close();
}
ifformatprovider fP=新文化信息(“it”);
DataTable tmp=新DataTable();
tmp.Columns.Add(“CodArt”,typeof(string));
tmp.Columns.Add(“descripione”,typeof(string));
tmp.Columns.Add(“Prezzo”,typeof(decimal));
使用(var rd=newstreamreader(“yourFileName”,Encoding.GetEncoding(“iso-8859-1”))
{
而(!rd.EndOfStream)
{
尝试
{
var nextLine=Regex.Replace(rd.ReadLine(),@“\s+”,”);
while(nextLine.Split(“;”)。长度<3)
{
nextLine=nextLine.Replace(“\r\n”,”)+Regex.Replace(rd.ReadLine(),@“\s+”,”);
}
var splits=nextLine.Split(“;”);
DataRow dR=tmp.NewRow();
dR[0]=拆分[0];
dR[1]=拆分[1];
字符串价格=拆分[2];
dR[2]=decimal.Parse(价格,fP);
tmp.Rows.Add(dR);
}
捕获(例外情况除外)
{
控制台写入线(例如消息);
}
}
}
使用(var conn=db.apriconnessione())
{
var sBC=新的SqlBulkCopy(conn);
conn.Open();
sBC.DestinationTableName=“yourTableName”;
sBC.WriteToServer(tmp);
康涅狄格州关闭();
}
现在需要一些解释:
首先,我将解析后的值存储在数据表中。请注意,我只包含CSV中的三个字段。实际上,您必须提供其他列,并用每行的正确值填充额外的列。我只是懒惰,但我相信你会明白的
我不知道您的csv文件是什么编码,但是iso-8859-1
对我来说很有用
我使用正则表达式将多个空格替换为单个空格
如果任何行没有所需的拆分数,我会继续添加更多行(删除回车符),直到我点击成功
一旦我有了一个完整的行,我现在可以拆分它,并将它分配给新的DataRow(请参阅我上面的注释以获得额外的列)
最后,一旦文件被读取,DataTable将拥有所有的行,并且可以使用BulkCopy上传到数据库。这太快了
嗯
PS你的一些行有双引号。你可能也想把这些也扔掉 正如其他人指出的,您有许多问题,编码、回车和大量空白。此外,在数据库中使用单个插入,速度非常慢。我在下面展示了一些示例代码,它演示了如何处理所有这些问题
IFormatProvider fP = new CultureInfo("it");
DataTable tmp = new DataTable();
tmp.Columns.Add("CodArt", typeof(string));
tmp.Columns.Add("Descrizione", typeof(string));
tmp.Columns.Add("Prezzo", typeof(decimal));
using (var rd = new StreamReader("yourFileName", Encoding.GetEncoding("iso-8859-1")))
{
while (!rd.EndOfStream)
{
try
{
var nextLine = Regex.Replace(rd.ReadLine(), @"\s+", " ");
while (nextLine.Split(';').Length < 3)
{
nextLine = nextLine.Replace("\r\n", "") + Regex.Replace(rd.ReadLine(), @"\s+", " ");
}
var splits = nextLine.Split(';');
DataRow dR = tmp.NewRow();
dR[0] = splits[0];
dR[1] = splits[1];
string Price = splits[2];
dR[2] = decimal.Parse(Price, fP);
tmp.Rows.Add(dR);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
}
using (var conn = db.apriconnessione())
{
var sBC = new SqlBulkCopy(conn);
conn.Open();
sBC.DestinationTableName = "yourTableName";
sBC.WriteToServer(tmp);
conn.Close();
}
ifformatprovider fP=新文化信息(“it”);
DataTable tmp=新DataTable();
tmp.Columns.Add(“CodArt”,typeof(string));
tmp.Columns.Add(“descripione”,typeof(string));
tmp.Columns.Add(“Prezzo”,typeof(decimal));
使用(var rd=newstreamreader(“yourFileName”,Encoding.GetEncoding(“iso-8859-1”))
{
而(!rd.EndOfStream)
{
尝试
{
var nextLine=Regex.Replace(rd.ReadLine(),@“\s+”,”);
while(nextLine.Split(“;”)。长度<3)
{
nextLine=nextLine.Replace(“\r\n”,”)+Regex.Replace(rd.ReadLine(),@“\s+”,”);
}
var splits=nextLine.Split(“;”);
DataRow dR=tmp.NewRow();
dR[0]=拆分[0];
dR[1]=拆分[1];
字符串价格=拆分[2];
dR[2]=decimal.Parse(价格,fP);
tmp.Rows.Add(dR);
}
捕获(例外情况除外)
{
控制台写入线(例如消息);
}
}
}
使用(var conn=db.apri