存储过程 returns 多个临时 table 结果。我想使用 C# 将它们复制到一个 CSV 文件中

Stored procedure returns multiple temp table results. I want to copy them into one CSV file using C#

我有一个存储过程,其中包含多个使用临时表的 select 语句。我想将结果复制到一个 CSV 文件中。每个结果都有不同的列。我想以这样的方式复制它们,即每个结果集应该在 CSV 文件中留下两行 space。

示例如下:

示例存储过程

Create procedure usp_Test_CSV_Report
As
Begin
    select 'Text Sample' as Description, 123 Amount, 20210511 as Joindate
    select GETDATE() as MonthATB
    select 1 as AccountId, 'CI' as Name
    select 'Sample Report'
End

临时表已在存储过程中创建,将像 Select * from #temp 一样调用。我没有包含大量的真实存储过程。

我会运行使用C#的存储过程

string query = "EXEC alpha.dbo.usp_Test_CSV_Report";

SqlCommand cmd = new SqlCommand(query, SQLConnection);

SQLConnection.Open();

DataTable d_table = new DataTable();
SqlDataReader sqlReader = cmd.ExecuteReader();
                while (sqlReader.Read())
                {
                    d_table.Load(sqlReader);
                    // Write the Header Row to File
                    int ColumnCount = d_table.Columns.Count;
                    for (int ic = 0; ic < ColumnCount; ic++)
                    {
                        //MessageBox.Show(d_table.Columns[ic].ToString());
                        sw.Write(d_table.Columns[ic]);
                        if (ic < ColumnCount - 1)
                        {
                            sw.Write(FileDelimiter);
                        }
                    }
                    sw.Write(sw.NewLine);

                    // Write All Rows to the File
                    foreach (DataRow dr in d_table.Rows)
                    {
                        for (int ir = 0; ir < ColumnCount; ir++)
                        {
                            if (!Convert.IsDBNull(dr[ir]))
                            {
                                sw.Write(dr[ir].ToString());
                                //MessageBox.Show(dr[ir].ToString());
                            }
                            if (ir < ColumnCount - 1)
                            {
                                sw.Write(FileDelimiter);
                            }
                        }
                        sw.Write(sw.NewLine);

                    }

                  
            }

            sqlReader.NextResult();

            while (sqlReader.Read())
            {
                d_table.Load(sqlReader);
                // Write the Header Row to File
                int ColumnCount = d_table.Columns.Count;
                for (int ic = 0; ic < ColumnCount; ic++)
                {
                    //MessageBox.Show(d_table.Columns[ic].ToString());
                    sw.Write(d_table.Columns[ic]);
                    if (ic < ColumnCount - 1)
                    {
                        sw.Write(FileDelimiter);
                    }
                }
                sw.Write(sw.NewLine);

                // Write All Rows to the File
                foreach (DataRow dr in d_table.Rows)
                {
                    for (int ir = 0; ir < ColumnCount; ir++)
                    {
                        if (!Convert.IsDBNull(dr[ir]))
                        {
                            sw.Write(dr[ir].ToString());
                            //MessageBox.Show(dr[ir].ToString());
                        }
                        if (ir < ColumnCount - 1)
                        {
                            sw.Write(FileDelimiter);
                        }
                    }
                    sw.Write(sw.NewLine);

                }

               
            }

                SQLConnection.Close();
            sw.Close();

到目前为止我已经试过了,但是没有用!! 有帮助吗?

我维护一个 nuget 包,Sylvan.Data.Csv,这使得这很容易。

    string query = "EXEC alpha.dbo.usp_Test_CSV_Report";

    using SqlConnection conn = GetSqlConnection();
    conn.Open();
    using SqlCommand cmd = new SqlCommand(query, conn);
    using var sw = File.CreateText("usp_Test_CSV_Report.csv");
    using var csvWriter = CsvDataWriter.Create(sw);
    using var sqlReader = cmd.ExecuteReader();

    bool first = true;
    do
    {
        if (!first)
        {
            // write the two lines to separate the result sets.
            sw.WriteLine();
            sw.WriteLine();
        }
        first = false;
        csvWriter.Write(sqlReader);
    } while (sqlReader.NextResult());

该库还支持以几乎相同的方式从单个 CSV 中读取多个结果集:

    // tell the reader to expect multiple result sets.
    var csvOpts = new CsvDataReaderOptions { ResultSetMode = ResultSetMode.MultiResult };
    var csvReader = CsvDataReader.Create("usp_Test_CSV_Report.csv", csvOpts);
    do
    {
        while (csvReader.Read())
        {
            for(int i = 0; i < csvReader.FieldCount; i++)
            {
                var value = csvReader.GetString(i);
            }
        }
    } while (csvReader.NextResult());