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?

Foi útil?

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.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top