【问题标题】:SQL query to flatfile csv with column header, separator column ";" and text qualifier double-quote对带有列标题、分隔列“;”的平面文件 csv 的 SQL 查询和文本限定符双引号
【发布时间】:2019-12-02 10:43:33
【问题描述】:

我想在 SSIS 的 ExecuteProcessTask 中将 SQL 查询导出到 csv 平面文件。

我看不到带有标题、分隔符并将其限定为文本的导出。 我尝试使用 sqlcmd 和 bcp。

关于信息,我必须使用 SELECT *,因为 FROM 中的视图是一个变量,我必须显示所有列。

使用 sqlcmd :

sqlcmd -S  ServerName -d dbName -E -Q "SELECT * FROM vPBI_Tasks WHERE [project Leader] like 'ProjectLeaderName'" -o "exportFile.csv" -W -s";"

提取结果:

Scope;Project type;Activity type;OBS;Customer;Contr...
-----;------------;-------------;---;--------;-----...
ESP;ESP - Amendment;NULL;NULL;GSA;ESP_Amendment#13;...
ESP;ESP - Amendment;NULL;NULL;GSA;ESP_Amendment#13;...
ESP;ESP - Amendment;NULL;NULL;GSA;ESP_Amendment#13;...

我想要:

"Scope";"Project type";"Activity type";"OBS";"Customer";"Contra..."
ESP";"ESP - Amendment";"NULL";"NULL";"GSA";"ESP_Amendment#13";""
ESP";"ESP - Amendment";"NULL";"NULL";"GSA";"ESP_Amendment#13";""
ESP";"ESP - Amendment";"NULL";"NULL";"GSA";"ESP_Amendment#13";""

使用 bcp :

bcp "SELECT * FROM vPBI_Resources WHERE [project Leader] like 'ProjectLeaderName'" queryout "exportFile.csv" -c -t ; -S ServerName -T

结果:

  • 我没有标题
  • 我没有文本限定符

【问题讨论】:

  • “我看不到带有标题、分隔符并将其限定为文本的导出” 你在哪里看?它们是平面文件数据源中选项herehere 中的明确选项。
  • 在 bcp 或 sqlcmd 中。我不使用经典的平面文件数据目标,我使用执行流程任务编辑器,因为我无法通过平面文件连接。
  • SQL 查询是正则表达式:"SELECT * FROM" + @[User::SQLView] + "WHERE" + @[User::WhereClause]
  • “因为我无法通过平面文件连接。” 为什么不呢?这将使您在这里追求的东西变得微不足道。
  • 我遇到的问题是,如果我创建一个平面文件连接,我必须定义导出列的名称和数量,但这取决于@User::SQLView。我跌倒了,也许吧?

标签: sql sql-server ssis sqlcmd bcp


【解决方案1】:

我确实想过这个解决方案,但是我对在行首和行尾添加双引号的问题感到困惑。

我找到的解决方法是 C# 中的脚本。 http://neil037.blogspot.com/2013/07/ssis-script-task-to-export-data-from.html

我把C#代码放在下面,供其他人使用:)。

public void Main()
    {

        String filePath = Dts.Variables["User::temporyExportFilePath"].Value.ToString();
        Dts.TaskResult = (int)ScriptResults.Success;
        CreateCSVFile(GetTableData(), filePath);

    }

    public DataTable GetTableData()
    {

        String sqlQuery = Dts.Variables["User::sqlQuery"].Value.ToString();
        String connectionString = Dts.Variables["User::stringDatabaseConnection"].Value.ToString();
        SqlConnection connect = new SqlConnection(connectionString);

        SqlCommand cmd = new SqlCommand(sqlQuery, connect);
        cmd.CommandType = CommandType.Text;
        SqlDataAdapter adap = new SqlDataAdapter(cmd);
        DataTable dt = new DataTable();
        adap.Fill(dt);
        return dt;
    }


    public void CreateCSVFile(DataTable dt, string strFilePath)
    {
        StreamWriter sw = new StreamWriter(strFilePath, false);
        int iColCount = dt.Columns.Count;
        for (int i = 0; i < iColCount; i++)
        {
            // Write text qualifier double-quote + value + double-quote
            sw.Write("\"" + dt.Columns[i] + "\"");
            if (i < iColCount - 1)
            {
                //Parser
                sw.Write(";");
            }
        }
        sw.Write(sw.NewLine);
        // Now write all the rows.
        foreach (DataRow dr in dt.Rows)
        {
            for (int i = 0; i < iColCount; i++)
            {
                if (!Convert.IsDBNull(dr[i]))
                {
                    // Write text qualifier double-quote + value + double-quote
                    sw.Write("\"" + dr[i].ToString() + "\"");
                }
                if (i < iColCount - 1)
                {
                    //Parser
                    sw.Write(";");
                }
            }
            sw.Write(sw.NewLine);
        }
        //Close file and all data writing
        sw.Close();
    }

【讨论】:

    【解决方案2】:

    请参阅对较早的类似请求的此答案:

    SQL Server BCP Bulk insert Pipe delimited with text qualifier format file

    本质上,您需要使用 BCP 格式的文件。构建 BCP 命令时,包括 -f 选项并指定格式文件的位置。在格式文件中,您不仅可以将分隔符指定为分号,还可以指定为“;” (这是两个 dbl-quote 字符,中间有一个分号)。

    除此之外还有更多内容,但其余部分由链接提供。

    要包含标题,您只需要本质上使用 2 个查询。一个查询将用于标题,另一个查询将用于详细记录。您可以使用 BCP 的“queryout”选项将两个查询“联合”在一起。您必须将所有详细数据转换为 varchar 数据类型,以便可以将它们一起查询到单个文件中。但是,既然您已经开始使用文本文件,这应该不会造成问题。还有其他答案详细说明了如何以这种方式包含标题。我会尽快添加一个作为编辑。您还可以将标题和详细记录作为两个单独的文件(2 个单独的 bcp 命令)查询出来,然后将它们与 OS/脚本命令合并在一起。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-06-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-04-22
      • 2020-08-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多