AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Datenbanken Firebird: Datenmenge bei DML zurückliefern
Thema durchsuchen
Ansicht
Themen-Optionen

Firebird: Datenmenge bei DML zurückliefern

Ein Thema von Iwo Asnet · begonnen am 19. Aug 2011 · letzter Beitrag vom 19. Aug 2011
Antwort Antwort
Iwo Asnet

Registriert seit: 11. Jun 2011
313 Beiträge
 
#1

Firebird: Datenmenge bei DML zurückliefern

  Alt 19. Aug 2011, 09:44
Datenbank: Firebird • Version: 2.1 • Zugriff über: IB-Komponenten
Hi,

Ich möchte einen Skriptgenerator basteln, der aus einem Memory-Dataset SQL-Code generiert.
Wenn ein neuer Datensatz im InMemory-Dataset erzeugt wird, bekommt dieser vorläufig einen PK < 0, genauergesagt eine eindeutige ID (<0). Gelöschte Datensätze werden in einer Liste vermerkt und Änderungen an Feldinhalten auch.

Wenn ich die Änderungen in die SQL-Datenbank einpflegen will, dann gehe ich durch das Dataset und füge die Records ein, deren PK negativ ist und erzeuge UPDATE bzw DELETE Anweisungen für die veränderten bzw. gelöschten Datensätze. Vernachlässigen wir die Änderungen, die sind ohne Probleme machbar.

Beim Einfügen treffe ich auf das bekannte Problem, das die neu generierten AutoInc-Werte wieder zurück in das In-memory Dataset geschrieben werden müssen (ich muss ja nach Speicherung den vorläufigen negativen PK mit dem aktuellen Wert überschreiben).

Bei direktem Ändern ist das kein Problem, denn ich kann ein Skript à la
insert into TABELLE (FELD) values ('FOO') returning PKFeldName; in einem TIBQuery ausführen und dann via TheQuery.Field[0] den neuen Wert auslesen und den vormals negativen PK mit dem aktuellen Wert aus der DB überschreiben (Natürlich ist da ein ON INSERT - Trigger mit Generator dahinter).

Die Ausführung ist also:
1. Gehe durch das Dataset
2. Wenn Dataset[PK]<0 dann
2.1 führe insert into TABELLE (FELD) values ('FOO') returning PKFeldName; aus.
2.2. schreibe das Ergebnis zurück in "Dataset[PK]"

Nun möchte ich die Ausführung jedoch verändern:
1. Skript für alle veränderten/eingefügten/gelöschten Records generieren
2. Skript ausführen
3. Neue PK 'auf einmal' in das In-Memory Dataset einflegen.

Um das zu erreichen muss das Skript eine Tabelle erstellen, die für jedes vorläufige negative PK den dann erzeugten Wert enthält.

Beispiel;
Im InMemory-Dataset sind zwei Zeilen eingefügt, deren vorläufiger PK ist -1 und -2.
Nehmen wir an, die DB wird für die beiden neuen Records die PK 10 und 11 erzeugen, dann soll mein Skript folgendes Dataset zurück liefern:
Code:
Key | ID
-1  | 10
-2  | 11
Dann kann ich anschließend mein InMemory-Dataset entsprechend überarbeiten, sodaß dann das InMemory-Dataset die neu vergebenen PK-Inhalte enthält und somit eine 1:1 Abbildung der Original-Tabelle ist, OHNE das ich die Daten neu laden muss.

Frage:
Wie müsste so ein Skript aussehen. Ich skizziere mal, wie ich das machen würde
SQL-Code:
-- Statischer Teil: Präambel
create temporary table _PK (Key int, ID int);
declare variable newPK int;

-- Update code für InMemory- record mit vorläufiger ID -1
insert into TABELLE (FELD) values ('FOO') returning PKFeldName into :newPK;
insert into _PK (-1,:newPK);
-- Update code für InMemory- record mit vorläufiger ID -2
insert into TABELLE (FELD) values ('BAR') returning PKFeldName into :newPK;
insert into _PK (-2,:newPK);

-- Statischer Teil: Postambel
select * from _PK;
drop table _PK;
Wie würde o.g. Skript für Firebird richtig aussehen?
Kann man auf das Anlegen einer temporären Tabelle verzichten?
  Mit Zitat antworten Zitat
Iwo Asnet

Registriert seit: 11. Jun 2011
313 Beiträge
 
#2

AW: Firebird: Datenmenge bei DML zurückliefern

  Alt 19. Aug 2011, 10:47
Habe es nun selbst herausbekommen
SQL-Code:
-- Statischer Teil: Präambel
execute block returns (oldID int, newID int)
as begin
-- Dieser Code wird für jede eingefügte Zeile erzeugt
  insert into MyTable (Field) values ('Foo') returning MyTablePK into :newID;
  oldID = -1;
  suspend;

  insert into MyTable (Field) values ('Bar') returning MyTablePK into :newID;
  oldID = -2;
  suspend;
-- Statischer Teil: Postambel
end;
Genial einfach!
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 17:05 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz