Announcement

Collapse
No announcement yet.

Zugriffsverletzung bei Adresse ... im Modul msado15.dll

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Zugriffsverletzung bei Adresse ... im Modul msado15.dll

    System: Win2000, D5 SP1, ADOExp SP2
    Hallo,<br>
    folgendes Problem:<br>
    Bei Ausführen folgenden Codes, kommt obige Fehlermeldung.<br>
    if ADOQ_Std.Active then ADOQ_Std.Close;<br>
    ADOQ_Std.sql.clear;<br>
    ADOQ_Std.sql.add('update global set fill_delta = :a');<br>
    if BO_REM then<br>
    ADOQ_Std.Parameters[0].value := 'T'<br>
    else<br>
    ADOQ_Std.Parameters[0].value := 'F';<br>
    ADOQ_Std.ExecSQL;<br>
    <br>
    Ich habe ein größeres Projekt nun von der BDE auf ADO umgestellt.<br>
    Wer kann mir sagen, worin dieser Fehler begründet ist, bzw. wie ich<br> ihn beheben kann?<br>
    Jedesmal, wenn ich TADOQuery.ExecSQL aufrufe, bekomme ich diese Meldung.
    <br>
    Gruß,<br>
    Christian

  • #2
    Hallo,

    hinter ADO Express (TADOQuery, TADODataSet etc.) verbergen sich nur VCL-Wrapperkomponenten für die nativen COM-Objekte von ADO (Connection, Command und Recordset). Dies bedeutet, dass ADO Express nur dann funktioniert, wenn man sich an die von Microsoft vorgeschriebenen Spielregeln hält. Im Falle einer parametisierten SQL-Anweisung bedeutet dies, dass das eingebundene Command-Objekt seine Parameters-Kollektion füllen muss, <b>bevor</b> die SQL-Anweisung ausgeführt wird. Im Fall des nativen Zugriffs sieht das zum Beispiel so aus:
    <pre>
    var
    aCon : _Connection;
    aCommand : _Command;
    vRows : OleVariant;
    iCnt : Integer;
    begin
    aCon := CoConnection.Create;
    aCon.CursorLocation := adUseClient;
    aCon.Open(cCS, '', '', adConnectUnspecified);
    try
    aCommand := CoCommand.Create;
    try
    with aCommand do begin
    CommandType := adCmdText;
    CommandText := 'INSERT INTO CommandTbl (Nr,Wert) ' +
    'VALUES (?,?)';
    Parameters.Append(CreateParameter('Nr', adInteger,
    adParamInput, 4, EmptyParam));
    Parameters.Append(CreateParameter('Wert', adVarChar,
    adParamInput, 10, EmptyParam));
    Set_ActiveConnection(aCon);
    for iCnt := 1 to 100 do begin
    Parameters[0].Value := iCnt;
    Parameters[1].Value := 'Nr. ' + IntToStr(iCnt);
    Execute(vRows, EmptyParam, adExecuteNoRecords);
    end;
    end;
    finally
    aCommand := nil;
    end;
    finally
    aCon.Close;
    aCon := nil;
    end;
    end;
    </pre>
    Hinter TADOQuery verbirgt sich nur eine Kompatibilitäts-Komponente (die man daher nur im Notfall verwenden sollte), normalerweise ist <b>TADODataSet</b> die erste und einzige Wahl.

    Da TADOQuery (ADO Express) direkt auf das darunterliegende Command-Objekt von ADO zugreift, muss "jemand" die Parameters-Kollektion vom Command-Objekt füllen. Und dies passiert bei ADO Express nur dann automatisch, wenn im <i>Objektinspektor</i> zur <b>Entwicklungszeit</b> der kleine Button in der Eigenschaft <b>Parameters</b> angeklickt wird.

    Es ist daher am Besten, generell nur feststehende SQLs vorzusehen, die dann im Objektinspektor permanent konfiguriert werden. Wenn sehr viele SQLs notwendig sind, macht es Sinn, die Komponenten auf mehrere Datenmodul-Instanzen auszulagern, die vom Programm erst bei Bedarf erzeugt/zerstört werden. Dieser Weg ist effektiver als der Aufruf der Parameters-Methode Refresh.

    P.S: Die Details und Hintergründe sind in meinem Buch <i>ADO und Delphi</i> nachzulesen

    Comment


    • #3
      Danke erstmal für die prompte Antwort!<br>
      <br>
      Es über den nativen Weg zu machen leuchtet mir ein. Jedoch fehlt mir dafür die Zeit. Wenn ich meinen Code von Oben in ein leeres Projekt einfüge und dort dann ausführe, funktioniert das wunderbar, sobald es jedoch im eigentlichen Projekt genutzt werden soll, dann dieser Fehler.<br>

      P.S: Ich kenne Ihr Buch und halte es für sehr hilfreich, jedoch muss ich aus Zeitgründen auf den nativen Weg verzichten

      Comment


      • #4
        Hallo,

        &gt;..leeres Projekt einfüge und dort dann ausführe..

        das Problem besteht darin, die SQLs und somit die Parameter-Auflistung für ein <b>bereits einmal ausgeführtes</B> Command-Objekt <b>nachträglich</b> in ADO Express zu ändern, ohne das Command-Objekt neu aufzubauen. Wenn man bei den bequemen ADO Express-Komponenten bleiben will, muss man für jede SQL eine eigene Komponenten-Instanz vorsehen und fest im Objektinspektor konfigurieren. Nur dann darf man davon ausgehen, dass ADO Express (Komponente) und ADO (Command-Objektinstanz) immer synchron bleiben

        Comment

        Working...
        X