Execução de consultas usando DAO
Pergunta
eu quero executar uma lista de consultas contra um banco de dados Access usando DAO. O "Database.Execute ()" método parece adequado para isso com a observação de que ele só pode executar "consultas ação", isto é consultas que não retornam um conjunto de resultados ( MSDN referência ). Para consultas que retornam registros "Database.OpenRecordset ()" pode ser usado. Ambos os métodos lançar exceções se o tipo errado de consulta é passada.
Tendo ambas as consultas ação e selecione consultas na lista como posso decidir antecipadamente que irá retornar registros e que não vai?
Solução 3
Inspirado pela resposta da @ HansUp eu investiguei um pouco mais a estrutura QueryDef fornecido pela interface DAO. A estrutura tem um "tipo" propriedade que eu possa usar para diferenciar entre diferentes tipos de consulta ( MSDN ). Eu acabei com a seguinte implementação:
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;
Obrigado a todos pelas respostas úteis e observações.
Outras dicas
Note que o ADO método de execução pode ser usado independentemente de haver ou não a consulta retorna um conjunto de resultados.
Mas você realmente deseja executar todas as 'consultas'? E se eles contêm SQL DDL? Considere que você criou um PROCEDURE
usando este código SQL DDL:
CREATE PROCEDURE qryDropMe AS DROP PROCEDURE qryDropMe;
;)
Acesso mantém uma tabela de sistema oculto chamado MSysObjects que inclui um campo (Flags), que armazena um valor que indica o tipo de consulta. Você poderia tentar a seguinte função com cada um dos nomes de consulta da sua lista e usar o valor de retorno para determinar se deve usar Database.Execute () ou Database.OpenRecordset ()
A função requer permissão de leitura para MSysObjects. Ouvi relatos de alguns usuários Acesso 2007 é negado permissão para ler MSysObjects. No entanto, eu não encontrei esse problema com o Access 2007.
Eu testei vários tipos de consulta para determinar os valores Bandeiras. Se uma das suas consultas é um tipo eu não fiz teste, a função retornará o valor Flags como despercebidas. Você pode modificar a função para incluir esse tipo Flags.
O único DDL consulta que foi testado TABELA GOTA (bandeiras = 96).
Além disso, esteja ciente de que nem todos os "SELECT ... FROM ..." consultas são consultas seleção para o seu propósito (retornando um conjunto de registros). A consulta, como "SELECT campos INTO newtable DE OldTable;" não retorna registros, e as classifica Acesso UI-lo como uma consulta criar tabela.
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
Por que você não pegar a exceção lançada e analisá-lo?
Você tem alguma maneira de usar uma instrução BeginTrans / reversão? Você pode então enviar o comando SQL, recolher os erros, em seguida, reverter as suas transacções, tendo seu banco de dados alterados.
Que tal usar conexão ADO, um pouco mais inteligente do que o ADO, onde a conexão segurar uma coleção e retorna 'erros' alguns outros dados, como número de registros afetados?
Esta informação aplica-se ao tipo de consulta. Assim:
- Todas as consultas que executam um SELECT ... FROM ... é selecione consultas
- Todos Inserir , Atualização , Excluir é ação consultas
Você apenas tem que inspecionar o texto de comando consulta SQL para olhar se ele começa com qualquer uma das palavras-chave acima e agir em conformidade.