Обновление набора записей VB6

Я запускаю программу vb6, которая просматривает множество записей в таблице базы данных и вводит дату в поле. Это займет много часов.

Я заметил, что количество записей в таблице увеличивается на 1 каждые несколько секунд, а затем уменьшается на 1 (возвращаясь к исходному количеству). Есть причина для этого?

Я использую набор записей VB6 и функцию обновления, то есть rs.update. Я не вставляю никаких новых записей.

Код выглядит следующим образом:

rs.Open "select reference,value1,datefield from datetable where field1 = 'value1' " & _
    "order by reference", objAuditCon.ActiveCon, adOpenStatic, adLockPessimistic

Do While Not rs.EOF
    intReadCount = intReadCount + 1
    DoEvents
    If Not IsNull(rs("value1")) Then
        testArray = Split(rs("value1"), ",")
        rs2.Open "SELECT Date FROM TBL_TestTable WHERE Record_URN = '" & testArray(1) & "'", objSystemCon.ActiveCon, adOpenStatic, adLockReadOnly
        If rs2.EOF Then

        End If
        If Not rs2.EOF Then
            rs("DateField") = Format$(rs2("Date"), "dd mmm yy h:mm:ss")
            rs.Update
            intWriteCount = intWriteCount + 1
        End If
    rs2.Close
    Else    
    End If

rs.MoveNext
Loop
rs.Close

person w0051977    schedule 05.01.2012    source источник
comment
Я не вижу причин для увеличения количества записей, но мне просто любопытно, почему вы не выполняете операторы SQL для обновления информации, а не перебираете записи? Тогда можно было сразу обновить кучу.   -  person Jordan    schedule 05.01.2012
comment
Почему бы не создать хранимую процедуру, а затем выполнить ее с помощью кода? Это должно немного сократить время обработки.   -  person Mark Kram    schedule 05.01.2012
comment
Я думаю, что может быть дополнительная строка для кеширования?   -  person w0051977    schedule 05.01.2012
comment
Как вы определяете, что количество записей меняется?   -  person CJ7    schedule 06.01.2012
comment
CraigJ, я просто запускаю счетчик в диспетчере SQL Studio, т.е. выбираю счетчик (*) из таблицы дат? Нажимая кнопку выполнения каждую секунду, счетчик иногда увеличивается на одну запись, а затем сразу уменьшается на одну запись? У тебя есть идеи? Спасибо.   -  person w0051977    schedule 06.01.2012
comment
Что было бы более интересно, так это то, какие данные находятся в этой дополнительной строке. В любом случае, суть в том, что если это на самом деле не вызывает у вас проблемы, не беспокойтесь об этом. Вы можете уведомить Microsoft о проблеме и посмотреть, что они скажут. Они предназначены для оказания поддержки.   -  person CJ7    schedule 08.01.2012
comment
@CraigJ MS, вероятно, не будет поддерживать поддержку, поскольку использует приложение VB 6. Больше они этого не поддерживают. Возможно, будет зависеть от версии базы данных, но, вероятно, они не будут ее трогать.   -  person Jordan    schedule 09.01.2012


Ответы (2)


Что ж, здесь вы можете значительно сократить объем работы с SQL.

If Not IsNull(rs("value1")) Then
        testArray = Split(rs("value1"), ",")
        rs2.Open "SELECT Date FROM TBL_TestTable WHERE Record_URN = '" & testArray(1) & "'", objSystemCon.ActiveCon, adOpenStatic, adLockReadOnly
        If rs2.EOF Then

        End If
        If Not rs2.EOF Then
            rs("DateField") = Format$(rs2("Date"), "dd mmm yy h:mm:ss")
            rs.Update
            intWriteCount = intWriteCount + 1
        End If
rs2.Close

По сути, вы, как мне кажется (я не использовал VB6 и ADO в течение 10 лет), загружаете ваш исходный набор записей, проверяете значение и, если это значение не равно нулю, выполняете второй выбор, ЗАТЕМ обновляя набор записей. ... Вместо того, чтобы делать все это, вы можете просто создать командный объект. Объявить их перед циклами dim objComm set objComm = Server.CreateObject("ADODB.Command")

objComm.ActiveConnection =  objSystemCon.ActiveCon 'I think this is your connn.
objComm.CommandType = 1 'adCmdText

Используйте это в своем цикле

objComm.CommandText = "UPDATE DateTable SET DateField = (SELECT Date FROM TBL_TestTable WHERE Record_URN = '" & testArray(1) & "'")
objComm.Execute 

Вместо того, чтобы делать второй дискретный выбор, извлекать данные, затем выполнять обновление и возвращать их обратно, просто вытолкните инструкцию обновления. Это должно ускорить обработку ваших записей ... Я знаю, что давно писал такие вещи на VB6 :)

Итак, ваш код теперь должен выглядеть как

dim objComm
set objComm = Server.CreateObject("ADODB.Command")` 

    objComm.ActiveConnection =  objSystemCon.ActiveCon 'I think this is your connn.
    objComm.CommandType = 1 'adCmdText

rs.Open "select reference,value1,datefield from datetable where field1 = 'value1' " & _
    "order by reference", objAuditCon.ActiveCon, adOpenStatic, adLockPessimistic

Do While Not rs.EOF
    intReadCount = intReadCount + 1
    DoEvents
    If Not IsNull(rs("value1")) Then
        testArray = Split(rs("value1"), ",")
    objComm.CommandText = "UPDATE DateTable SET DateField = (SELECT Date FROM TBL_TestTable WHERE Record_URN = '" & testArray(1) & "'")
    objComm.Execute 

    End If

rs.MoveNext
Loop
rs.Close

ваш оператор select все еще там, как вы можете видеть, теперь это вспомогательный выбор, преимущество огромно, вы не рисуете записи на сервер, а затем обновляете их. Вы отправляете серверу инструкцию для выполнения обновления. Вы сокращаете свои поездки вдвое.

Надеюсь, это имело смысл.

person Jordan    schedule 06.01.2012
comment
Джордан, я понимаю, что есть более эффективные способы написания кода. Однако исходный вопрос был задан конкретно о том, почему количество записей увеличивается на 1 запись каждые несколько секунд, а затем сразу же уменьшается на 1 запись. Я устанавливаю количество записей, выполняя SQL-запрос в SQL Studio Manager. Спасибо. - person w0051977; 06.01.2012
comment
Да, я понимаю, что извините, я просто воспользовался возможностью, чтобы сделать предложение. Это должно быть что-то еще, вызывающее это. У вас есть указатель на столе? Возможно, постоянные обновления приводят к тому, что индекс возвращает несколько отличающееся значение. Я подозреваю, что НЕ создается дополнительная строка. Если вы действительно считаете, что есть лишняя строка, я полагаю, вы могли бы скопировать таблицу в другую со всеми данными и запустить запрос, чтобы вытащить те, которые существуют в таблице обработки, по сравнению со статической резервной копией. Это будет очень медленно, и я не думаю, что это что-то покажет. - person Jordan; 06.01.2012
comment
Спасибо, Джордан. Я думал об этом весь день. Я провел несколько тестов с данными, и хотя они возвращают больше строк, когда программа работает; он не возвращает никаких строк, когда я пытаюсь запустить сравнение, то есть выбрать * из таблицы дат, где нет ссылки (выберите ссылку из datetabletest). Таблица datetabletest была создана до запуска программы. Когда я добавляю первичный ключ, проблема больше не возникает, т. Е. Счет согласовывается. У тебя есть другие идеи? - person w0051977; 07.01.2012
comment
Сегодня утром мне не удалось получить доступ к этой теме, но, похоже, она появилась снова. - person w0051977; 07.01.2012
comment
Ну, первичный ключ добавит в таблицу кластеризованный индекс. Возможно, у вас раньше не было индекса? Я полагаю, что некоторая блокировка строк может вызвать расходящееся количество строк. Наличие индекса позволит ему получить доступ к счетчику строк независимо от блокировок на уровне таблицы. Я знаю, что ожидающая транзакция может давать неправильное количество строк в зависимости от, поэтому я предполагаю, что это возможно. Если вы знакомы с ACID, I - это изоляция, поэтому, возможно, сервер не имеет дело с этой строкой, пока она фактически обновляется. Теперь, когда я думаю об этом, у обновления есть неявная транзакция, которая, вероятно, заблокирует читателя. - person Jordan; 07.01.2012
comment
При запуске программы возвращаются другие записи. Если бы возникла проблема с блокировкой, я бы ожидал, что запрос вернет меньше запросов. Как я уже сказал, это происходит, когда есть кластерный индекс и нет первичного ключа. Этого не происходит при наличии кластерного индекса и первичного ключа. - person w0051977; 07.01.2012
comment
Есть ли у вас какие-либо триггеры обновления таблицы данных. Это может быть причиной вашей проблемы с добавлением / удалением. - person George Mastros; 08.01.2012
comment
Хорошо. На этом этапе я бы предложил запустить SQL Server Profiler. Вы можете видеть, что происходит на самом деле. Есть ли у вас опыт использования этого инструмента? - person Jordan; 08.01.2012
comment
Я поговорил с администратором баз данных, и мы выполнили некоторую отладку с помощью SQL Profiler. Не было ничего убедительного. - person w0051977; 10.01.2012

Простой ответ: уберите инструкцию DoEvents. Если вы используете его для обновления экрана, периодически обновляйте графический интерфейс вручную после, скажем, 1000 итераций цикла.

Причина, по которой это может вызвать проблему, заключается в том, что другой код, который вы не можете контролировать, может выполняться при вызове DoEvents.

person Mark Bertenshaw    schedule 12.04.2013