Autor |
Beitrag |
SmileySN
      
Beiträge: 297
WinXP, Win7
Delphi 2010 Professional
|
Verfasst: So 18.06.06 19:59
Es kann doch nicht so schwer seine, einen neuen Datensatz anzulegen, oder doch ?
Ich benutze Firebird 1.5 und die Zeos Komponenten.
In meiner DB habe ich die Tabelle Firma mit der PK ID.
Dazu einen Generator und einen Trigger der auf Insert reagiert.
Wenn ich jetzt einen neuen Datensatz anlegen will mache ich das folgendermassen:
Delphi-Quelltext 1: 2: 3: 4:
| DM.QFirma.SQL.Clear; DM.QFirma.SQL.Add('Insert into Firma (Name,Strasse) Values (''NeuName'',''NeuStrasse'')'); DM.QFirma.ExecSQL; |
Mit diesem Insert Befehl sollte doch der Trigger anspringen und eine eindeutige ID vergeben.
Stattdessen bekomme ich die Meldung:
'no 2 Tables can have duplicate collumn values'
Kann mir mal jemand sagen wie man einen neuen Datensatz anlegt (leer nur mit ID reicht mir schon)
|
|
mkinzler
      
Beiträge: 4106
Erhaltene Danke: 13
Delphi 2010 Pro; Delphi.Prism 2011 pro
|
Verfasst: So 18.06.06 20:02
Welchen wert hat der dazugehörige Generator?
_________________ Markus Kinzler.
|
|
SmileySN 
      
Beiträge: 297
WinXP, Win7
Delphi 2010 Professional
|
Verfasst: So 18.06.06 20:11
Der Generator hat zur Zeit den Wert 13 und das ist auch die ID meines letzten Datensatzes.
|
|
mkinzler
      
Beiträge: 4106
Erhaltene Danke: 13
Delphi 2010 Pro; Delphi.Prism 2011 pro
|
Verfasst: So 18.06.06 20:14
Der Generator enthält aber den Wert des nächsten Datensatzes erhöhe den Generator, dann sollte es klappen.
_________________ Markus Kinzler.
|
|
SmileySN 
      
Beiträge: 297
WinXP, Win7
Delphi 2010 Professional
|
Verfasst: So 18.06.06 20:21
Ok, das hab ich jetzt auch entdeckt, nachdem Du danach gefragt hast, hab den letzten datensatz gelöscht, dann geht es.
War ein Fehler beim Generatorwert.
Jetzt sagt er mir, dass er den Feldnamen 'Name' nicht finden kann, das ist aber eindeutig der Name des Feldes für den Firmennamen. was soll das jetzt ?
|
|
SmileySN 
      
Beiträge: 297
WinXP, Win7
Delphi 2010 Professional
|
Verfasst: So 18.06.06 20:24
Der neue Datensatz wird auch mit den eingetragenen Werten 'Neuname' und NeueStrasse' angelegt
|
|
mkinzler
      
Beiträge: 4106
Erhaltene Danke: 13
Delphi 2010 Pro; Delphi.Prism 2011 pro
|
Verfasst: So 18.06.06 20:24
Welchen Namen hat das Feld; 'Name', 'NAME', 'name'?
_________________ Markus Kinzler.
|
|
SmileySN 
      
Beiträge: 297
WinXP, Win7
Delphi 2010 Professional
|
Verfasst: So 18.06.06 20:36
In der Datenbank sind alle Felder groß geschrieben es heißt hier also 'NAME', das hab ich dann probiert indem ich geschrieben habe:
Delphi-Quelltext 1: 2: 3:
| DM.QFirma.SQL.Clear; DM.QFirma.SQL.Add('Insert into Firma (NAME,STRASSE) Values (''NeuName'',''NeuStrasse'')'); DM.QFirma.ExecSQL; |
Er bringt mir aber noch den gleichen Fehler.
QFirma: Das Feld 'Name' wurde nicht gefunden
|
|
mkinzler
      
Beiträge: 4106
Erhaltene Danke: 13
Delphi 2010 Pro; Delphi.Prism 2011 pro
|
Verfasst: So 18.06.06 20:40
Ich vermutete eher das es wirklich Name heißt, dann hätte man den feldname Quoten müssen.
Post mal die Metadaten der Tabelle.
Welche Komponenten verwendest du?
_________________ Markus Kinzler.
|
|
SmileySN 
      
Beiträge: 297
WinXP, Win7
Delphi 2010 Professional
|
Verfasst: So 18.06.06 20:40
Jetzt bin ich etwas weiter, es passiert in der darauffolgenden Procedure DatenlesenFirma;
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17:
| procedure DatenLesenFirma; begin Form1.EdFirmaName.text := DM.QFirma.FieldByName('NAME').AsString; Form1.EdFirmaStrasse.Text := DM.QFirma.FieldByName('STRASSE').AsString; Form1.EdFirmaPLZ.Text := DM.QFirma.FieldByName('PLZ').AsString; Form1.EdFirmaOrt.Text := DM.QFirma.FieldByName('Ort').AsString; Form1.EdFirmaTel.Text := DM.QFirma.FieldByName('Tel').AsString; Form1.EdFirmaMail.Text := DM.QFirma.FieldByName('Mail').AsString; Form1.EdFirmaWeb.Text := DM.QFirma.FieldByName('Web').AsString; Form1.EdFirmaStatus.Text := DM.QFirma.FieldByName('Status').AsString; Form1.EdFirmaGruendung.Text := DM.QFirma.FieldByName('Gruendung').AsString; Form1.EdFirmaLiq.Text := DM.QFirma.FieldByName('Liq').AsString; Form1.EdFirmaInfo.Text := DM.QFirma.FieldByName('Memo').AsString; AktFirmaID := DM.QFirma.FieldByName('FirmaID').AsInteger; Form1.EdFirmaID.Text := DM.QFirma.FieldByName('FirmaID').AsString; SpracheLaden(AktSprache); end; |
|
|
mkinzler
      
Beiträge: 4106
Erhaltene Danke: 13
Delphi 2010 Pro; Delphi.Prism 2011 pro
|
Verfasst: So 18.06.06 20:42
Dann ist es ja klar, win DDL-Query hat keine Felder.
_________________ Markus Kinzler.
|
|
SmileySN 
      
Beiträge: 297
WinXP, Win7
Delphi 2010 Professional
|
Verfasst: So 18.06.06 20:45
Kann es sein, dass die Query QFirma nicht mehr richtig geöffnet ist nach dem ExecSQL-Befehl ?
Hier mal die definition aus der Datenbank:
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85:
| /******************************************************************************/ /*** Generated by IBExpert 18.06.2006 20:43:06 ***/ /******************************************************************************/
SET SQL DIALECT 3;
SET NAMES NONE;
/******************************************************************************/ /*** Tables ***/ /******************************************************************************/
CREATE GENERATOR GEN_FIRMA_ID;
CREATE TABLE FIRMA ( FIRMAID INTEGER NOT NULL, NAME VARCHAR(40), STRASSE VARCHAR(40), PLZ VARCHAR(10), ORT VARCHAR(40), TEL VARCHAR(40), MAIL VARCHAR(40), WEB VARCHAR(40), STATUS VARCHAR(20), GRUENDUNG DATE, LIQ DATE, MEMO BLOB SUB_TYPE 2 SEGMENT SIZE 16384 );
/******************************************************************************/ /*** Primary Keys ***/ /******************************************************************************/
ALTER TABLE FIRMA ADD CONSTRAINT PK_FIRMA PRIMARY KEY (FIRMAID);
/******************************************************************************/ /*** Indices ***/ /******************************************************************************/
CREATE INDEX IDX_FIRMA_NAME ON FIRMA (NAME);
/******************************************************************************/ /*** Triggers ***/ /******************************************************************************/
SET TERM ^ ;
/******************************************************************************/ /*** Triggers for tables ***/ /******************************************************************************/
/* Trigger: FIRMA_BI */ CREATE TRIGGER FIRMA_BI FOR FIRMA ACTIVE BEFORE INSERT POSITION 0 AS BEGIN IF (NEW.FIRMAID IS NULL) THEN NEW.FIRMAID = GEN_ID(GEN_FIRMA_ID,1); END ^
SET TERM ; ^
/******************************************************************************/ /*** Privileges ***/ /******************************************************************************/
/* Privileges of users */ GRANT ALL ON FIRMA TO DBUSER; |
|
|
mkinzler
      
Beiträge: 4106
Erhaltene Danke: 13
Delphi 2010 Pro; Delphi.Prism 2011 pro
|
Verfasst: So 18.06.06 20:51
.ExecSQL liefert keinen Cursor. Ich würde in deinem Fall 2 Queries nehmen, Abfrage und DML getrennt.
_________________ Markus Kinzler.
|
|
SmileySN 
      
Beiträge: 297
WinXP, Win7
Delphi 2010 Professional
|
Verfasst: So 18.06.06 20:52
Zitat: | Dann ist es ja klar, win DDL-Query hat keine Felder. |
Das sagt mir jetzt nichts ?????
|
|
mkinzler
      
Beiträge: 4106
Erhaltene Danke: 13
Delphi 2010 Pro; Delphi.Prism 2011 pro
|
Verfasst: So 18.06.06 20:55
Eine Abfrage mit Select liefert ein Cursor mit feldern auf dene man mit .FieldByName o.ö. zugreifen kann, eine DML-Abfrage nicht; nach dem .ExecSQL ist der Query geschlössen.
_________________ Markus Kinzler.
|
|
SmileySN 
      
Beiträge: 297
WinXP, Win7
Delphi 2010 Professional
|
Verfasst: So 18.06.06 20:56
Das hat sich jetzt etwas überschnitten.
Ich kann natürlich auch ein zweites Query für das Insert anlegen, aber wie wird es denn normalerweise gemacht.
Ich muss nach dem INSERT ja die Daten wieder am Bildschirm anzeigen lassen damit der Benutzer die Änderungen sieht.
Ist es wirklich so aufwendig ? Oder gehe ich hier einfach nur einen komplizierten Weg ??
|
|
mkinzler
      
Beiträge: 4106
Erhaltene Danke: 13
Delphi 2010 Pro; Delphi.Prism 2011 pro
|
Verfasst: So 18.06.06 21:00
Du kannst natürlich nur einen Query nehmen, ist aber dann nicht optimal, weil du ständig die Abfrage ändern mußt. Besser sind 2. Wobei nach dem Insert ein refresh auf den select-Query gemacht werden muß.
_________________ Markus Kinzler.
|
|
SmileySN 
      
Beiträge: 297
WinXP, Win7
Delphi 2010 Professional
|
Verfasst: So 18.06.06 21:02
Ich kann auch einfach ein neues Select machen, nur brauche ich dazu die Datensatznummer des neuen Datensatzes und den kann ich ja noch nicht ansprechen.
Oder ich muss auf den letzten Datensatz springen und mir dort die ID holen.
|
|
SmileySN 
      
Beiträge: 297
WinXP, Win7
Delphi 2010 Professional
|
Verfasst: So 18.06.06 21:19
Jetzt bin ich wieder an dem alten Problem mit der ID lesen.
Den letzten Datensatz lesen ist auch nicht so sicher, da könnte ein anderer User ja auch gerade einen Datensatz neu angelegt haben. Dann bekomme ich seinen Datensatz und nicht meinen gerade eingefügten.
Lässt sich das Problem doch nur mit einer StoredProcedure lösen ?
|
|
mkinzler
      
Beiträge: 4106
Erhaltene Danke: 13
Delphi 2010 Pro; Delphi.Prism 2011 pro
|
Verfasst: So 18.06.06 21:26
Ja, anstatt des Triggers. In der SP dann zuerst den Generator ermitteln/erhöhen, dann insert inkl ID, ID zurückgeben.
_________________ Markus Kinzler.
|
|