【问题标题】:SQL Server BCP Export where comma in SQL fieldSQL Server BCP 导出 SQL 字段中的逗号
【发布时间】:2018-09-04 16:17:09
【问题描述】:

我已成功将文件导出为 CSV。我使用以下代码导出文件:

exec xp_cmdshell 'bcp "[DC_TrainEnvironment].[dbo].[HAFacilities_Master]" out "\\fspincdc01\data$\HIMSSAnalytics\Data Analyst\HG Data\Technical Documentation\HA Facilities\HAFacilities_Master.csv" -f "\\fspincdc01\data$\HIMSSAnalytics\Data Analyst\HG Data\Technical Documentation\HA Facilities\HAFacilities_Master_FORMAT.fmt" -o "\\fspincdc01\data$\HIMSSAnalytics\Data Analyst\HG Data\Technical Documentation\HA Facilities\HAFacilities_Master_LOG.txt" -T -S "HAPDBCDC02,2112"'

这很好用,但是有一个问题。某些字段中包含逗号。我正在使用这个格式文件:

我可以在格式文件中做些什么来避免更改整个格式文件?有没有一种快速的方法来指示字段终止符在这些特定字段中不会以逗号结尾? IE。 “','“ 或者 ”'',''”?

感谢任何帮助。谢谢

【问题讨论】:

  • 有一个打印屏幕按钮。它在 Scroll Lock 和 Pause/Break 键旁边。那张照片不太可读。不过,您确实应该提供text 之类的信息。
  • 它是否将其导出为 RFC 4180 标准?文本应该有双引号,特别是如果文本包含逗号。不遵守这一点可能会使导入程序完全陷入困境,您很容易不知道哪个是文本中的逗号,哪个是逗号分隔符。有些人建议使用逗号以外的分隔符,这与该字符永远不会出现在任何文本中一样好(例如管道符号)en.wikipedia.org/wiki/Comma-separated_values#RFC_4180_standard
  • SQL Server 从 2017 版开始仅支持 CSV 导入。您使用的是哪一种?
  • 这似乎是一个很好的过去答案stackoverflow.com/questions/21097978/…
  • @Larnu 上传了一张更好的图片。

标签: sql-server bcp


【解决方案1】:

如果您要导出的字段可以包含您用来分隔文件中字段的字符,您的选择是:

  1. 使用不同的分隔符 - 这似乎是最简单的方法。只需使用“|”或“~”作为分隔符。将“,”全局替换为“|”使用几乎任何文本编辑器在格式文件中。目前尚不清楚为什么很难修改“整个”文件。也许您的文件收件人需要逗号分隔?

  2. 如果必须使用逗号作为分隔符,则必须将列分隔符从逗号 (,) 更改为 quote-comma-quote (",")。为此,您需要使用转义字符让 BCP 程序忽略要在输出文件中用作分隔符的引号,因此它不会将它们视为它理解的引号,以包含格式文件中的分隔符.所以……

而不是 ","... 使用... "\",\""

这将导致以下结果

col1,col2,"col,3",col4

col1 的分隔符是:,在格式文件中使用:","

对于 col2,分隔符是:, 以在格式文件中表示它:“,\””

对于 col3,分隔符是:",在格式文件中使用:"\","

对于 col4,分隔符是:,在格式文件中使用:","

希望对你有帮助。

【讨论】:

  • 如何在 SSIS 中通过 Bulk Insert Task 实现这一点?
【解决方案2】:

困难重重。您需要在 bcp 命令中选择列并替换逗号。

exec xp_cmdshell 'bcp "SELECT ''ColumnHeader'' UNION ALL SELECT REPLACE(Column1, '','', '''') FROM [DC_TrainEnvironment].[dbo].[HAFacilities_Master]" out "\\fspincdc01\data$\HIMSSAnalytics\Data Analyst\HG Data\Technical Documentation\HA Facilities\HAFacilities_Master.csv" -f "\\fspincdc01\data$\HIMSSAnalytics\Data Analyst\HG Data\Technical Documentation\HA Facilities\HAFacilities_Master_FORMAT.fmt" -o "\\fspincdc01\data$\HIMSSAnalytics\Data Analyst\HG Data\Technical Documentation\HA Facilities\HAFacilities_Master_LOG.txt" -T -S "HAPDBCDC02,2112"'

【讨论】:

  • 说真的 - 他们没有想到这一点吗?我遇到过一些人没有一遍又一遍地考虑这个事实,但你会认为 BCP 实用程序会允许这样做。我认为这是一个本质上类似于人们决定他们自己的基于字符串的日期格式必须比 SQL 日期格式更好的问题。
【解决方案3】:

这是我的 C# 解决方案,您必须变形才能在 SQL Server 中使用,但仍然是一个模板:

private static void EliminateCommasInFields(List<string> files, string path)
{
    foreach (var f in files)
    {
        string filename = path + f.Substring(0, f.Length - 4);

        StreamReader sr = new StreamReader(filename);
        String[] rows = Regex.Split(sr.ReadToEnd(), "\r\n");
        sr.Close();
        StreamWriter sw = new StreamWriter(filename);

        for (int i = 0; i < rows.Length; i++)
        {
            //search the row for the dreaded ," (indicating a comma in the field)
            while (rows[i].IndexOf(",\"") > 0) 
                {
                    //find the position of the first ," and it's ending ",
                    int start = rows[i].IndexOf(",\""); 
                    int end = rows[i].IndexOf("\",");
                    //find the position of the first comma within this field
                    int comma = rows[i].IndexOf(",", start + 1, end - start);
                    while (comma > 0) //eliminate all the commas within this cell
                    {
                        //Replace the offending comma with a space 
                        rows[i] = rows[i].Substring(0, comma) + " " + rows[i].Substring(comma + 1, rows[i].Length - (comma + 1)); 
                        //Search for next comma
                        comma = rows[i].IndexOf(",", start + 1, end - start);
                    }
                    //Save the rest of the row eliminating the double quotes for this cell
                    rows[i] = rows[i].Substring(0, end ) + rows[i].Substring(end + 1, rows[i].Length - (end + 1));
                    rows[i] = rows[i].Substring(0, start + 1) + rows[i].Substring(start+ 2, rows[i].Length - (start + 2));

                }

            sw.WriteLine(rows[i]);
        }
        sw.Close();
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-11-05
    • 2015-02-02
    • 2017-11-30
    • 2020-04-19
    • 2017-07-22
    相关资源
    最近更新 更多