2017-08-24 30 views
1

我正在处理用于验证用户以Excel文件的形式上载的数据的Web表单。代码遍历电子表格中的每一行,并根据各种规则进行检查,其中之一是引用必须是唯一值。我有一个存储过程,是以userIDreferenceNum作为参数:提供不一致返回值的存储过程

BEGIN 
    SET NOCOUNT ON; 

    DECLARE @Status AS BIT 

    IF EXISTS (SELECT [TransactionMstID] 
       FROM [dbo].[tbl_TransactionMst] 
       WHERE [TransactionRef] = @DocumentNumber 
       AND [SupplierID] = @SupplierID) 
    BEGIN 
     SET @Status = 0 
    END 
    ELSE 
    BEGIN 
     SET @Status = 1 
    END 

    SELECT @Status AS [Status] 
END 

当我在SQL Server Management Studio中(SSMS)尝试不同的场景,我得到想要的输出如存在参考时为“0”,不存在时为“1”。

问题出现在我的C#代码中,它执行存储过程,但在我的测试中,无论数据是否存在,我都得到相同的结果。

这里是C#的核心:

bool returnValue = true; 

    if (Docnumber != null) 
    { 
     SqlConnection con = new SqlConnection(GlobalSettings.connection); 
     con.Open(); 

     SqlCommand Cmd = new SqlCommand("p_ValRefNumber", con); 
     Cmd.CommandType = System.Data.CommandType.StoredProcedure; 

     Cmd.Parameters.AddWithValue("@DocumentNumber", Docnumber); 
     Cmd.Parameters.AddWithValue("@SupplierID", SupplierID); 

     Cmd.ExecuteNonQuery(); 

     SqlDataReader dr = Cmd.ExecuteReader(); 

     while (dr.Read()) 
     { 
      bool Status = convertor.ConvertToBool(dr["Status"]); 
      string test = dr["Status"].ToString(); 
      int testint = convertor.ConvertToInt(dr["Status"].ToString()); 

      if (Status == false) 
      { 
       //throw new System.Exception(CEObj.GetErrorDesc(101)); 
       returnValue = false; 
      } 
     } 

     dr.Close(); 
     con.Close(); 
    } 

    return returnValue; 
} 

无论什么docnumber值在测试中,它总是显示为True。我添加了一个断点,以便我可以检查每次,然后在SSMS中进行测试,并得到相互冲突的结果。

我的逻辑错了吗? Visual Studio是否以不同的方式处理值?将结果转换为string时结果不一致 - 至少如此?它似乎总是读VS一个“1”的价值,但在SSMS变化

编辑:这是我的转换方法的代码:

public static bool ConvertToBool(object value) 
{ 
     bool result = false; 

     if (value != null) 
     { 
      bool.TryParse(value.ToString(), out result); 
     } 

     return result; 
} 
+0

在Docnumber上划一个断点。语句评估为True时的值是多少? –

+0

目前它是'12324' - 在[[tbl_TransactionMst]' – Daniel

+1

'转换器的代码在哪里?也许这不符合你的想法。我建议你在调试器中通过convertor.ConvertToBool。 – Polyfun

回答

2

bool.TryParse没有做什么转换器(SIC)的代码,认为这确实。

bool.TryParse如果值参数等于bool.TrueString(它是文本字符串“True”),则返回true。它对任何其他值返回false,这意味着它对0和1都返回false。

另外,T-SQL bit values是数字。转换器代码并不是必须的 - 只需将返回值转换为Int32并进行比较即可。

using (var con = new SqlConnection(GlobalSettings.connection)) 
{ 
    con.Open(); 
    using (var cmd = new SqlCommand() { Connection = con, CommandType = CommandType.StoredProcedure, CommandText = "p_ValRefNumber" }) 
    { 
    /* Assuming both parameters are integers. 
     Change SqlDbType if necessary. */ 
    cmd.Parameters.Add(new SqlParameter() { ParameterName = "@DocumentNumber", SqlDbType = SqlDbType.Int, Value = Docnumber }); 
    cmd.Parameters.Add(new SqlParameter() { ParameterName = "@SupplierID", SqlDbType = SqlDbType.Int, Value = SupplierID }); 

    using (var reader = cmd.ExecuteReader(CommandBehavior.CloseConnection)) 
    { 
     return dr.Read() && (Convert.ToInt32(dr["Status"]) == 1) 
    } 
    } 
} 
+0

谢谢克里斯,你能解释一下对我的回报?我不明白语法 – Daniel

+0

表达式的前半部分 - “dr.Read()' - 尝试从结果集中读取一行,如果成功则返回true。第二部分将'Status'值转换为'Int32',并将其与1进行比较。用简单的语言,表达式的内容如下:“返回是否成功检索了行,并且该行中的”Status“列等于1。请注意[&&](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/operators/conditional-and-operator)运算符不会评估表达式的后半部分,如果前半部分返回false(即如果没有行被读取)。 –

+0

哦,我明白了,这比我使用的更有效率!您的代码完美工作,但它突出了从Excel文件导入的另一个问题。我不认为你有这方面的专业知识吗? – Daniel