2015-11-30 2 views
0

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

For i= asc("A") To asc("C") 
    DBEngine.Workspaces(0).BeginTrans 
    '...a lot more code... 
    strSql = "SELECT table.string, Count(*) INTO tableCount FROM table LEFT JOIN table2 ON table.string= table2.string WHERE table2.string Is Null AND (((table.string) Like [param])) GROUP BY table.string HAVING (((Count(*))>1))" 
     DoCmd.SetWarnings False 
     Set qdf = CurrentDb.CreateQueryDef("", strSql) 
     qdf.Parameters("param").Value = Chr(i) & "*" 
     Call qdf.Execute(dbFailOnError) 
     DoCmd.SetWarnings True 
     If DCount("*", "tableCount") = 0 Then 'check if there were records 
      GoTo nextIteration 
     End If 
     '...a lot more code using tableCount if DCount shows that there are records... 
    DBEngine.Workspaces(0).CommitTrans 
Next i 

При прибытии в DCount проверки я получаю сообщение об ошибке:

Двигатель Microsoft Access не может найти входную таблицу или запрос «TableCount» .. .

И таблица не отображается в db. Я попытался выполнить запрос, который находится в strSql в Create Query in Access. Когда его спрашивают param, я ввожу A*, и он отлично работает. Таблица tableCount не создается в базе данных до совершения транзакции, но мне она нужна внутри транзакции, а не только для DCount. Есть ли способ использовать таблицу или ее данные перед фиксацией? Пожалуйста, запросите дополнительную информацию, необходимую для ответа на меня, в комментариях. Я отвечу сразу.

+0

Я думаю, что метод Execute выполняется асинхронно, и ваш код будет ждать его до конца, а не продолжать дальше. Я посмотрел CreateQueryDef.Execute, и это параметр dbRunAsync, но он не говорит, что такое по умолчанию, если вы не используете этот параметр. Мое предложение было бы изменить вызов DCount, чтобы включить ваш параметр в качестве фильтра), а не каждый раз создавать новый запрос. Таким образом, вы не будете повторно обновлять tableCount и должны его заблокировать. – nicomp

+0

@DelmerNicholson Вы хотите сказать, что таблица не создана до тех пор, пока транзакция не будет завершена? – MJH

+0

Я думаю, что таблица заблокирована, потому что она обновляется по вашему запросу. Если вы только обновляете его один раз, со всеми вашими подсчетами и без предложения HAVING, вы можете прочитать его с помощью функции DCOUNT без необходимости многократно блокировать ее. – nicomp

ответ

0

Используйте следующие проще и держит все в рамках сделки:

Dim dbS As DAO.Database 
Dim wsP As DAO.Workspace 
Dim lngRecs as Long 
Set wsP = DBEngine.Workspaces(0) 
Set dbS = CurrentDb 
strSql = "SELECT table.string, Count(*) INTO tableCount FROM table LEFT JOIN table2 ON table.string= table2.string WHERE table2.string Is Null AND (((table.string) Like '" & Chr(i) & "*'")) GROUP BY table.string HAVING (((Count(*))>1))" 
wsP.BeginTrans 
dbS.Execute strSql, dbFailOnError 
lngRecs = dbS.RecordsAffected 
If Not lngRecs > 0 Then 
    GoTo nextIteration 
End If 
'Do whatever you like with lngRecs 
wsP.CommitTrans dbForceOSFlush 
+0

DCount не единственный раз, когда я использую tableCount. Например, позже в транзакции я создаю и запускаю запрос, который выбирает из таблицы, используя соединение с tableCount. Итак, вы видите, мне нужно ** records ** в tableCount перед совершением транзакции. Будет ли этот ответ помогать мне в этом? – MJH

+0

RecordsAffected предоставит вам количество записей. Поэтому вместо того, чтобы просто проверять, есть ли оно> 0, заполнить переменную с ним и делать все, что вам нравится. В чем проблема? – AVG

+0

Я не понимаю. Как узнать, сколько записей позволяет мне присоединиться к ним? Все, что я буду знать, это то, что ** есть разница (что помогает с dCount). Мне нужно получить доступ к ** данным ** непосредственно в записях, чтобы сделать соединение. – MJH

Смежные вопросы