2

重複の可能性:
ExecuteScalarはnullまたはDBNull(開発サーバーまたは本番サーバー)を返します

既存のファイルIDがアイテムに関連付けられているかどうかを確認するストアドプロシージャがあります。selectステートメントが値を返す場合、それはtrueであり、boolに「true」を割り当てる必要があります。ただし、selectステートメントが存在しないためにnullを返す場合でも、コードビハインドは.Executeを「true」に戻します。

これは私のストアドプロシージャです:

ALTER PROCEDURE [dbo].[Events_TaskIDExists] 
@EventID int
AS
BEGIN
    select TaskID from Events where EventID = @EventID
END

そしてここに私のコードがあります:

public void hasTaskAssociatedToNote()
{
    String[] Notes = hidSelectedEventIDs.Value.Split(',');
    bool exists = false;
    foreach (var note in Notes)
    {
        var connection = new SqlConnection(ConfigurationManager.ConnectionStrings["OSCIDConnectionString"].ToString());
        var command = new SqlCommand("Events_TaskIDExists", connection);
        command.Parameters.Add(new SqlParameter("@EventID", SqlDbType.Int));
        command.Parameters["@EventID"].Value = Convert.ToInt32(note.Trim());
        command.CommandType = CommandType.StoredProcedure;
        try
        {
            connection.Open();
            exists = command.ExecuteScalar() != null;//causes true when it returns null......
            var temp = command.ExecuteScalar();//this was just to check something else
            if (exists)
            {
                exhibitWarning.Visible = true;
                Warning1.Text = "There is an existing Task associated 0.";
            }
        }
        catch (SqlException sql)
        {
            lblStatus.Text = "Couldn't connect to the Database - Error";
            lblStatus.ForeColor = System.Drawing.Color.Red;
        }
        catch (Exception ex)
        {
            lblStatus.Text = "An error occured";
            lblStatus.ForeColor = System.Drawing.Color.Red;
        }
        finally
        {
            if (connection.State == ConnectionState.Open)
                connection.Close();
        }
    }
}
4

2 に答える 2

3

変数は次のexistsように設定する必要があります。

object result = command.ExecuteScalar();
exists = result != DBNull.Value && result != null;

からのnullの結果は、ではなく、をSqlCommand.ExecuteScalar()返します。空の結果セットのみがを返します。DBNull.Valuenullnull

EventIDに基づいてTaskIDを選択しているので、すべてのイベントにTaskIDを要求するようにデータベースが制約されていないため、TaskIDフィールドがnullになっていると思います。つまり、を含むイベントレコードがありますが@EventID、関連付けられたタスクレコードはありません(に基づくTaskID)。この条件は、DBNull.Valueではなくを返しnullます。

"戻り値の タイプ:System.Object結果セットの最初の行の最初の列、または結果セットが空の場合はnull参照(Visual BasicではNothing)。最大2033文字を返します。" -MSDN - SqlCommand.ExecuteScalar()

于 2012-10-22T21:07:10.550 に答える
1

私はおそらくこれとちょうどショットガンだろう

exists = (command.ExecuteScalar() ?? DBNull.Value) != DBNull.Value;

これは、何らかの理由で、ストアドプロシージャが、最初の列がDBNullに等しい行を実際に返していること、およびその場合に存在する==falseであることを前提としています。短いデバッグはそれを証明または反証する必要があります。

于 2012-10-22T21:11:15.883 に答える