-Поиск по дневнику

Поиск сообщений в rss_sql_ru_access_programming

 -Подписка по e-mail

 

 -Постоянные читатели

 -Статистика

Статистика LiveInternet.ru: показано количество хитов и посетителей
Создан: 16.03.2006
Записей:
Комментариев:
Написано: 4


непонятное поведение .AddNew ADO-рекордсета

Суббота, 25 Октября 2014 г. 17:54 + в цитатник
Давно не брал я шашек в руки, а задача была тривиальная - из кода заполнить таблицу числовыми значениями, идущими подряд. В таблице первичный ключ - это самое значение.
Пытался добавлять через открытие ADO-рекордсета в цикле с известным нижним и верхним пределом. Алгоритм - если значение уже есть, пытаемся добавить следующее (по номеру ошибки делаем Resume Next) и т.д. до верхнего предела.
Столкнулся с неведомой хренью - если первое значение вызвало эту ошибку (повторяющиеся значения уник. индекса), то все последующие в цикле ТАКЖЕ НЕ ДОБАВЛЯЮТСЯ в таблицу, хотя их там и нет. Уже голову сломал, где я ошибся. См. тестовый код. Если кто будет тестить, запускать процедуру Test и смотреть вывод в Immediate.
Внесение rst.update в цикл ничего не изменило.
Ясно, что какая-то примитивная ошибка - но я ее не вижу :-(
+


Option Compare Database
Option Explicit

Sub Test()
   On Error GoTo EXCEPT
    
    Call DropTable
    Call CreateTable(NoKey:=False)   'создаем таблицу с первичным ключом
'    Call CreateTable(NoKey:=True) 'создаем таблицу без первичного ключа
    Call PopulateTable(1)
    Call PopulateTable(2) 'по идее должна добавиться 1 запись в таблицу с ключом "4", но не добавляется
    Debug.Print CurrentProject.Connection.Execute("SELECT n FROM d", adCmdText).GetString(, , , ";")
    'смотрим, что получилось
    Call ClearTable
EXIT_HERE:
   Exit Sub

EXCEPT:

    Select Case Err.Number
        Case -2147217865 'таблица не существет
            Resume Next
        Case -2147217900  'таблица существует
            Resume Next
        Case Else
       MsgBox "Произошла ошибка " & Err.Number & vbNewLine & " (" & Err.Description & ") "
    End Select
    Resume EXIT_HERE

End Sub

Sub PopulateTable(ByVal n As Integer)
    Dim SQL As String, rst As ADODB.Recordset, i As Integer
   On Error GoTo EXCEPT

    SQL = "SELECT n FROM d WHERE 1=0"
    Set rst = New ADODB.Recordset
    With rst
        .Open SQL, CurrentProject.Connection, adOpenForwardOnly, adLockOptimistic
        For i = n To n + 2
            .AddNew "n", i 'Err.number -2147217887 возникает даже если такого ключа еще нет
            'в случае, если она уже возникала на предыдущем шаге цикла. (Но Resume next сбрасывает ошибку (обязан сбрасывать))
        Next i
        .Update
        
    End With
EXIT_HERE:
    On Error Resume Next
    rst.Close
    Set rst = Nothing
   Exit Sub

EXCEPT:

    Select Case Err.Number
        Case -2147217887 'повторяющиеся записи
           Resume Next
        Case Else
           MsgBox "Произошла ошибка " & Err.Number & vbNewLine & " (" & Err.Description & ") "
    End Select
    Resume EXIT_HERE
End Sub

Sub CreateTable(Optional NoKey As Boolean = False)
    Dim SQL As String
    If NoKey Then
        SQL = "CREATE TABLE d (n INTEGER NOT NULL)"
    Else
        SQL = "CREATE TABLE [d] ([n] INTEGER NOT NULL, CONSTRAINT d_pk PRIMARY KEY ([N]) )"
    End If
    CurrentProject.Connection.Execute SQL, , adCmdText + adExecuteNoRecords
End Sub

Sub DropTable()
    Dim SQL As String
    SQL = "DROP TABLE [d]"
    CurrentProject.Connection.Execute SQL, , adCmdText + adExecuteNoRecords
End Sub

Sub ClearTable()
    Dim SQL As String
    SQL = "DELETE * FROM d"
    CurrentProject.Connection.Execute SQL, , adCmdText + adExecuteNoRecords
End Sub

http://www.sql.ru/forum/1122965/neponyatnoe-povedenie-addnew-ado-rekordseta


 

Добавить комментарий:
Текст комментария: смайлики

Проверка орфографии: (найти ошибки)

Прикрепить картинку:

 Переводить URL в ссылку
 Подписаться на комментарии
 Подписать картинку