当结束列省略

时间:2016-08-12 07:47:17

标签: sql-server-2008 csv unicode bulkinsert

我拥有正确格式化的CSV - 它是用CRLF分隔的单字节制表符分隔的CSV,十六进制00 0D 00 0A - 请参阅Notepad ++图片:

enter image description here

当我在SQL Server 2008(10.0.2531.0)上从SSMS 2016运行SQL命令时:

    BULK
     INSERT #ZCSD84
     FROM 'x:\ZCSD84.csv'
     WITH
     (
     FIELDTERMINATOR = '\t',
     ROWTERMINATOR = '\n',
     FIRSTROW = 1,
     CODEPAGE = 1250,
     DATAFILETYPE='widechar'
     )

除了在CSV记录末尾有省略选项卡的行外,我得到了很好的结果。在那里我得到两行错误地合并成一行,如下所示。甚至来自下一行的第一列值也被添加到该行的最后一列值,从而创建例如, Jednorázový zákazník CB30

enter image description here

我试图指定其他各种rowterminator,例如0x0A,但是对于我来说,我总是The bulk load failed. The column is too long ...错误。

如果在受到CRLF攻击后立即强制创建新表行?或者其他一些解决方法,比如正确准备更多CSV?

1 个答案:

答案 0 :(得分:0)

我发现this answer表明可能没有解决此问题的简单方法。我决定在使用C#console app和CsvHelper批量插入之前修复CSV,这非常简单:

class Program
{
    public class ZCSD84
    {
        public string PrOrg { get; set; }
        public string Odberatel { get; set; }
        public string Dodavatel { get; set; }
        public string Jmeno1 { get; set; }
        public string Jmeno2 { get; set; }
        public string Ulice { get; set; }
        public string PSC { get; set; }
        public string Misto { get; set; }
        public string MistniCast { get; set; }
        public string DIC { get; set; }
        public string ICO { get; set; }
        public string StareCislo { get; set; }
        public string HeadOffice { get; set; }
        public string HeadOfficeName { get; set; }
        public string Payer { get; set; }
        public string PayerName { get; set; }
    }

    public sealed class ZCSD84Map : CsvClassMap<ZCSD84>
    {
        public ZCSD84Map()
        {
            Map(m => m.PrOrg).Index(0);
            Map(m => m.Odberatel).Index(1);
            Map(m => m.Dodavatel).Index(2);
            Map(m => m.Jmeno1).Index(3);
            Map(m => m.Jmeno2).Index(4);
            Map(m => m.Ulice).Index(5);
            Map(m => m.PSC).Index(7);
            Map(m => m.Misto).Index(8);
            Map(m => m.MistniCast).Index(9);
            Map(m => m.DIC).Index(10);
            Map(m => m.ICO).Index(11);
            Map(m => m.StareCislo).Index(12);
            Map(m => m.HeadOffice).Index(13);
            Map(m => m.HeadOfficeName).Index(14);
            Map(m => m.Payer).Index(15);
            Map(m => m.PayerName).Index(17);
        }
    }

    static void Main(string[] args)
    {
        string file1 = @"C:\JOBS\ZCSD84.csv";
        string file1Out = @"C:\JOBS\ZCSD84_out.csv";

        if (!File.Exists(file1))
            throw new FileNotFoundException(String.Format("Soubor csv nelze otevřít {0}.", file1));

        List<ZCSD84> ZCSD84s;
        CsvConfiguration config = new CsvConfiguration();
        config.Delimiter = "\t";
        config.IgnoreBlankLines = true;
        config.HasHeaderRecord = true;
        config.DetectColumnCountChanges = false;
        config.IgnoreReadingExceptions = false;
        config.SkipEmptyRecords = true;
        config.WillThrowOnMissingField = false;
        Encoding ce = System.Text.Encoding.GetEncoding(1250);
        config.Encoding = ce;
        config.QuoteNoFields = true;

        config.RegisterClassMap<ZCSD84Map>();
        Console.WriteLine(file1);
        using (CsvReader csvIn = new CsvReader(new StreamReader(file1), config))
        {
            ZCSD84s  = csvIn.GetRecords<ZCSD84>().ToList();
        }
        Console.WriteLine(file1Out);
        using (CsvWriter csvOut = new CsvWriter(new StreamWriter(file1Out, false, ce), config))
        {
            csvOut.WriteRecords(ZCSD84s);
        }
    }
}