Hallo Zusammen,
ich habe ein spezielles Problem:
Eine Datenbank mit sog. Stammdaten;
Weitere Datenbanken die auf die Stammdaten verweisen.
Die Synchronisierung ist nicht das Problem.
Ich habe bisher neue Datensätze von außerhalb der Datenbanken eingefügt.
Nun soll eine Procedure dies tun.
Klappt auch gut; nur wenn ich den Insert-String als Eingabeparameter übergebe erhalte ich Fehlermeldung = Column unknown für die Daten die ebenfalls als Eingabeparameter übergeben werden. Das Mapping (Values :a, :b, :c) (a := :eingabeparama, b := :eingabeparamb, c := :eingabeparamc) wird als Eingabeparameter ignoriert. Auch Versuche dies in Hochkommas oder Anführungszeichen zu stellen haben nicht funktioniert. Der Eingabeparameter für den Datenbanknamen funktioniert.
Hier der Auszug:
RECREATE PROCEDURE SP_KOMM_NEU (
AAGSNAME VARCHAR(20),
AADRID INTEGER,
AAGSART INTEGER,
AGREMKENNUNG INTEGER,
AMITSD BOOLEAN,
AZUSATZDB VARCHAR(20),
AINSERTSTRING VARCHAR(250),
APARAMSTRING VARCHAR(100))
RETURNS (
AKOMMID INTEGER)
AS
BEGIN
/* Procedure text */
/* Daten in eine Tabelle der Datenbank */
insert into TABELLE
(felda, feldb, feldc, feldd)
values (:aagsname, :aadrid, :aagsart, :agremkennung)
returning ags_id into :akommid;
if (:amitsd) then
begin
/* Daten in eine Tabelle einer fremden Datenbank */
execute statement ('insert into tabelle (felda, feldb, feldc)
values (:a, :b, :c)') (a := :aagsname, b := :akommid, c := :aagsart)
with autonomous transaction
on external data source (:azusatzdb)
with caller privileges;
end
suspend;
END^
Wenn ich die Zeile execute Statement
ersetze durch: execute Statement (:ainsertstring) (:aparamstring)
ergibt die Fehlermeldungen. Auch der Versuch, beides in einen Eingabeparamter zu packen hat nicht funktioniert.
Im Programmcode sind Konstanten eingerichtet:
cstrinsert = 'insert into tabelle(felda, feldb, feldc) ' +
'values (:a, :b, :c)';
cstrparam = 'a := :aagsname, b := :akommid, c := :aagsart';
Viellicht hat jemand eine Idee dazu?
Vielen Dank schon mal.
Daten in andere Datenbank einfügen
Moderator: martin.koeditz
Hallo,
ich mache so etwas immer mit z.B. folgender Procedure.
execute statement('insert into xy_tabelle(STATUS_ID, COMMAND_ID, TYPE_ID, LINK_ID, COMMAND_TEXT)
values ( :STATUS_ID, :COMMAND_ID, :TYPE_ID, :LINK_ID,:COMMAND_TEXT)')
(STATUS_ID := STATUS_ID, COMMAND_ID := COMMAND_ID, TYPE_ID := TYPE_ID, LINK_ID := LINK_ID, COMMAND_TEXT := :COMMAND_TEXT)
on external data source CONNECTIONSTRING
as user USERNAME password password ;
Vielleicht hilft Ihnen das.
ich mache so etwas immer mit z.B. folgender Procedure.
execute statement('insert into xy_tabelle(STATUS_ID, COMMAND_ID, TYPE_ID, LINK_ID, COMMAND_TEXT)
values ( :STATUS_ID, :COMMAND_ID, :TYPE_ID, :LINK_ID,:COMMAND_TEXT)')
(STATUS_ID := STATUS_ID, COMMAND_ID := COMMAND_ID, TYPE_ID := TYPE_ID, LINK_ID := LINK_ID, COMMAND_TEXT := :COMMAND_TEXT)
on external data source CONNECTIONSTRING
as user USERNAME password password ;
Vielleicht hilft Ihnen das.
Leider ist das Ganze nicht volldynamisch.
Entweder du musst den gesamten Insert immer wieder neu zusammenbasteln, also auch die Parameter oder du musst die Parameter neutral benennen und auf eine gewisse Anzahl beschränken.
https://firebirdsql.org/rlsnotesh/rnfb2 ... stmnt.html
An dem Beispiel siehst du das Vorgehen:
S = 'INSERT INTO TTT VALUES (:a, :b, :a)';
EXECUTE STATEMENT (:S) (a := CURRENT_TRANSACTION, b := CURRENT_CONNECTION)
Wie du siehst, je Parameter ist eine eigene Variable zu übergben.
Da du ja jede Variable kennst, kannst du den Insert auch entsprechend zusammen bauen.
Aber wie sicher bist du, dass du nur einen Insert zu einer Zeit durchführst?
Oder generierst du je Tabelle eine Prozedur?
Und warum überhaupt eine Prozedur da dies die Sache ja komplizierter macht und das Ganze dann auch länger dauert (jeder Insert muss erst mal auf Syntax geprüft werden)?
Da du ja sowieso jede Variable kennen must hast du keinen Vorteil.
Entweder du musst den gesamten Insert immer wieder neu zusammenbasteln, also auch die Parameter oder du musst die Parameter neutral benennen und auf eine gewisse Anzahl beschränken.
https://firebirdsql.org/rlsnotesh/rnfb2 ... stmnt.html
An dem Beispiel siehst du das Vorgehen:
S = 'INSERT INTO TTT VALUES (:a, :b, :a)';
EXECUTE STATEMENT (:S) (a := CURRENT_TRANSACTION, b := CURRENT_CONNECTION)
Wie du siehst, je Parameter ist eine eigene Variable zu übergben.
Da du ja jede Variable kennst, kannst du den Insert auch entsprechend zusammen bauen.
Aber wie sicher bist du, dass du nur einen Insert zu einer Zeit durchführst?
Oder generierst du je Tabelle eine Prozedur?
Und warum überhaupt eine Prozedur da dies die Sache ja komplizierter macht und das Ganze dann auch länger dauert (jeder Insert muss erst mal auf Syntax geprüft werden)?
Da du ja sowieso jede Variable kennen must hast du keinen Vorteil.
-
- Beiträge: 2
- Registriert: Mo 6. Aug 2018, 11:56
Hallo Leute,
vielen Dank für die Hilfe.
@bfuerchau:
wie Du aus dem Prozedur-Text ersehen kannst, gehe ich nach Beschreibung vor, solange der Insert-String im Prozedur-Text steht. Das gleiche tue ich auch wenn ich den String als variable übergebe. Was dann nicht funktioniert.
Aber man ist ja manchmal etwas vernagelt: Beim Zusammenstellen des Insert-Strings kann man natürlich die Daten direkt übergeben.
Übrigens gibt es für jede Tabelle auf die verwiesen wird, eine solche Prozedur.
Mir geht es dabei um die Datenkonsistenz: Gibt es einen Fehler bei der Übergabe der Daten an die externe Datenbank, wird die gesamte Prozedur "zurück-gerollt". Dies ist innerhalb der Datenbank (Server) wesentlich einfacher zu implementieren als von außerhalb.
Und nochmals vielen Dank für Eure Hilfe.
vielen Dank für die Hilfe.
@bfuerchau:
wie Du aus dem Prozedur-Text ersehen kannst, gehe ich nach Beschreibung vor, solange der Insert-String im Prozedur-Text steht. Das gleiche tue ich auch wenn ich den String als variable übergebe. Was dann nicht funktioniert.
Aber man ist ja manchmal etwas vernagelt: Beim Zusammenstellen des Insert-Strings kann man natürlich die Daten direkt übergeben.
Übrigens gibt es für jede Tabelle auf die verwiesen wird, eine solche Prozedur.
Mir geht es dabei um die Datenkonsistenz: Gibt es einen Fehler bei der Übergabe der Daten an die externe Datenbank, wird die gesamte Prozedur "zurück-gerollt". Dies ist innerhalb der Datenbank (Server) wesentlich einfacher zu implementieren als von außerhalb.
Und nochmals vielen Dank für Eure Hilfe.
Denke jedoch beim direkten Zusammenbauen an die benötigte Verdoppelung von ggf. enthaltenen Hochkommatas.
Wenn du allerdings sowieso je Tabelle eine Prozedur baust, warum kannst du den Code nicht mit einzelnen Parametern erstellen an Stelle nun alle Werte in Strings zu casten und zusammen zu bauen?
Du definierst doch alle deine Variaben als Parameter, also gib diese doch alle an, so wie im Beispiel des Vorredners.
Wenn du allerdings sowieso je Tabelle eine Prozedur baust, warum kannst du den Code nicht mit einzelnen Parametern erstellen an Stelle nun alle Werte in Strings zu casten und zusammen zu bauen?
Du definierst doch alle deine Variaben als Parameter, also gib diese doch alle an, so wie im Beispiel des Vorredners.