Odbcresultset

Anatoly

Well-Known Member
Lotus team
30.03.2007
222
0
#1
Столкнулся с ситуацией что ODBCResultSet возвращает не все записи по сравнению с таким-же SQL-запросом на самом MS SQL сервере.
Получить больше 4112 записей никак не получалось (хотя на самом деле должно быть 6912). После изменения свойства .CacheLimit с дефолтного на DB_ALL, возвращает положенное. А есть еще и .FetchBatchSize, дефолтное значение которого =1 пока не трогал.
Почему количество кешируемых записей по умолчанию имеет такое "засадное" значение?
Как играя данными свойствами не нарушить производительности? Иметь везде .CacheLimit =DB_ALL мне кажется не очень правильным, так как некоторые запросы будут возвращать до 50-60 тысяч записей для анализа в агенте.
 

Akupaka

А че я?.. О.о
04.10.2007
3 360
2
#2
Получить больше 4112 записей никак не получалось (хотя на самом деле должно быть 6912). После изменения свойства .CacheLimit с дефолтного на DB_ALL, возвращает положенное. А есть еще и .FetchBatchSize, дефолтное значение которого =1 пока не трогал.
А как считал? По-идее, если проходить строки, то должен обойти все, что возвращает запрос, а не только закешированные.
К сож проверить не могу, не имею сиквела под рукой...
 

Anatoly

Well-Known Member
Lotus team
30.03.2007
222
0
#3
А как считал? По-идее, если проходить строки, то должен обойти все, что возвращает запрос, а не только закешированные.
К сож проверить не могу, не имею сиквела под рукой...
Агент получает записи от MS SQL сервера, либо создает новый документ в базе LN, либо получает ссылку на существующий и обновляет поля.
Я просто уже ввел счетчик

RetCode = ResDog.FirstRow
Cnt =0
Do While RetCode = True
cnt =cnt+1
...
RetCode =resDog.NextRow
Loop

Так вот cnt=4112 после отработки агента, тот-же SQL запрос, что был в ODBCQuery.SQL на самом сервере возвращает 6912 записей.
 

Akupaka

А че я?.. О.о
04.10.2007
3 360
2
#4
А почему справку не читаешь?
Do not use NextRow as a condition for a While or Until loop because when NextRow returns False because there are no more rows, an error is generated. Use IsEndOfData to test for the end of the table, and use NextRow within the loop.
In a Do loop, use IsEndOfData in the Until clause. Then, you can use NextRow at the top of the loop. When the loop is first called and no other procedures have been called, NextRow is set to 1 to cover all rows in the table.
Возможно, поведение программы это и не изменит, но попробовать стоит.
 

Anatoly

Well-Known Member
Lotus team
30.03.2007
222
0
#5
А почему справку не читаешь?

Возможно, поведение программы это и не изменит, но попробовать стоит.
:lovecodeby: Приведенный вариант я попробовал только сегодня утром, в поисках.
А до вчерашнего дня было:

res.Execute
Do
res.NextRow
<...>
Loop Until res.IsEndOfData

Вид тот-же, результат был тот-же.
Только после .CacheLimit =DB_ALL обработались все записи.
 

Akupaka

А че я?.. О.о
04.10.2007
3 360
2
#6
Что ж... "на этом мысли заканчиваются" :) А тестить не на чем, а подымать себе сиквел... ну не хочется :lovecodeby:
В любом случае, лучше использовать .IsEndOfData для проверки.
 

Anatoly

Well-Known Member
Lotus team
30.03.2007
222
0
#7
Что ж... "на этом мысли заканчиваются" :) А тестить не на чем, а подымать себе сиквел... ну не хочется :lovecodeby:
В любом случае, лучше использовать .IsEndOfData для проверки.
Да проблема как бы снялась...
Остался вопрос об оптимальном подборе .CacheLimit и .FetchBatchSize для разных ситуаций.
В хелпе никаких рекомендаций не нашел. Кроме что-бы второе было не больше первого :)
 

lmike

нет, пердело совершенство
Lotus team
27.08.2008
6 483
360
#8
а может вопрос не имеет отношения к нотусам? :lovecodeby:
курить мсявые спеки, одбц, и прочие шняжки...
или из хелпа Examples: NumRows method:
Код:
Uselsx "*LSXODBC"
Sub Initialize
Dim con As New ODBCConnection
Dim qry As New ODBCQuery
Dim result As New ODBCResultSet
Dim firstName As String
Dim lastName As String
Dim msg As String
Set qry.Connection = con
Set result.Query = qry
con.ConnectTo("ATDB")
qry.SQL = "SELECT * FROM STUDENTS ORDER BY LASTNAME"
result.Execute
result.LastRow
msg = "Student names:" & Chr(10)
For i = 1 To result.NumRows
result.CurrentRow = i
firstName = result.GetValue("FIRSTNAME", firstName)
lastName = result.GetValue("LASTNAME", lastName)
msg = msg & Chr(10) & firstName & " " & lastName
Next
Messagebox msg,, "Student Names"
result.Close(DB_CLOSE)
con.Disconnect
End Sub
 

Anatoly

Well-Known Member
Lotus team
30.03.2007
222
0
#9
Все может быть, но:
-
res.CacheLimit =DB_ALL
res.Execute
res.LastRow
Print "NumRows =" & Cstr(res.NumRows)
Возвращает 6192 записи
-
если закомментировать 1 строку
'res.CacheLimit =DB_ALL
res.Execute
res.LastRow
Print "NumRows =" & Cstr(res.NumRows)
Возвращает 1 (!)
 

Anatoly

Well-Known Member
Lotus team
30.03.2007
222
0
#10
Потестировал тут...
---
Call con.ConnectTo("Server1","sa","sa")
Set qryAdU.Connection = Con
Set resAdU.Query = qryAdU
resAdU.CacheLimit =DB_ALL
qryAdU.SQL = "SELECT TOP 10 * FROM dbo.Adr"
resAdU.Execute

Dim cnt As Long
Cnt =0
Do
resAdU.NextRow
cnt =cnt+1
...
Loop Until resAdU.IsEndOfData
Print Cstr(cnt)
---
при resAdU.CacheLimit =DB_ALL обрабатываются всего 6 записей (1,3,5,7,9,10)
если закомментарить - обрабатываются все 10

что-то я непонятках