Announcement

Collapse
No announcement yet.

Transaktion

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

  • Transaktion

    Hallo zusammen,

    habe folgende Frage. Kann man innerhalb einer Transaktion eine Anweisung auf dem Server machen, welche igrenwie die bis zu diesem Punkt veränderten Daten in eine Temporärtabelle kopiert, die Temporätabelle aber nach einem evtl. Rollback aber noch mit den daten bleibt. Ich bräuchte dies für einen Probelauf, bei welchem ich die Daten zwar aufbereite, diese dann drucken möchte, und dann ein Rollback machen müsste, da ich die Daten natürlich nicht geändert zurückschreiben will.

    Bräuchte wenn es möglcih ist eine dringende Antwort.

    mfg

    Astner Klaus

  • #2
    Hallo,

    die Antwort hängt von der verwendeten Datenbank ab. Im Fall des MS SQL Server 2000 ist dies möglich

    Comment


    • #3
      Ich verwende MS SQLSRv 2000. Wie kann man da vorgehen

      Comment


      • #4
        Hallo,

        der MS SQL Server 2000 unterstützt die so genannten <i>Named Transactions</i>, die als Bookmarks (Lesezeichen) innerhalb einer T-SQL-Stapelanweisung verwendet werden:
        <pre>
        BEGIN TRAN TestMainTransaction
        ...
        SAVE TRAN TestBookmark1
        ...
        ROLLBACK TRAN TestBookmark1
        ...
        COMMIT TRAN
        </pre>
        Über <b>SAVE TRAN</b> wird ein Lesezeichen gesetzt, dessen einzelne Aktionen später zum Beispiel über <b>ROLLBACK TRAN</b> zurückgenommen werden können, um in der Fehlerbehandlung einen 2. Versuch zu starten. Der <b>COMMIT TRAN</b>-Aufruf bestätigt am Ende alle Änderungen (unabhgängig vom Bookmark).

        Beispiel-Datenbanktabelle:

        <pre>
        USE tempdb
        GO
        CREATE TABLE NESTEDTRANTEST (
        RecID INTEGER NOT NULL IDENTITY PRIMARY KEY,
        Wert VARCHAR(10))
        GO
        </pre>

        Aufruf über <b>ADO.NET</b> heraus:<br>
        Das T-SQL-Verhalten wird auch von der <br>SqlTransaction</b>-Klasse unterstützt, indem die Methoden <b>BeginTran</b> und <b>Rollback</b> überladen wurde und zusätzlich die Methoden <b>Save</b> zur Verfügung gestellt wird:
        <pre>Me.SqlConnection1.Open()
        Dim aTran As System.Data.SqlClient.SqlTransaction
        aTran = SqlConnection1.<b><font color="#FF0000">BeginTransaction</font></b>(IsolationLevel.ReadCommitted, &quot;TestMainTran&quot
        Dim aCmd As New System.Data.SqlClient.SqlCommand()
        <font color="#008000">' SqlCommand-Instanz muss immer die gleiche Transaktion nutzen </font>
        aCmd.Transaction = aTran
        <font color="#008000">' Testeintrag 1 wird in der &quot;Haupt-Transaktion&quot; eingetragen </font>
        aCmd.Connection = SqlConnection1
        aCmd.CommandText = &quot;INSERT INTO NESTEDTRANTEST (Wert) VALUES ('Test1')&quot;
        aCmd.ExecuteNonQuery()
        <font color="#008000">' Nach dem Testeintrag 1 wird ein Prüfpunkt gesetzt </font>
        aTran.<font color="#FF0000"><b>Save</b></font>(&quot;TestBookmark1&quot
        <font color="#008000">' Testeintrag 2 wird in der &quot;Neben-Transaktion&quot; eingetragen </font>
        aCmd.CommandText = &quot;INSERT INTO NESTEDTRANTEST (Wert) VALUES ('Test2')&quot;
        aCmd.ExecuteNonQuery()
        <font color="#008000">' Die &quot;Neben-Transaktion&quot; wird über Rollback zurückgenommen </font>
        aTran.<font color="#FF0000"><b>Rollback</b></font>(&quot;TestBookmark1&quot
        <font color="#008000">' Testeintrag 3 wird in der &quot;Haupt-Transaktion&quot; eingetragen </font>
        aCmd.CommandText = &quot;INSERT INTO NESTEDTRANTEST (Wert) VALUES ('Test3')&quot;
        aCmd.ExecuteNonQuery()
        <font color="#008000">' Commit auf alle offenen Vorgänge </font>
        aTran.<font color="#FF0000"><b>Commit</b></font>()
        Me.SqlConnection1.Close()
        </pre>
        &#10

        Comment


        • #5
          Ist dies auch mit Delphi 5 möglich, wenn man kein Ado.Net hat

          Comment


          • #6
            Hallo,

            nein, dieser Teil steht über den OLE DB-Provider nicht zur Verfügung. Microsoft liefert im .NET Framework die Klassen <b>SqlConnection</b> und <b>SqlTransaction</b> aus, die als "Spezialisten" nur mit dem MS SQL Server zusammenarbeiten und daher auch alles unterstützen. Hinter OLE DB steckt im Gegensatz dazu eine universell nutzbare Zwischenschicht (die von ACCESS bis zum SQL-Server verschiedener Bauart reicht), aber bei der nicht alle spezifischen Merkmale verfügbar sind.

            &gt; wenn man kein Ado.Net hat ?

            In diesem Fall würde ich mit Delphi 8 eine kleine Assembly (DLL) zusammenbauen, die dann von Delphi 5 eingebunden wird. Delphi 5 "sieht" diesen .NET-Teil nur als "ganz normale" Schnittstellenprozeduren einer DLL, d.h. Delphi 5 kann nicht erkennen, dass dieses Teil von Delphi 8 (.NET) kommt. Über diesen Weg können wir unsere alten/bewährten Anwendungen mit neuen Funktionen aufpolieren, ohne das Ganze in einem Schritt auf .NET umstellen zu müssen.

            Das Ganze könnte im Beispiel so aussehen:
            <pre>
            <b>library</b> UnmanagedExportBDELibrary;

            <font color="#003399"><i>{$UNSAFECODE ON}</i></font>

            <font color="#003399"><i>{%DelphiDotNetAssemblyCompiler 'c:\programme\gemeinsame dateien\borland shared\bds\shared assemblies\2.0\Borland.Delphi.dll'}</i></font>
            <font color="#003399"><i>{%DelphiDotNetAssemblyCompiler 'c:\programme\gemeinsame dateien\borland shared\bds\shared assemblies\2.0\Borland.Vcl.dll'}</i></font>

            <b>uses</b>
            SysUtils,
            Classes,
            System.Reflection,
            UnmanagedExportBDELibrary_DM <b>in</b> <font color="#9933CC">'UnmanagedExportBDELibrary_DM.pas' </font> <font color="#003399"><i>{DataModule1: TDataModule}</i></font>;

            [assembly: AssemblyTitle(<font color="#9933CC">'UnmanagedExportBDELibrary'</font>)]
            [assembly: AssemblyDescription(<font color="#9933CC">'VCL.NET Datenmodul nutzt BDE'</font>)]
            [assembly: AssemblyVersion(<font color="#9933CC">'1.0.0.0'</font>)]

            <b>function</b> GetDataFromBDE: Integer;
            <b>var</b>
            aDM : TDataModule1;
            <b>begin</b>
            aDM := TDataModule1.Create(<b>nil</b>);
            <b>try</b>
            aDM.TableCustomerDb.Active := True;
            Result := aDM.TableCustomerDb.RecordCount;
            <b>finally</b>
            aDM.TableCustomerDb.Active := False;
            aDM.Free;
            <b>end</b>;
            <b>end</b>;

            <b>exports</b>
            GetDataFromBDE;

            <b>begin</b>
            <b>end</b>.
            </pre>
            Das Delphi 5-Programm ruft diese DLL (alias .NET-Assembly) über den vertrauten Weg auf:
            <pre>
            <b>function</b> GetDataFromBDE: Integer; <b>external</b> <font color="#9933CC">'UnmanagedExportBDELibrary.dll'</font>;

            <b>procedure</b> TForm1.ButtonGetDataFromBDEClick(Sender: TObject);
            <b>begin</b>
            StatusBar1.SimpleText := IntToStr(GetDataFromBDE);
            <b>end</b>;
            </pre>

            Comment

            Working...
            X