2017-08-24 5 views
1

ユーザーがExcelファイルの形式でアップロードしたデータを検証するWebフォームで作業しています。コードはスプレッドシートの各行を繰り返し処理し、さまざまなルールをチェックします。その1つは、参照が一意の値でなければならないということです。私はSQL Server Management Studioを(SSMS)でさまざまなシナリオをしようとすると、私は希望の出力などを得る一貫性のない戻り値を提供するストアドプロシージャ

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 

:私は、パラメータとしてuserIDreferenceNumを取るストアドプロシージャを持っています参照が存在するときには「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.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

Chrisに感謝します。 – Daniel

+0

式の前半 - 'dr.Read()' - 結果セットから1行を読み込もうとしましたが、成功した場合はtrueを返します。 'Status'値を' Int32'に変換して1と比較します。普通の言語では、次のようになります。 "行が正常に取得され、その行の' Status'カラムが1に等しい場合に返します。 [&&](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/operators/conditional-and-operator)演算子は、式の後半を評価しません。最初の半分falseを返します(つまり、行が読み取られなかった場合)。 –

+0

ああ、それは私が使っていたものよりずっと効率的です!コードは完璧に動作しますが、Excelファイルからのインポートに関する別の問題が強調表示されています。あなたはそれに専門知識を持っているとは思わない? – Daniel

関連する問題