Frage

Ich möchte eine Liste von Abfragen für eine Access-Datenbank auszuführen, mit DAO. Die „Database.Execute ()“ Methode für diesen mit der Bemerkung geeignet scheint, dass es nur „Aktionsabfragen“ ausführen kann, dh Abfragen, die ( MSDN Referenz ). Bei Abfragen, die Datensätze „Database.OpenRecordset ()“ zurückkehren können verwendet werden. Beiden Methoden werfen Ausnahmen, wenn die falsche Art der Abfrage übergeben wird.

Mit beiden Aktionsabfragen und Auswahlabfragen in der Liste, wie kann ich im Voraus entscheiden, welche Datensätze angezeigt werden können und welche nicht?

War es hilfreich?

Lösung 3

Inspiriert von @ HansUp Antwort suchte ich ein bisschen mehr die QueryDef Struktur durch die DAO-Schnittstelle zur Verfügung gestellt. Die Struktur hat eine Eigenschaft „Type“, die ich verwenden kann zwischen verschiedenen Abfragetypen ( MSDN ). Ich landete mit der folgenden Umsetzung:

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;

Vielen Dank für die hilfreichen Antworten und Bemerkungen.

Andere Tipps

Beachten Sie, dass die Methode ADO ausführen, unabhängig davon verwendet werden kann, ob die Abfrage eine Ergebnismenge zurückgibt.

Aber tun Sie wirklich alle ‚Abfragen‘ ausgeführt werden soll? Was passiert, wenn sie SQL DDL enthalten? Betrachten Sie eine PROCEDURE mit diesem SQL-DDL-Code erstellt:

CREATE PROCEDURE qryDropMe AS DROP PROCEDURE qryDropMe;

;)

Access verwaltet eine versteckte Systemtabelle MSysObjects genannt, die ein Feld (Flags) enthält, die einen Wert speichert, die den Abfragetyp. Sie könnten die folgende Funktion mit jedem der Abfrage-Namen aus der Liste versuchen und den Rückgabewert verwenden, um festzustellen, ob Database.Execute () verwenden oder Database.OpenRecordset ()

Die Funktion Erlaubnis für MSysObjects lesen erfordert. Ich habe gehört, Berichte als einige Access 2007-Benutzer die Erlaubnis verweigert werden MSysObjects zu lesen. Allerdings habe ich dieses Problem nicht mit Access aufgetreten 2007.

Ich testete mehrere Abfragetypen, die Flags Werte zu bestimmen. Wenn einer Ihrer Anfragen ein Typ habe ich nicht testen, wird die Funktion den Wert Flags als unerkannt zurück. Sie können die Funktion ändern, um enthalten, dass Flags geben.

Die einzige DDL-Abfrage I getestet wurde DROP TABLE (Flags = 96).

Auch bitte beachten Sie, dass nicht alle „SELECT ... FROM ...“ Abfragen sind SELECT-Abfragen für Ihre Zwecke (ein Re-Cord zurückkehrt). Eine Abfrage wie "SELECT Felder INTO newtable VON OldTable;" nicht Datensätze zurück, und der Access-UI stuft es als Make Table-Abfrage.

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

Warum Sie die Ausnahme nicht fangen geworfen und analysieren?

Haben Sie eine Möglichkeit haben, eine Begintran / Rollback-Befehl zu benutzen? Sie könnten dann Ihren SQL-Befehl senden, um die Fehler sammeln, dann Ihre Transaktionen zurück, unverändert Datenbank verlassen zu müssen.

Was ist ADO-Verbindung verwenden, etwas schlauer als der ADO ein, wo die Verbindung ein ‚Fehler‘ Sammlung halten und gibt einige andere Daten, wie Anzahl der Datensätze betroffen?

Diese Informationen gelten für die Art der Abfrage. Also:

  • Alle Abfragen, die ein SELECT ... FROM ... sind select Abfragen
  • execute
  • Alle INSERT UPDATE Löschen sind Aktion Abfragen

Sie müssen nur die Abfrage SQL-Befehl Text untersuchen, um zu sehen, ob es mit einer der oben genannten Keywords beginnt und entsprechend handeln.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top