将多个查询写入单个csv

时间:2016-02-01 17:44:55

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

我需要将多个查询写入单个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();
        }
    }
}

2 个答案:

答案 0 :(得分:0)

根据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')"));
}

答案 1 :(得分:0)

我非常喜欢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);
                     ...
    }}}}}