【问题标题】:Writing multiple queries to single csv将多个查询写入单个 csv
【发布时间】:2016-02-01 17:44:55
【问题描述】:

我需要将多个查询写入单个 CSV 文件。例如,我将生成一个包含员工计划的报告,然后在同一个 CSV 中我想查看员工个人信息,例如工资、办公地点等。我可以从一个存储过程返回两个查询,认为它会写一个接下来是下一个,但显然这是不正确的,因为只返回了第一个结果。

我的 SQL 查询如下:

SELECT EmployeeSchedule.TaskTime, Employees.EmployeeName, EmployeeSchedule.M, EmployeeSchedule.Tu, EmployeeSchedule.W,
        EmployeeSchedule.Th, EmployeeSchedule.F, EmployeeSchedule.Sa, EmployeeSchedule.Su
FROM EmployeeSchedule
    INNER JOIN Employees on EmployeeSchedule.EmployeeID = Employees.EmployeeID
WHERE (
    EmployeeSchedule.EmployeeID = @EmployeeID AND
    EmployeeSchedule.TaskTime >= @ShiftStart AND 
    EmployeeSchedule.TaskTime <= @ShiftEnd AND
    (
        (EmployeeSchedule.M=1) AND (EmployeeSchedule.M = @M) OR 
        (EmployeeSchedule.Tu=1) AND (EmployeeSchedule.Tu = @Tu) OR 
        (EmployeeSchedule.W=1) AND (EmployeeSchedule.W = @W) OR 
        (EmployeeSchedule.Th=1) AND (EmployeeSchedule.Th = @Th) OR 
        (EmployeeSchedule.F=1) AND (EmployeeSchedule.F = @F) OR 
        (EmployeeSchedule.Sa=1) AND (EmployeeSchedule.Sa = @Sa) OR 
        (EmployeeSchedule.Su=1) AND (EmployeeSchedule.Su = @Su)
    )
)
ORDER BY EmployeeName, TaskTime


SELECT Employees.EmployeeName, Salary, City, AdditionalDetails
FROM EmployeeDetails
    INNER JOIN Employees on EmployeeDetails.EmployeeID = Employees.EmployeeID
WHERE Employees.EmployeeID=@EmployeeID

我的相关部分代码如下:

public void GenerateEmployeeLog()
{
string employee = Convert.ToString(EmployeesDropDown.SelectedItem.Text);

    string sqlConn = ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString;
    using (SqlConnection sqlConnection1 = new SqlConnection(sqlConn))
    {
        try
        {
            sqlConnection1.Open();
            using (SqlCommand cmd = new SqlCommand())
            {
                cmd.CommandText = ("usp_" + proc);
                cmd.CommandType = CommandType.StoredProcedure;
                cmd.Connection = sqlConnection1;
                cmd.Parameters.AddWithValue("EmployeeID", Convert.ToString(EmployeeDropDown.SelectedItem.Value));
                cmd.Parameters.AddWithValue("ShiftStart", StartTextBox.Text);
                cmd.Parameters.AddWithValue("ShiftEnd", EndTextBox.Text);
                cmd.Parameters.AddWithValue("M", MCheckBox.Checked);
                cmd.Parameters.AddWithValue("Tu", TuCheckBox.Checked);
                cmd.Parameters.AddWithValue("W", WCheckBox.Checked);
                cmd.Parameters.AddWithValue("Th", ThCheckBox.Checked);
                cmd.Parameters.AddWithValue("F", FCheckBox.Checked);
                cmd.Parameters.AddWithValue("Sa", SaCheckBox.Checked);
                cmd.Parameters.AddWithValue("Su", SuCheckBox.Checked);

                using (SqlDataReader reader = cmd.ExecuteReader())
                {
                    try
                    {
                        using (DataTable dt = new DataTable())
                        {
                            dt.Load(reader);

                            using (StreamWriter writer = new StreamWriter(Response.OutputStream))
                            {
                                DataConvert.ToCSV(dt, writer, false);
                                Response.AddHeader("content-disposition", @"attachment;filename=""" + "EmployeeLog - " + employee + @".csv""");
                                Response.Charset = "";
                                Response.ContentType = "application/text";
                                Response.End();
                            }
                        }
                    }
                    catch (Exception)
                    {
                        throw;
                    }

                    finally
                    {
                        reader.Close();
                        reader.Dispose();
                    }
                }
            }
        }

        catch (Exception ex)
        {
            throw ex;
        }

        finally
        {
            sqlConnection1.Close();
            sqlConnection1.Dispose();
        }
    }
}

非常感谢任何关于如何完成我正在寻找的建议。

解决方案: 我最终将这两个查询拆分为不同的存储过程,并根据下面接受的答案的建议对我的代码进行了最终修改。

public void GenerateEmployeeLog()
{
string employee = Convert.ToString(EmployeesDropDown.SelectedItem.Text);

    string sqlConn = ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString;
    using (SqlConnection sqlConnection1 = new SqlConnection(sqlConn))
    {
        try
        {
            sqlConnection1.Open();

            using (SqlCommand cmd1 = new SqlCommand())
            {
                cmd1.CommandText = ("usp_" + proc + "_EmployeeDetails");
                cmd1.CommandType = CommandType.StoredProcedure;
                cmd1.Connection = sqlConnection1;
                cmd1.Parameters.AddWithValue("EmployeeID", Convert.ToString(AffiliatesDropDown.SelectedItem.Value));

                using (SqlDataReader reader = cmd1.ExecuteReader())
                {
                    try
                    {
                        using (dt1 = new DataTable())
                        {
                            dt1.Load(reader);
                        }
                    }
                    catch (Exception)
                    {
                        throw;
                    }

                    finally
                    {
                        reader.Close();
                        reader.Dispose();
                    }
                }
            }

            using (SqlCommand cmd2 = new SqlCommand())
            {
                cmd2.CommandText = ("usp_" + proc);
                cmd2.CommandType = CommandType.StoredProcedure;
                cmd2.Connection = sqlConnection1;
                cmd2.Parameters.AddWithValue("EmployeeID", Convert.ToString(EmployeeDropDown.SelectedItem.Value));
                cmd2.Parameters.AddWithValue("ShiftStart", StartTextBox.Text);
                cmd2.Parameters.AddWithValue("ShiftEnd", EndTextBox.Text);
                cmd2.Parameters.AddWithValue("M", MCheckBox.Checked);
                cmd2.Parameters.AddWithValue("Tu", TuCheckBox.Checked);
                cmd2.Parameters.AddWithValue("W", WCheckBox.Checked);
                cmd2.Parameters.AddWithValue("Th", ThCheckBox.Checked);
                cmd2.Parameters.AddWithValue("F", FCheckBox.Checked);
                cmd2.Parameters.AddWithValue("Sa", SaCheckBox.Checked);
                cmd2.Parameters.AddWithValue("Su", SuCheckBox.Checked);

                using (SqlDataReader reader = cmd2.ExecuteReader())
                {
                    try
                    {
                        using (DataTable dt2 = new DataTable())
                        {
                            dt2.Load(reader);

                            using (StreamWriter writer = new StreamWriter(Response.OutputStream))
                            {
                                DataConvert.ToCSV(dt2, writer, false);
                                writer.WriteLine();
                                DataConvert.ToCSV(dt1, writer, false);

                                Response.AddHeader("content-disposition", @"attachment;filename=""" + "EmployeeLog - " + employee + @".csv""");
                                Response.Charset = "";
                                Response.ContentType = "application/text";
                                Response.End();
                            }
                        }
                    }
                    catch (Exception)
                    {
                        throw;
                    }

                    finally
                    {
                        reader.Close();
                        reader.Dispose();
                    }
                }
            }
        }

        catch (Exception ex)
        {
            throw ex;
        }

        finally
        {
            sqlConnection1.Close();
            sqlConnection1.Dispose();
        }
    }
}

【问题讨论】:

    标签: c# csv stored-procedures sql-server-2008-r2


    【解决方案1】:

    我非常喜欢 Mike U 的第二种方法,但如果你绝对必须有一个 csv 文件输出,它并不漂亮,但你不能这样做吗?:

    using (SqlDataReader reader = cmd.ExecuteReader()){
        using (SqlDataReader reader1 = cmd1.ExecuteReader()){
            using (DataTable dt = new DataTable()){
                using (DataTable dt1 = new DataTable()){
                    dt.Load(reader);
                    dt1.Load(reader1);
                    using (StreamWriter writer = new StreamWriter(Response.OutputStream)){
                         DataConvert.ToCSV(dt, writer, false);
                         DataConvert.ToCSV(dt1, writer, false);
                         ...
        }}}}}
    

    【讨论】:

      【解决方案2】:

      Response 的内容来看,您是在网页上执行此操作的。您将遇到的问题是您只能为单个请求返回单个响应。由于您只是将DataConvert.ToCSV() 输出作为响应流发送,这意味着每个文件都有不同的流。

      如果您不打算在 HTML 中实际显示这些文件,那么您需要创建一个 ZIP 文件来存储这两个不同的文件。

      可在此处找到创建多文件 ZIP 文件的示例:https://msdn.microsoft.com/en-us/library/system.io.compression.zipfile(v=vs.110).aspx

      编辑:第二种选择是将javascript发送到Page_Load事件中,该事件将调用一个实际运行两个单独查询的HTTPHandler。这将弹出两个附加选项卡,每个选项卡都有一个 CSV 文件。您必须将所有这些代码移动到自定义 HTTPHandler 中,其中查询字符串字符串参数“t”可以确定运行两个查询中的哪一个。

      protected void btn_OnClick(object sender, EventArgs e)
      {
          string sysPgLoad = "Sys.Application.add_load(function () {{ {0}; }});";
          this.Page.ClientScript.RegisterStartupScript(this.Page.GetType(), "employeeLog", string.Format(sysPgLoad, "window.Open('exployeeCsv.axd?t=log')"));
          this.Page.ClientScript.RegisterStartupScript(this.Page.GetType(), "employeeSal", string.Format(sysPgLoad, "window.Open('exployeeCsv.axd?t=sal')"));
      }
      

      【讨论】:

      • 你是对的,我没有在 HTML 中显示这个,但是,在这种情况下,多个文件不是一个选项,包括将它们压缩在一起。该报告将由经理非常频繁地生成,并且必须在单个文档中。我愿意接受任何其他允许我创建单个 csv 文件的建议。
      • 您希望在一个文件中包含两个不同的数据集?我认为 CSV 不能在这里做你想做的事,除非你愿意简单地将第二个数据集“附加”到响应流中。您可以总是在调用Response.End() 之前运行第二个查询并将DataConvert.ToCSV() 的输出写入Response.Stream,但这样文件将有点难以阅读。您遇到的是网络工作方式的限制,而不是缺乏编码知识。
      • 我已经用第二个选项更新了我的答案,虽然有点复杂。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-02-11
      • 2016-01-30
      • 1970-01-01
      • 2018-04-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多