Выполнение запросов с использованием DAO
Вопрос
Я хочу выполнить список запросов к базе данных Access, используя DAO.Метод «Database.Execute()» кажется подходящим для этого с замечанием, что он может выполнять только «запросы действий», то есть запросы, которые не возвращают набор результатов (Справочник MSDN).Для запросов, возвращающих записи, можно использовать «Database.OpenRecordset()».Оба метода генерируют исключения, если передается неправильный тип запроса.
Имея в списке как запросы действий, так и запросы выбора, как я могу заранее решить, какие записи будут возвращать, а какие нет?
Решение 3
Вдохновленный ответом @ HansUp, я немного больше изучил структуру QueryDef, предоставляемую интерфейсом DAO. Структура имеет тип "Тип" свойство, которое я могу использовать для различения различных типов запросов ( MSDN ) , Я закончил со следующей реализацией:
function TAccessDatabase.SQLExec(AName, AQuery: String): Integer;
var
I: Integer;
QDef: QueryDef;
QDefExists: Boolean;
begin
Result := 0;
// Lookup querydef in the database
QDefExists := False;
for I := 0 to DB.QueryDefs.Count - 1 do
begin
QDef := DB.QueryDefs[I];
if QDef.Name = AName then
begin
QDefExists := True;
break; //-->
end;
end;
// Create query def if it doesn't exists
if not QDefExists then
begin
QDef := DB.CreateQueryDef(AName, AQuery);
// Refresh is required to get the correct QDef.Type_
DB.QueryDefs.Refresh;
end;
// Execute the query only if it is not a SELECT
if QDef.Type_ <> dbQSelect then
begin
db.Execute(AQuery, dbInconsistent);
Result := DB.RecordsAffected;
end;
end;
Спасибо всем за полезные ответы и замечания.
Другие советы
Обратите внимание, что метод ADO Execute можно использовать независимо от того, возвращает ли запрос набор результатов.
Но действительно ли вы хотите выполнить все «запросы»?Что, если они содержат SQL DDL?Предположим, вы создали PROCEDURE
используя этот код SQL DDL:
CREATE PROCEDURE qryDropMe AS DROP PROCEDURE qryDropMe;
;)
Access поддерживает скрытую системную таблицу MSysObjects, которая включает в себя поле (Flags), в котором хранится значение, указывающее тип запроса. Вы можете попробовать следующую функцию с каждым из имен запросов из вашего списка и использовать возвращаемое значение, чтобы определить, использовать ли Database.Execute () или Database.OpenRecordset ()
Функция требует разрешения на чтение для MSysObjects. Я слышал сообщения о том, что некоторым пользователям Access 2007 отказано в разрешении читать MSysObjects. Однако я не сталкивался с этой проблемой в Access 2007.
Я протестировал несколько типов запросов, чтобы определить значения флагов. Если один из ваших запросов относится к типу, который я не проверял, функция вернет значение Flags как нераспознанное. Вы можете изменить функцию для включения этого типа флагов.
Единственным протестированным DDL-запросом был DROP TABLE (Flags = 96).
Также учтите, что не все " SELECT ... FROM ... " запросы - это выборочные запросы для вашей цели (возвращение набора записей). Запрос, такой как " SELECT fields INTO newtable FROM oldtable; " не возвращает записи, и пользовательский интерфейс Access классифицирует его как запрос Make Table.
Public Function QueryType(ByVal pQueryName As String) As String
Dim lngFlags As Long
Dim strType As String
Dim strCriteria As String
strCriteria = "[Name] = """ & pQueryName & """ And [Type] = 5"
lngFlags = DLookup("Flags", "MSysObjects", strCriteria)
Select Case lngFlags
Case 0
strType = "Select"
Case 16
strType = "Crosstab"
Case 32
strType = "Delete"
Case 48
strType = "Update"
Case 64
strType = "Append"
Case 80
strType = "Make Table"
Case 96
strType = "Drop Table"
Case 128
strType = "Union"
Case Else
strType = "Flags " & CStr(lngFlags) & " unrecognized"
End Select
QueryType = strType
End Function
Почему бы вам не поймать выброшенное исключение и не проанализировать его? Р>
У вас есть какой-нибудь способ использовать инструкцию beginTrans / Rollback? Затем вы можете отправить свою команду SQL, собрать ошибки, а затем откатить транзакции, оставив базу данных без изменений.
Как насчет использования соединения ADO, несколько умнее, чем соединение ADO, где соединение содержит коллекцию «ошибок» и возвращает некоторые другие данные, например количество затронутых записей?
Эта информация относится к типу запроса.Так:
- Все запросы, выполняющие ВЫБИРАТЬ ...ОТ ... являются выбрать запросы
- Все ВСТАВЛЯТЬ, ОБНОВЛЯТЬ, УДАЛИТЬ являются запросы действий
Вам просто нужно проверить текст команды sql-запроса, чтобы посмотреть, начинается ли он с любого из приведенных выше ключевых слов, и действовать соответствующим образом.