EINFÜGEN WÄHLEN Sie im Firebird
Ich bin neu in firebird und ich habe verious Probleme. Ich will an insert-mehrere Zeilen in eine Tabelle ausgewählt aus einer anderen Tabelle.
Hier der code:
/*CREATE GENERATOR POS; */
SET GENERATOR POS TO 1;
SET TERM ^;
create trigger BAS_pkassign
for MATERIAL
active before insert position 66
EXECUTE BLOCK
AS
declare posid bigint;
select gen_id(POS, 1)
from RDB$DATABASE
into :posid;
BEGIN
END
SET TERM ; ^
INSERT INTO MATERIAL ( /*ID */ LOCATION, POSID, ARTID, ARTIDCONT, QUANTITY )
SELECT 1000, ':posid', 309, BAS_ART.ID, 1
FROM BAS_ART
WHERE BAS_ART.ARTCATEGORY LIKE '%MyWord%'
Die ID sollte autoincrement von 66 auf. Die posid sollten autoincrement-aus 1.
Eigentlich ist es nicht einfügen alles.
Ich bin mit Firebird Maestro und gerade eröffnet das SQL-Skript-Editor (was aber nicht werfen eine Fehlermeldung auf das Skript ausgeführt wird).
Kann mir keiner helfen?
Dank!
Zusätzliche Informationen:
Den trigger sollte die autoincrement-Spalte "ID" - aber ich weiß nicht wie genau ich das ändern kann, damit es funktioniert..': posid' wirft einen Fehler, die es verwenden :posid aber so gibt es keinen Fehler (ich denke, es ist umgesetzt als string). Aber wie verwende ich es richtig?
Ich bekomme kein Fehler, wenn ich es ausführen. Die Struktur der Tabelle ist einfach. Ich habe 2 Tabellen:
1.
Material (
ID (INTEGER),
Location (INTEGER),
POSID (INTEGER),
ARTID (INTEGER),
ARTIDCONT (INTEGER),
QUANTITY (INTEGER),
OTHERCOLUMN (INTEGER))
und die 2. andere Tabelle
BAS_ART (ID (INTEGER), ARTCATEGORY (VARCHAR255))
-> ich einfügen wollen, die alle Einträge aus der Tabelle BAS_ART, die enthalten "MyWord" in der Spalte ARTCATEGORY in der MATERIAL-Tabelle.
':posid'
ist kein Gültiger Wert für die Spalte POSID
. Sie können aber auch jeden Fehler erhalten Sie, wenn Sie diese ausführen, und beschreiben Sie bitte die Struktur der Tabelle und was Sie wirklich erreichen wollenDer trigger sollte die autoincrement-Spalte "ID" - aber ich weiß nicht wie genau ich das ändern kann, damit es funktioniert..': posid' wirft einen Fehler, die es verwenden :posid aber so gibt es keinen Fehler (ich denke, es ist umgesetzt als string). Aber wie verwende ich es richtig?
Ich bekomme kein Fehler, wenn ich es ausführen. Die Struktur der Tabelle ist einfach. Ich habe 2 Tabellen: 1. Material (ID, Lage, POSID, ARTID, ARTIDCONT, MENGE, OTHERCOLUMN) und die 2. andere Tabelle BAS_ART (ID, ARTCATEGORY) -> ich einfügen wollen, die alle Einträge aus der Tabelle BAS_ART, die enthalten "MyWord" in der MATERIAL-Tabelle. @MarkRotteveel
Bitte, dass die Art der Informationen, die in Ihrer Frage und enthalten den Datentypen, das ist besser lesbar, als in den Kommentaren!
Es ist mir unklar, was
POSID
ist, und warum sollte es generiert alle.InformationsquelleAutor number5 | 2014-01-14
Du musst angemeldet sein, um einen Kommentar abzugeben.
Ich verstehe nicht, warum Sie benötigen, um die trigger überhaupt.
Dieses problem:
Gelöst werden kann mit einem einzigen
insert ... select
- Anweisung.Dies setzt Voraus, dass es eine zweite Sequenz (auch bekannt als "generator"), die mit dem Namen
seq_mat_id
bietet die neue id für die Spaltematerial.id
id
Spalte. Beachten Sie, dass die Einlage in Ihrer Antwort weist immer1000
dieser Spalte statt derlocation
Spalte, wie in der Frage.ja ich bin mir bewusst, über die der Konstante Wert für
material.id
Aber so funktioniert das Beispielinsert ... select in the question
also bin ich davon ausgegangen, dass das, was die Absicht ist. Aber es wäre sehr einfach, füllen Sie diese Spalte aus einer Sequenz als gut.In der Frage der
ID
Spalte ist auskommentiert, aber jetzt bin ich einfach nur pingelig 😉ah! Ich habe irgendwie verpasst, dass.
Danke sehr, der nächste Wert, was zusammen mit einer Sequenz gearbeitet. Ich habe nicht brauchen einen trigger an alle. Sie hatten Recht. Sie vergaß die ARTIDCONT Spalte, aber ich klebte es und dann war es perfekt funktioniert. Jetzt auf jeder ausführen ich l0ok mit der aktuellen ID und legen Sie es in
RESTART WITH <id>
. Möglicherweise gibt es eine einfachere Lösung mit einem trigger, aber es funktioniert.InformationsquelleAutor a_horse_with_no_name
Für die meisten meiner Antwort gehe ich davon aus eine sehr einfache Tabelle:
Auto-increment-id
Firebird (bis version 2.5) nicht eine identity-Spalte type (dieser wird in Firebird 3), sondern Sie brauchen, um eine Sequenz zu verwenden (auch bekannt als generator) und einen Auslöser, um dieses zu erhalten.
Sequenz
Müssen Sie zuerst erstellen Sie eine Sequenz mit
CREATE SEQUENCE
:Einer Sequenz ist atomar, was bedeutet interleaving Transaktionen/Anschlüsse erhalten keine doppelten Werte, es ist auch außerhalb der Transaktion die Kontrolle, was bedeutet, dass ein
ROLLBACK
wird nicht wieder auf den vorherigen Wert. In den meisten verwendet Sequenzen sollten immer zu erhöhen, so wird der Wert zurückgesetzt, den Sie tun, zu Beginn Ihrer Frage ist falsch für fast alle Zwecke; zum Beispiel eine andere Verbindung könnte zurücksetzen der Sequenz als auch midway in Ihrer Ausführung, so dass Sie mit ungewollten Duplikate derPOSID
.Trigger
Generieren einen Wert für ein auto-increment-id, die Sie benötigen, um ein
BEFORE INSERT TRIGGER
, weist einen generierten Wert, der - in diesem Beispiel -ID
Spalte.In diesem Beispiel habe ich immer weisen einen generierten Wert, andere Beispiele weisen einen generierten Wert nur, wenn der
ID
istNULL
.Immer den Wert
Um den erzeugten Wert, den Sie verwenden können, die
GIBT
-Klausel derINSERT
-Anweisung:INSERT INTO ... SELECT
Mit
INSERT INTO ... SELECT
können Sie Zeilen aus einer Tabelle und fügen Sie Sie in andere. Der Grund, warum es nicht funktioniert für Sie ist, weil Sie versuchen, zuweisen der string-Wert':pos'
auf eine Spalte des TypsINTEGER
, und das ist nicht erlaubt.Vorausgesetzt, ich habe eine andere Tabelle
MyOtherTable
mit einer ähnlichen Struktur wieMyTable
ich kann Werte übertragen mit:Mit
INSERT INTO ... SELECT
es ist nicht möglich, um die erzeugten Werte nur, wenn nur eine einzige Zeile eingefügt wurde.Vermutungen hinsichtlich
POSID
Es ist mir nicht klar, was
POSID
sein soll, und welche Werte sollte es haben. Es sieht aus wie Sie wollen, haben einen steigenden Wert, beginnend mit 1 für einen einzelnenINSERT INTO ... SELECT
. In Versionen von Firebird bis 2,5, das ist nicht möglich in dieser Art und Weise (in Firebird 3 Sie würden in der Lage sein zu verwendenROW_NUMBER()
).Wenn meine Vermutung richtig ist, dann benötigen Sie eine
EXECUTE BLOCK
(oder eine gespeicherte Prozedur) zugeordnet und erhöhen Sie den Wert für jede Zeile eingefügt werden.Die execute-block wäre so etwas wie:
Ohne
ORDER BY
mit derSELECT
den Wert von posid ist im Grunde bedeutungslos, weil es keine garantierte Reihenfolge.InformationsquelleAutor Mark Rotteveel