Consultor Eletrônico



Kbase P65124: Visual Basic 6.0 application uses ADO and ODBC to talk to Progress database, Update takes 30+ second
Autor   Progress Software Corporation - Progress
Acesso   Público
Publicação   10/15/2008
Status: Verified

FACT(s) (Environment):

Progress 9.1D
MERANT 3.60 32-BIT Progress SQL-92

SYMPTOM(s):

Visual Basic 6.0 application uses ADO and ODBC to talk to Progress database

Invoking the ADO RecordSet objects Update method to update a single record takes 30+ seconds to execute

Large number of exclusive locks are obtained against the table being updated

CAUSE:

The SELECT statement which is used to fetch the record uses the correct index to resolve the query, however, the index is not defined as being unique so when the update is invoked an index scan is performed which in turn causes each record to be exclusively locked until the correct record is found.

FIX:

The resolution for this problem is to use the ADO Connection objects Execute method to send a SQL UPDATE statement directly to the server.  This UPDATE statement must use a WHERE clause that references the ROWID to update.

In order to obtain the ROWID the SELECT statement must select an explicit list of columns along with the ROWID function.  

Sample code is shown below:

Dim MyConnection As Connection
Dim MyRecordSet As Recordset
Dim MyUpdateStatement As String
Dim MySelectStatement As String

Set MyConnection = New ADODB.Connection

MyConnection.Open "DSN=SomeDB;UID=SomeUser;PWD=SomePassword;"

Set MyRecordSet = New ADODB.Recordset

MySelectStatement = "SELECT ROWID, Field1 FROM PUB.SomeTable WHERE SomeField = SomeValue"

MyRecordSet.Open MySelectStatement, MyConnection, adOpenDynamic, adLockReadOnly

If Not MyRecordSet.EOF Then
MyUpdateStatement = "UPDATE PUB.SomeTable "
MyUpdateStatement = MyUpdateStatement + "SET Field1 = 'SomeValue' "
MyUpdateStatement = MyUpdateStatement + " WHERE ROWID = '" + MyRecordSet("Rowid").Value + "'"

MyConnection.Execute (MyUpdateStatement)

MyRecordSet.Close
MyConnection.Close
Set MyRecordSet = Nothing
Set MyConnection = Nothing
Else
MsgBox "Record not found", vbCritical
End If