将多个值(OUTPUT)存储过程返回到数据集或数据表?

时间:2017-12-02 14:40:13

标签: c# sql-server database stored-procedures output

这是我的问题:我正在使用一个返回多个结果的存储过程,但我需要知道的是,如何传递(检索)"输出"存储过程对数据集或数据的值?

从存储过程返回的结果集我使用SqlDataAdapter和方法Fill很好地捕获它们,但是我需要的是数据集中的输出值或datatable,因为这些值将包含一组输出数据。

我已经研究过,但是我找不到任何东西来获取数据集或数据中的输出。

关于多个结果存在许多问题但是已经解决了我不需要那个部分因为我已经解决了,只是那些输出可以传递给数据集或数据表。

请原谅我的英语语法,因为我正在使用翻译,谢谢。

在存储过程返回数据集后附加要嵌入数据集的值。

C#2010和SQL Server 2014

谢谢你,但是你还没有理解我的问题,我会留下我的代码让你明白。

正如你所看到的,我有一切正常,存储过程,返回2个表和另外一组输出数据,我用SqlDataAdapterFill方法得到的两个结果表,并且输出值是单独分配的,但我不希望它是单独的,我需要数据集或数据表中的所有输出值,就像其他结果一样

// Function
private void procedure(decimal id, string date)
{
    bool done = false;

    SqlTransaction Transaction = null;

    int value_return = 0;

    try
    {
        // Function
        open_conexion();

        // Transaction
        Transaccion = conexion.BeginTransaction(System.Data.IsolationLevel.Serializable);

        SqlCommand command = new SqlCommand("NameStoreProcedure", conexion, Transaction);
        command.CommandType = CommandType.StoredProcedure;

        command.Parameters.Clear();

        // Multiple resulsets
        command.Parameters.AddWithValue("@id", id);
        command.Parameters.AddWithValue("@date", date);

        // Output values
        command.Parameters.Add("@Value1", SqlDbType.VarChar, 2).Direction = ParameterDirection.Output;
        command.Parameters.Add("@Value2", SqlDbType.DateTime).Direction = ParameterDirection.Output;
        command.Parameters.Add("@Value3", SqlDbType.DateTime).Direction = ParameterDirection.Output;
        command.Parameters.Add("@Value4", SqlDbType.DateTime).Direction = ParameterDirection.Output;
        command.Parameters.Add("@Value5", SqlDbType.Char, 1).Direction = ParameterDirection.Output;
        command.Parameters.Add("@Value6", SqlDbType.Decimal).Direction = ParameterDirection.Output;
        command.Parameters.Add("@Value7", SqlDbType.Decimal).Direction = ParameterDirection.Output;
        command.Parameters.Add("@Value8", SqlDbType.Char, 1).Direction = ParameterDirection.Output;
        command.Parameters.Add("@Value9", SqlDbType.VarChar, 30).Direction = ParameterDirection.Output;

        // Return Value
        command.Parameters.Add("@return_value", SqlDbType.Int).Direction = ParameterDirection.ReturnValue; 

        DataSet dataset = new DataSet();

        string output_values = string.Empty;

        SqlDataAdapter dataadapter = new SqlDataAdapter(command);

        // 2nd Resulset
        dataadapter.Fill(dataset, "Table1, Table2");

        // These values, instead of having them in a string variable, I need them in a //dataset or datatable
        // Values Output
        output_values = "Value1: " + Convert.ToString(command.Parameters["@Value1"].Value) + " \n" +
                        "Value2: " + Convert.ToString(command.Parameters["@Value2"].Value) + " \n" +
                        "Value3: " + Convert.ToString(command.Parameters["@Value3"].Value) + " \n" +
                        "Value4: " + Convert.ToString(command.Parameters["@Value4"].Value) + " \n" +
                        "Value5: " + Convert.ToString(command.Parameters["@Value5"].Value) + " \n" +
                        "Value6: " + Convert.ToString(command.Parameters["@Value6"].Value) + " \n" +
                        "Value7: " + Convert.ToString(command.Parameters["@Value7"].Value) + " \n" +
                        "Value8: " + Convert.ToString(command.Parameters["@Value8"].Value) + " \n" +
                        "Value9: " + Convert.ToString(command.Parameters["@Value9"].Value);

        value_return = Convert.ToInt32(command.Parameters["@return_value"].Value);

        if (value_return == 0)
        {
            done = true;
        }
    }
    catch (SqlException exception)
    {
        MessageBox.Show("ERROR" + exception.Message, "ERROR ", MessageBoxButtons.OK, MessageBoxIcon.Error);
    }
    finally
    {
        if (done)
        {
            Transaction.Commit();
            close_conexion();
        }
        else
        {
            Transaction.Rollback();
            close_conexion();
        }
    }
}

IMAGE result of stored procedure example

2 个答案:

答案 0 :(得分:1)

您应该在Finisted SQL DataReader流之后检索输出参数。这意味着在读取DataReader中的所有行之前,您无法获取输出参数。所以,如果你想将输出值设置为所有行(我不推荐它,它会导致冗余数据),你可以这样做;

        foreach (DataTable datasetTable in dataset.Tables)
        {
            datasetTable.Columns.Add("Value1", typeof(string));
            datasetTable.Columns.Add("Value2", typeof(string));
            datasetTable.Columns.Add("Value3", typeof(string));
            datasetTable.Columns.Add("Value4", typeof(string));
            foreach (DataRow datasetTableRow in datasetTable.Rows)
            {
                datasetTableRow["Value1"] = command.Parameters["@Value1"].Value;
                datasetTableRow["Value2"] = command.Parameters["@Value2"].Value;
                datasetTableRow["Value3"] = command.Parameters["@Value3"].Value;
                datasetTableRow["Value4"] = command.Parameters["@Value4"].Value;
            }
        }

或者你可以为这样的输出值创建另一个表;

    dataset.Tables.Add("OutputResults");
    dataset.Tables["OutputResults"].Columns.Add("Value1", typeof(string));
    dataset.Tables["OutputResults"].Columns.Add("Value2", typeof(string));
    dataset.Tables["OutputResults"].Columns.Add("Value3", typeof(string));
    dataset.Tables["OutputResults"].Columns.Add("Value4", typeof(string));
    var outputRow = dataset.Tables["OutputResults"].NewRow();
    outputRow["Value1"] = command.Parameters["@Value1"].Value;
    outputRow["Value2"] = command.Parameters["@Value2"].Value;
    outputRow["Value3"] = command.Parameters["@Value3"].Value;
    outputRow["Value4"] = command.Parameters["@Value4"].Value;
    dataset.Tables["OutputResults"].Rows.Add(outputRow);

另一个选项是你可以像这样在创建的表中为每个输出值添加行作为键值对;

    dataset.Tables.Add("OutputResults");
    dataset.Tables["OutputResults"].Columns.Add("OutputName", typeof(string));
    dataset.Tables["OutputResults"].Columns.Add("OutputValue", typeof(string));

    var value1Row = dataset.Tables["OutputResults"].NewRow();
    value1Row["OutputName"] = "Value1";
    value1Row["OutputValue"] = command.Parameters["@Value1"].Value;

    var value2Row = dataset.Tables["OutputResults"].NewRow();
    value2Row["OutputName"] = "Value2";
    value2Row["OutputValue"] = command.Parameters["@Value2"].Value;

    var value3Row = dataset.Tables["OutputResults"].NewRow();
    value3Row["OutputName"] = "Value3";
    value3Row["OutputValue"] = command.Parameters["@Value3"].Value;

    var value4Row = dataset.Tables["OutputResults"].NewRow();
    value4Row["OutputName"] = "Value4";
    value4Row["OutputValue"] = command.Parameters["@Value4"].Value;

    dataset.Tables["OutputResults"].Rows.Add(value1Row);
    dataset.Tables["OutputResults"].Rows.Add(value2Row);
    dataset.Tables["OutputResults"].Rows.Add(value3Row);
    dataset.Tables["OutputResults"].Rows.Add(value4Row);

答案 1 :(得分:0)

我认为你应该提供一个由dataadapter填充的数据集,如下所示:

DataTable myTable= new DataTable();


using (var con = new SqlConnection(AConnectionString))
using (SqlCommand cmd = new SqlCommand("STORED_PROCEDURE", con)) 
using (var da = new SqlDataAdapter(cmd))
{
    cmd.CommandType = System.Data.CommandType.StoredProcedure;
    //Data adapter(da) fills the data retuned from stored procedure 
   //into myTable
    da.Fill(myTable);
}

这将返回您正在追踪的数据表....

但是使用你的附加编辑代码,我想你想要同时返回不同的结果集。如果是这样,您可以考虑使用MARS (Multiple active Result Set)

我已更新了我的回复:您可以将所有结果集检索为现有数据集中的3个dataTable,然后创建另一个数据集并将其复制到最后一个dataTable,或者只是将其复制...