如何在 C# 中获取从 SQL 服务器存储过程返回的结果

How to get the result returned back from a SQL Server stored procedure in C#

我构建了一个从 Excel sheet 获取数据的组件,将其复制到 SQL 服务器 table。我还有一个存储过程,可以对该数据执行验证,如果 v=data 未通过验证,returns 会显示一条消息。

我设法将数据导入 SQL 服务器,获取记录列表并在存储过程中执行它们,全部使用 C#。现在我面临的挑战或困惑实际上是获取程序验证的每条记录的结果,以便我可以排除未通过验证的记录。我如何在 C# 中执行此操作?

这里我导入记录

public static void ImportDataFromExcel(string excelFilePath)
{
    var sqlTable = "[MSCRM_Intergration].[dbo].[CRMSupplierClaimsUpload]";

    try
    {
        var excelConnectionString = @"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + excelFilePath + ";EXTENDED PROPERTIES=" + ";Extended Properties=Excel 12.0;";

        var sqlConnectionString = "data source=WM-PMARAKA-NB;initial catalog=MSCRM_Intergration;integrated security=True;";

        //this code removes any data in the SQL Server table before importing/ optional step, need to check with Steve and Kyle
        var sqlDeleteQuery = "DELETE FROM [dbo].[CRMSupplierClaimsUpload]";

        SqlConnection conn = new SqlConnection(sqlConnectionString);
        SqlCommand comm = new SqlCommand(sqlDeleteQuery, conn);

        conn.Open();
        comm.ExecuteNonQuery();
        conn.Close();

        //commands to bulk upload data to SQL Server table
        OleDbConnection oleDBConnection = new OleDbConnection(excelConnectionString);
        OleDbCommand oldeDBCommand = new OleDbCommand("SELECT * From [Claims$]", oleDBConnection);

        oleDBConnection.Open();
        OleDbDataReader oleDBDataReader = oldeDBCommand.ExecuteReader();

        SqlBulkCopy sqlBulkCopy = new SqlBulkCopy(sqlConnectionString);
        sqlBulkCopy.DestinationTableName = sqlTable;

        while (oleDBDataReader.Read())
        {
            sqlBulkCopy.ColumnMappings.Add(new SqlBulkCopyColumnMapping("Action", "Action"));
            sqlBulkCopy.ColumnMappings.Add(new SqlBulkCopyColumnMapping("Line No", "Line No."));
            sqlBulkCopy.ColumnMappings.Add(new SqlBulkCopyColumnMapping("Total Claim", "Total Claim"));
            sqlBulkCopy.ColumnMappings.Add(new SqlBulkCopyColumnMapping("Currency", "Currency"));
            sqlBulkCopy.ColumnMappings.Add(new SqlBulkCopyColumnMapping("Claim Reference", "Claim Reference"));
            //sqlBulkCopy.ColumnMappings.Add(new SqlBulkCopyColumnMapping(5, 6));
            //sqlBulkCopy.ColumnMappings.Add(new SqlBulkCopyColumnMapping(6, 7));
            sqlBulkCopy.WriteToServer(oleDBDataReader);
        }

        oleDBConnection.Close();
    }
    catch (Exception ex)
    {
        //throw new ArgumentException(ex.Message);
    }
}

这里我从 table

中获取列表
public static IList<CRMSupplierClaimsData> GetClaimsUpdateRecordsFromStaging()
{
    using (MSCRM_IntergrationEntities1 db = new MSCRM_IntergrationEntities1())
    {
        var query = from claims in db.CRMSupplierClaimsUploads
                    select new CRMSupplierClaimsData()
                         {
                            Action = claims.Action,
                            LineNunber = claims.Line_No_,
                            TotalClaim = (Decimal)(claims.Total_Claim),
                            Currency = claims.Currency,
                            ClaimReference = claims.Claim_Reference
                         };

        return query.ToList();
    }
}

这里我尝试运行程序,这就是我的问题所在,我如何从程序中获取响应然后排除记录,因为验证记录需要导出到Excel 再次。

public static IList<CRMSupplierClaimsData> ExcecuteClaimsValidationProc()
{
    using (EmbraceEntities context = new EmbraceEntities())
    {
        IList<CRMSupplierClaimsData> claimsData = GetClaimsUpdateRecordsFromStaging();

        foreach (var claim in claimsData)
        {
            context.Supplier_Claim_Upload(claim.LineNunber, claim.TotalClaim);
        }

        return claimsData;
    }
}

这是 运行 过程的示例及其显示的结果,运行 来自 SQL 服务器本身

USE [Embrace]
GO

DECLARE @return_value int

EXEC    @return_value = [CRM].[Supplier_Claim_Upload]
        @Invoice = N'TA40151295*01-1',
        @Amount = 3404.2

SELECT  'Return Value' = @return_value
GO

这是验证返回的错误

TA40151295*01-1 Warning: You Are going to Overwrite a Claim Value: 3404.000

该程序是由外部人员编写的,我需要 运行 使用来自 Excel sheet 的数据进行验证。有什么想法可以实现吗?

基本上我需要在 C# 中做一些逻辑,说明如果发票号码通过并且金额导致警告 "You Are going to Overwrite a Claim Value: 3404.000" 我想排除这条记录。

如果存储过程 returns 是一个结果集,那么在 ImportDataFromExcel() 方法中调用 ExecuteReader() 并在代码中读取数据集而不是 ExecuteNonQuery() 就像您在 "SELECT * From [Claims$]" 中所做的那样在代码中进一步命令。

所以我得到了问题的最终解决方案,存储过程根据您传递给它的内容返回动态结果,因此我需要逻辑来满足不同的响应。这是最终对我有用的代码

public static Supplier_Claim_Upload_Result ExcludeFailedValidationRecords()
    {
        IList<CRMSupplierClaimsData> claimsData = GetClaimsUpdateRecordsFromStaging();
        Supplier_Claim_Upload_Result supplierClaimUplaod = new Supplier_Claim_Upload_Result();
        //Supplier_Claim_Uplaod_Result_Error supplierClaimUploadError = new Supplier_Claim_Uplaod_Result_Error();
        var sqlConnection = "data source=WMVSQL02;initial catalog=Embrace;integrated security=True;";
        using (SqlConnection conn = new SqlConnection(sqlConnection))
        {
            try
            {
                foreach (var claim in claimsData)
                {
                    SqlCommand cmd = new SqlCommand();
                    cmd.CommandTimeout = 60;
                    SqlDataReader reader;

                    cmd.CommandText = "CRM.Supplier_Claim_Upload";
                    cmd.CommandType = CommandType.StoredProcedure;
                    cmd.Parameters.Add("@Invoice", SqlDbType.NVarChar).Value = claim.LineNunber;
                    cmd.Parameters.Add("@Amount", SqlDbType.Decimal).Value = claim.TotalClaim;
                    cmd.Connection = conn;

                    conn.Open();
                    reader = cmd.ExecuteReader();

                    while (reader.Read())
                    {
                        supplierClaimUplaod.ST_Key = reader["ST_Key"].ToString();
                        if (supplierClaimUplaod.SupplierClaim != null)
                        {
                            supplierClaimUplaod.SupplierClaim = reader["Supplier_Claim"].ToString();
                        }
                        else if (supplierClaimUplaod.SupplierClaim == null)
                        {
                            if (supplierClaimUplaod.Error != null)
                            {
                                supplierClaimUplaod.Error = reader["Error"].ToString();
                            }
                            else if (supplierClaimUplaod.Error == null)
                            {
                                supplierClaimUplaod.SupplierClaim = "No value";
                            }
                        }
                        if (supplierClaimUplaod.OrigInv != null)
                        {
                            supplierClaimUplaod.OrigInv = reader["Orig_Inv"].ToString();
                        }
                        else if (supplierClaimUplaod.OrigInv == null)
                        {
                            if (supplierClaimUplaod.Error != null)
                            {
                                supplierClaimUplaod.Error = reader["Error"].ToString();
                            }
                            else if (supplierClaimUplaod.Error == null)
                            {
                                supplierClaimUplaod.OrigInv = reader["Orig_Inv"].ToString();
                            }
                        }
                        if (supplierClaimUplaod.SystemCost != null)
                        {
                            supplierClaimUplaod.SystemCost = reader["System_Cost"].ToString();
                        }
                        else if (supplierClaimUplaod.SystemCost == null)
                        {
                            if (supplierClaimUplaod.Error != null)
                            {
                                supplierClaimUplaod.Error = reader["Error"].ToString();
                            }
                            else if (supplierClaimUplaod.Error == null)
                            {
                                supplierClaimUplaod.SystemCost = reader["System_Cost"].ToString();
                            }
                        }
                    }
                    conn.Close();
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                Console.WriteLine(ex.InnerException);
            }
            return supplierClaimUplaod;
        }
    }