-1

我没想到这会是一项如此艰巨的任务。

用户参加测验,然后出于任何原因决定重新参加测验。

我们的要求是在将结果插入 SurveyAnswers 表之前删除该用户已经完成的测验结果。

下面的代码旨在删除属于尝试重新参加测验的用户的每个 questionId (qid) 的现有结果,然后插入当前结果。

这应该在一个操作中。

然后,如果当前不存在结果,则插入当前测验的结果。

代码没有插入或删除。

非常感谢您的帮助。

这是我的代码:

Private Sub SaveAnswer(ByVal qid As Integer, ByVal cid As Integer, ByVal ct As String, ByVal cscore As Integer)
    Dim al As ArrayList = CType(Session("AnswerList"), ArrayList)

    If al Is Nothing Then
        Response.Redirect("List.aspx")
    End If

    Dim cnn As New SqlConnection(ConfigurationManager.ConnectionStrings("DBConnectionString").ConnectionString)

    Dim cmd As New SqlCommand("IF EXISTS(SELECT QuestionId FROM SurveyAnswers WHERE questionId = @qid and UserName = @cuser " & _
                           "BEGIN delete from SurveyAnswers where UserName=@cuser and QuestionId=@qid " & _
                           "insert into surveyanswers(QuestionID,ChoiceID,ChoiceText,Username,dateTaken) values(@qid,@cid,@ct,@cuser,getDate()) END " & _
                           "Else BEGIN insert into surveyanswers(QuestionID,ChoiceID,ChoiceText,Username,dateTaken) values(@qid,@cid,@ct,@cuser,getDate()) END", cnn)
    Dim p1 As New SqlParameter("@qid", qid)
    Dim p2 As New SqlParameter("@cid", IIf(cid = 0, DBNull.Value, cid))
    Dim p3 As New SqlParameter("@ct", IIf(ct = "", DBNull.Value, ct))
    Dim p4 As New SqlParameter("@cuser", Session("UserName"))
    cmd.Parameters.Add(p1)
    cmd.Parameters.Add(p2)
    cmd.Parameters.Add(p3)
    cmd.Parameters.Add(p4)
    cnn.Open()
    cmd.ExecuteNonQuery()
    cnn.Close()
End Sub
4

1 回答 1

0

以下是应 OP 的要求提升为答案的评论:

if exists ( select 42 from SurveyAnswers where ... )
  begin
  delete SurveyAnswers where ...
  end;
insert into SurveyAnswers ...

旁白:请注意,您所做的不是原子的,除非它包含在适当隔离级别的事务中。虽然单个用户不太可能同时多次回答同一个调查问题,但您应该意识到这个问题并做出明确的决定来处理或忽略它。我同意在存储过程中实现它,例如:

create procedure dbo.InsertSurveyAnswer
  -- NB: The prior answer, if any, is deleted.
  @QuestionId as Int,
  @ChoiceId as Int,
  @ChoiceText as NVarChar(64),
  @Username as NVarChar(64)
  as

  set nocount on;

  set transaction isolation level serializable;
  begin transaction;

  -- Attempt to delete any prior answer for this user/question.
  delete from SurveyAnwers
    where Username = @Username and QuestionId = @QuestionId;

  -- Save the new answer.
  insert into SurveyAnswers
    ( QuestionId, ChoiceId, ChoiceText, Username, DateTaken ) values
    ( @QuestionId, @ChoiceId, @ChoiceText, @Username, GetDate() );

  commit transaction;

正如 Martin Smith 所建议的那样,您可能只是简单地执行delete而不是浪费资源来确定是否需要它。如果您有理由知道某行是否被删除,您可以检查@@RowCountafter的值。delete

于 2013-08-18T18:04:05.640 回答