【问题标题】:Import CSV File Error : Column Value containing column delimiter导入 CSV 文件错误:包含列分隔符的列值
【发布时间】:2017-03-17 16:05:09
【问题描述】:

我正在尝试使用 SSIS 将 Csv 文件导入 SQL SERVER

这是一个数据看起来如何的示例

Student_Name,Student_DOB,Student_ID,Student_Notes,Student_Gender,Student_Mother_Name
Joseph Jade,2005-01-01,1,Good listener,Male,Amy
Amy Jade,2006-01-01,1,Good in science,Female,Amy
....

Csv 列不包含文本限定符(引号)

我使用 SSIS 创建了一个简单的包以将其导入 SQL,但有时 SQL 中的数据如下所示

Student_Name    Student_DOB Student_ID  Student_Notes   Student_Gender  Student_Mother_Name
Ali Jade    2004-01-01  1   Good listener   Bad in science  Male,Lisa

原因是 somtimes [Student_Notes] 列包含用作列分隔符的逗号 (,),因此未正确导入 Row

任何建议

【问题讨论】:

  • 更改列分隔符,列数据中包含列分隔符是不好的做法
  • 怎么做...我不是创建这些 csv 文件的人
  • 也许你可以用某种编程语言创建一个程序,这样你就可以逐行读取这些文件并根据需要处理数据
  • 你能自动确定哪个是有问题的逗号吗?如果是这样,您可以编写一个脚本来清理它。解决这个问题的一种方法似乎是计算每行逗号的数量,如果有太多,从右边开始删除它们。您可以手动将此算法应用于您的数据并查看它是否正确。如果是这样,我可以帮助您编写一个预先清理它的脚本。
  • 我会给你一些代码,但有一点建议:永远不要说“code plz”,这有点烦人。

标签: sql sql-server csv ssis delimiter


【解决方案1】:

如果导入 CSV 文件不是例程

  1. 在 Excel 中导入 CSV 文件
  2. 使用 Excel 行过滤器搜索错误行并重写它们
  3. 以 TXT 制表符分隔保存 Excel 文件
  4. 使用 SSIS 导入 TXT 文件 否则,制作一个在学生笔记列范围内搜索逗号的脚本

【讨论】:

  • 请解释一下第二步。处理数百行时!
  • 排序最后一列 desc 以识别错误的行。然后,您可以仅在错误的行上使用 Excel 进行一些数据清理(附加单元格等)。显然,这种解决方法只有在学生笔记单元格中有一个逗号时才有效。另一种解决方案是在 Web 应用程序文本字段中禁止逗号
【解决方案2】:

一个警告:我不是一个普通的 C# 编码器。

但无论如何,这段代码执行以下操作:

它会打开一个名为 C:\Input.TXT 的文件

它搜索每一行。如果该行的逗号超过 5 个,则将所有多余的逗号从倒数第三个字段(注释)中取出

它将结果写入 C:\Output.TXT - 这是您实际需要导入的那个

还有很多可以改进的地方:

  • 从连接管理器获取文件路径
  • 错误处理
  • 有经验的 C# 程序员可能会在 hlaf 代码中做到这一点

请记住,您的包需要对相应文件夹的写入权限

public void Main()
{
    // Search the file and remove extra commas from the third last field
    // Extended from code at
    // http://stackoverflow.com/questions/1915632/open-a-file-and-replace-strings-in-c-sharp
    // Nick McDermaid        

    string sInputLine;
    string sOutputLine;
    string sDelimiter = ",";
    String[] sData;
    int iIndex;

    // open the file for read
    using (System.IO.FileStream inputStream = File.OpenRead("C:\\Input.txt"))
    {
        using (StreamReader inputReader = new StreamReader(inputStream))
        {
            // open the output file
            using (StreamWriter outputWriter = File.AppendText("C:\\Output.txt"))
            {
                // Read each line
                while (null != (sInputLine = inputReader.ReadLine()))
                {
                    // Grab each field out
                    sData = sInputLine.Split(sDelimiter[0]);
                    if (sData.Length <= 6)
                    {
                        // 6 or less fields - just echo it out
                        sOutputLine = sInputLine;
                    }
                    else
                    {
                        // line has more than 6 pieces 
                        // We assume all of the extra commas are in the notes field                                

                        // Put the first three fields together
                        sOutputLine =
                            sData[0] + sDelimiter +
                            sData[1] + sDelimiter +
                            sData[2] + sDelimiter;

                        // Put the middle notes fields together, excluding the delimiter
                        for (iIndex=3; iIndex <= sData.Length - 3; iIndex++)
                        {
                            sOutputLine = sOutputLine + sData[iIndex] + " ";
                        }

                        // Tack on the last two fields
                        sOutputLine = sOutputLine +
                            sDelimiter + sData[sData.Length - 2] +
                            sDelimiter + sData[sData.Length - 1];


                    }

                    // We've evaulted the correct line now write it out
                    outputWriter.WriteLine(sOutputLine);
                }
            }
        }
    }


    Dts.TaskResult = (int)Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Success;
}

【讨论】:

  • 感谢您的帮助
【解决方案3】:

在平面文件连接管理器中。将文件设为一列 (DT_STR 8000)

只需在数据流任务中添加一个脚本组件并添加输出列(与所示示例相同)

在脚本组件中使用以下代码分割每一行:

\\Student_Name,Student_DOB,Student_ID,Student_Notes,Student_Gender,Student_Mother_Name

Dim strCells() as string = Row.Column0.Split(CChar(","))

Row.StudentName = strCells(0)
Row.StudentDOB = strCells(1)
Row.StudentID = strCells(2)
Row.StudentMother = strCells(strCells.Length - 1)
Row.StudentGender = strCells(strCells.Length - 2)

Dim strNotes as String = String.Empty

For int I = 3 To strCells.Length - 3

strNotes &= strCells(I)

Next

Row.StudentNotes = strNotes

对我来说效果很好

【讨论】:

    猜你喜欢
    • 2011-08-18
    • 2018-03-13
    • 1970-01-01
    • 2015-11-01
    • 2015-11-02
    • 1970-01-01
    • 2020-03-10
    • 2021-01-17
    • 2014-11-20
    相关资源
    最近更新 更多