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