【问题标题】:Return multiple values (OUTPUT) stored procedure to dataset or datatable?将多个值(OUTPUT)存储过程返回到数据集或数据表?
【发布时间】:2017-12-02 14:40:12
【问题描述】:

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

我使用SqlDataAdapterFill 方法很好地捕获了从存储过程返回的结果集,这已解决,但我需要的是数据集或数据表中的输出值,因为这些值将包含一组输出数据。

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

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

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

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

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

【问题讨论】:

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


    【解决方案1】:

    您应该在完成 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);
    

    【讨论】:

    • 谢谢 请再次查看我的问题,编辑它以便您更好地理解,谢谢。
    • 谢谢,不要使用 DataReader,使用 DataAdapter 存储过程只返回 2 个表,我已经选择了填充。输出值不会重复(它也是一个结果表),但 DATATASET 只包含两个结果表,输出值不包含在该数据集中,我想要的是将输出值包含在同一个数据集中另一张桌子。如果数据集已经有输出数据,您向我提出的解决方案是直接的。输出数据不包含在此数据集中。一旦我知道如何处理它们,我想包括它们。
    • 请看我上传的图片:IMAGE Result of store Procedure Example i.stack.imgur.com/vumsG.png
    • 谢谢,我尝试了您提出的第二种解决方案,它对我有用。感谢您的回复朋友。
    【解决方案2】:

    我认为您应该像这样提供一个由您的数据适配器填充的数据集:

    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 个数据表检索,然后创建另一个数据集并将您的最后一个数据表复制到其中,或者直接复制它......

    【讨论】:

    • 谢谢 请再次查看我的问题,编辑它以便您更好地理解,谢谢。
    • 请看我上传的图片:IMAGE Result of store Procedure Example i.stack.imgur.com/vumsG.png
    • 好的,谢谢您提供信息。这里有一个简单的方法:一次性检索所有 3 个数据表: dataadapter.Fill(dataset, "Table1, Table2","Table3");然后创建另一个数据集以通过以下方式复制其中的 table3:AnotherDataset.Tables.Add(dataset.Tables["Table3"].Copy());
    • Dypso,我试过这种方式,但它不起作用,出现以下异常:找不到表3。
    猜你喜欢
    • 2020-03-27
    • 1970-01-01
    • 2017-02-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-19
    • 1970-01-01
    相关资源
    最近更新 更多