存储过程未在表中插入值。

4

我有一个存储过程,首先在UserSignUp表中更新值,然后在UserKeyPoints表中插入值,但我的存储过程没有执行。

这是我的存储过程:

CREATE PROC [dbo].[proc_getActivationCode] @ActivationCode VARCHAR(1000)=''
AS
  BEGIN
      IF EXISTS(SELECT ActivationCode
                FROM   UserSignUp
                WHERE  ActivationCode = @ActivationCode
                       AND Activate = 'False')
        BEGIN
            DECLARE @UserId INT

            SET @userid= (SELECT AutoID
                          FROM   UserSignUp
                          WHERE  ActivationCode = @ActivationCode)

            UPDATE UserSignUp
            SET    Activate = 'Confirm Code'
            WHERE  ActivationCode = @ActivationCode

            INSERT INTO UserKeyPoints
                        (KeyPoints,
                         UserId)
            VALUES      (500,
                         @userid)

            SELECT 1
        END
      ELSE
        BEGIN
            SELECT 2
        END
  END 

这是我执行存储过程的C#代码。
if (Request.QueryString["token"] != null)
{
    Label1.Text = Request.QueryString["token"];
    con.Open();
    SqlCommand cmd = new SqlCommand("proc_getActivationCode1", con);
    cmd.Parameters.AddWithValue("@ActivationCode", Request.QueryString["token"].ToString());
    SqlDataReader dr = cmd.ExecuteReader();
    DataTable dt = new DataTable();
    dt.Load(dr);
    dr.Close();
    con.Close();

    if (dt.Rows[0][0].ToString() == "1")
    {
        //Label1.Text = "You are confirmed successfully. Please Click here for Login: ";
        SendEmail objMail = new SendEmail();

    }
    else
    {
        Label1.Text = "You are already confirmed.";
    }
}

当我执行这段代码时,它会在没有insertupdate的情况下运行该过程,在我的.aspx页面上,我得到了Label1的输出,即You are already confirmed. 有人能指导我出了什么问题吗?

2
你的SP存在一些并发问题。 - Hamlet Hakobyan
2
关于上述内容,您可以替换整个 IF EXIST5 部分,直接执行更新操作,并使用 OUTPUT 子句将所需值直接插入到 UserKeyPoints 中。然后检查 @@ROWCOUNT 以了解要返回的值。因此,存储过程基本上变成了两个语句,并解决了并发问题。 - Martin Smith
@MartinSmith 好的。这样会好得多。谢谢。让我们研究和开发这个技术。 - analyticalpicasso
@MartinSmith,我已经解决了我的问题,但很高兴我找到了另一种方法。从现在开始会注意并发问题。 - analyticalpicasso
1个回答

4
我能看到的第一个问题是缺少将 CommandType设置为StoredProcedure。
这是基础,可以让框架代码正确地解释您的字符串。
SqlCommand cmd = new SqlCommand("proc_getActivationCode1", con);
cmd.CommandType = CommandType.StoredProcedure;

Martin Smith在下面的评论中所解释的那样,调用失败的原因是没有正确设置CommandType,因此参数不会传递给存储过程,而是使用@ActivationCode参数的默认值执行了该过程。

然后我将编写对存储过程的调用,使用ExecuteScalar而不是使用SqlDataAdapter仅返回数据表中的单行单列。

SqlCommand cmd = new SqlCommand("proc_getActivationCode1", con);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("@ActivationCode", Request.QueryString["token"].ToString());
object result = cmd.ExecuteScalar();
if(result != null)
{
    int resultValue = Convert.ToInt32(result);
    if (resultValue == 1)
        SendEmail objMail = new SendEmail();
    else
        Label1.Text = "You are already confirmed.";
}

4
是的,缺少的命令类型意味着存储过程仍会被执行(一个只包含单词“proc_getActivationCode1”的批处理将被视为存储过程调用),但参数不会传递给它。 - Martin Smith
2
哦,这个网站真是太棒了,它永远不会停止教你新的东西并改变你未经测试的信念。当然,你是对的,我刚刚测试了 sp_help 提示,它也可以在没有设置 CommandType 的情况下工作。你介意我用你的评论来完善答案吗? - Steve
好的,你能解释一下你改变了什么吗?我希望为未来的读者提供一个完整的答案。 - Steve
1
@Steve,我在存储过程中删除了IF EXIST部分,并使用您改进的代码更新了我的代码。不需要更新,因为我所做的一切都已经在您的答案中了。 :) - analyticalpicasso
1
@Steve 还有一件事,我也同意这个网站永远不会停止教授新知识。你总是能从这里学到更多! - analyticalpicasso
显示剩余5条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接