2014-05-02 44 views
1

我所在的公司正在举行筹款活动工作后,要我把一个小的Web应用程序通过PayPal接受捐赠。这听起来很简单,但截止日期很紧,所以我决定疏通一些类似于我在10年前在Classic ASP/VBScript中创建的东西,并重用它(以及Access数据库)。但随后的需求变了,变得更加复杂(同期限虽然),并且,为了使长话短说,我结束了代码大杂烩和应用程序,似乎正常工作......直到今天,当用户报告在应用程序的“谢谢”页面看到错误的数据。一个记录插入到数据库后,它在某一点我清楚的是,代码偶尔会返回错误的ID,但我无法复制的错误,或者发现代码中的问题,我希望有人也许能够帮我。经典ASP/VBScript中 - 偶尔返回错误的ID插入

在最简单地说,这里的应用程序是如何工作的:

  1. 用户必须注册三个不同事件的选择,必须做一个PayPal捐赠,参加他选择的事件。根据他报名的事件,他可以做出各种其他选择。所以基本上,用户填写了一个标准的html表单,并且在后台有大量的jQuery内容来帮助指导用户完成各种选择。
  2. 当用户做出所有必需的选择并点击“提交”按钮后,我使用jQuery将ajax调用发送到经典的ASP/VBScript页面,该页面将用户的数据插入Access数据库并返回新插入的记录作为json响应。
  3. ajax成功函数采用新的id,将其插入隐藏的PayPal表单中名为“item_number”的字段,然后将PayPal表单提交给PayPal。然后用户被带到PayPal进行支付。
  4. 我有贝宝的即时付款通知功能设置,这样,当用户进行支付,通知发送到我们的服务器上的监听器。通知包含查询字符串中的item_number,并且侦听器接收item_number,返回Access数据库并更新该记录以显示用户实际已付款。
  5. 最后,贝宝用户返回感谢您网页我们的服务器上。感谢页面提取item_number查询字符串,查询Ac​​cess数据库以查找与该id相匹配的记录,并显示用户注册的确认(这是“谢谢”页面)。

问题是,在数据插入到数据库(数据插入正确)之后,在步骤2中偶尔会出现错误的id,这反过来会对其余步骤产生不利影响。另一个问题是,有时当PayPal将用户返回到“谢谢”页面时,它会附加item_number查询字符串两次,这似乎在服务器上引发500错误...所以用户获得了500页而不是谢谢。起初我想可能有两个人立刻注册了,而Access只是跛脚,但我能够确认当时只有一个用户注册了。

,我认为这个问题必须在步骤2中的代码,但我完全失踪了。下面的代码(我已经离开了这里的大部分领域,以节省空间):

'Declare field names 
Dim Email 
Dim EventType 

'Declare variable for the id of the inserted record 
Dim currentId 

Email = Request.Form("Email") 
EventType = Request.Form("EventType") 

'if EventType = tournament, then check if user already registered 
If EventType = "tournament" Then 
    Dim rscheckregistration 
    Dim rscheckregistration_cmd 
    Dim checkRegistration 
    Dim hasAlreadyRegistered 

    hasAlreadyRegistered = 0 

    Set rscheckregistration_cmd = Server.CreateObject ("ADODB.Command") 
    rscheckregistration_cmd.ActiveConnection = connregistration 
    rscheckregistration_cmd.CommandText = "SELECT COUNT(*) AS Total FROM tournament WHERE EventType = 'tournament' AND Email = '" & Email & "'" 
    rscheckregistration_cmd.Prepared = true 

    Set rscheckregistration = rscheckregistration_cmd.Execute 

    checkRegistration = rscheckregistration("Total") 

    rscheckregistration.Close 
    Set rscheckregistration = Nothing 

    if checkRegistration > 0 Then 
     hasAlreadyRegistered = 1 
    end if 

    'do not allow user to register more than once 
    if hasAlreadyRegistered = 1 Then 
     Response.ContentType = "application/json" 
     Response.Write("{ ""type"":""Already Registered""}") 
    end if 

    if hasAlreadyRegistered = 0 Then 
     Set rsregister = Server.CreateObject("ADODB.Recordset") 
     rsregister.ActiveConnection = connregistration 
     rsregister.Source = "SELECT * FROM tournament" 
     rsregister.CursorType = 2 
     rsregister.LockType = 3 
     rsregister.CursorLocation = 3 
     rsregister.Open() 

     rsregister.AddNew 

     rsregister.Fields("Email") = Email 
     rsregister.Fields("EventType") = "tournament" 

     'get the id of the record that was just inserted 
     rsregister.Update 
     bookmark = rsregister.absolutePosition 
     rsregister.Requery 
     rsregister.absolutePosition = bookmark 
     currentId = rsregister("TournamentId") 

     rsregister.Close 
     Set rsregister = Nothing 
     Response.ContentType = "application/json" 
     Response.Write("{ ""type"":" & currentId & "}") 
    end if 

'handle EventType = raffle and and EventType = casino 
Else 
    Set rsregister = Server.CreateObject("ADODB.Recordset") 
    rsregister.ActiveConnection = connregistration 
    rsregister.Source = "SELECT * FROM tournament" 
    rsregister.CursorType = 2 
    rsregister.LockType = 3 
    rsregister.CursorLocation = 3 
    rsregister.Open() 

    'insert the record 
    rsregister.AddNew 

    rsregister.Fields("Email") = Email 
    rsregister.Fields("EventType") = EventType 

    'get the id of the newly inserted record 
    rsregister.Update 
    bookmark = rsregister.absolutePosition 
    rsregister.Requery 
    rsregister.absolutePosition = bookmark 
    currentId = rsregister("TournamentId") 

    rsregister.Close 
    Set rsregister = Nothing 
    Response.ContentType = "application/json" 
    Response.Write("{ ""type"":" & currentId & "}") 
End if 
+0

我很惊讶,这并不在你的代码更经常发生,你依靠'Recordset.AbsolutePosition'给你一个书签回到同一记录你再次查询表后。你甚至没有对你的查询进行排序,所以你如何期望这不会给你一个随机记录?如果你的'TournamentId'是一个自动增加的字段,你应该将'SELECT * FROM tournament ORDER BY TournamentId ASC'作为一个最小值,以确保查询在每次重新查询后以相同的顺序返回。即使这是可疑的,但你使用Access,所以你的选择是有限的。 – Lankymart

+1

请注意,使用Access数据库作为Web应用程序的后端是一个**糟糕的想法**。为什么,请看[这里](http://msdn.microsoft.com/en-us/library/jj653753.aspx#access_database)。 –

+1

我知道......我知道......我甚至有一台SQL服务器。我正在懒惰和恢复一个古老的后端。 Mea culpa。 – djackiem

回答

2

不知道为什么你需要Recordset.Requery()得到TournamentId这应该工作一样好(取决于你的连接上,但应该由OLEDB和ODBC支持)。

Set rsregister = Server.CreateObject("ADODB.Recordset") 
rsregister.ActiveConnection = connregistration 
rsregister.Source = "SELECT * FROM tournament" 
rsregister.CursorType = 1 'adOpenKeyset 
rsregister.LockType = 3 'adLockOptimistic 
rsregister.Open() 

'insert the record 
rsregister.AddNew 

rsregister.Fields("Email") = Email 
rsregister.Fields("EventType") = EventType 

'get the id of the newly inserted record 
rsregister.Update 
currentId = rsregister("TournamentId") 

rsregister.Close 
Set rsregister = Nothing 
Response.ContentType = "application/json" 
Response.Write("{ ""type"":" & currentId & "}") 
+0

(cc:@djackiem)+1:我刚刚在OLEDB下测试了这种方法,似乎工作正常。但是,我仍然强烈建议*反对*使用Access数据库作为Web应用程序的后端。 –

+0

约定@GordThompson,这里的瓶颈是JET DB引擎。如果你可以迁移到像SQL Server Express这样更成熟的解决方案,那么它就是等价的。 – Lankymart

+1

使用[更新到JET引擎](http://support.microsoft.com/kb/232144/en-us)完全可以使用INSERT ... INTO ... VALUES(...)和'SELECT @@ identity'这将是我的首选方法。 – Lankymart