![]() |
Datenbank: Firebird • Version: 2.5 • Zugriff über: IBQUERY
In einer Existierenden Firebird Table ein feld ergänzen
Hallo
Also meine Idee ist ich möchte schauen ob meine SQl Tabellen auch alle Felder haben Da hatte ich folgende Idee Ich schreibe einen Funktion mit folgendem Inhalt
Code:
So nun kommt beim SQL Monitor folgendes
Function tsqldbform.Checkdatab_field(Tabelle:TIBQuery;Tabname:String;Feldname:String;feldtyp:String;Feldsize:integer;notwendig:Boolean):Boolean;
var _feldtyp :tfieldtype; sqlbastel : String; Begin if Feldtyp = 'Integer' then _feldtyp := ftInteger; if Feldtyp = 'String' then _feldtyp := ftString; if Feldtyp = 'Boolean' then _feldtyp := ftBoolean; if Feldtyp = 'TimeStamp' then _feldtyp := ftdatetime; if Feldtyp = 'Unbekannt' then _feldtyp := ftunknown; if Feldtyp = 'Float' then _feldtyp := ftfloat ; // Das ist meine neue Check routine aber hat ja nix mit dem Fehler zu tun if Tabelle.FindField(Feldname)=nil then begin Showmessage('Feld nicht vorhanden !'); end; try // schauen nach dem Typ des Feldes mit dem Feldnamen Feldname if tabelle.FieldDefs.Find(Feldname).DataType = _feldtyp then Result := true; Except on EDatabaseError do Begin // Das Datenbankfeld neu erzeugen showmessage('Datenbank Feld:'+Feldname + ' nicht vorhanden ! / Wird erzeugt ! '); tabelle.FieldDefs.Add(Feldname,_feldtyp,feldsize,notwendig); sqlbastel := 'alter table ' + Trim(Tabname) + ' add ' + Trim(Feldname) + ' ' + Trim(Feldtyp); Tabelle.SQL.Text := sqlbastel; // Hier kommt dann der Fehler ! :-( Tabelle.ExecSQL; // TAbelle.SQL.Clear; ibmaintransaction.CommitRetaining; end; 00:06:05 | [Application: test ] testtabelle: [Execute] alter table TEST add FELD4 Integer 00:06:05 | [Application: test ] [Error] -607 335544351 unsuccessful metadata update STORE RDB$RELATION_FIELDS failed Ich gehe davon aus das der SQl String stimmt a sieht er hier gut aus und wenn ich ihn in interbase Konsole eingebe dann geht er auch ! Aber was ist falsch ... das ich die Prüfung auf exist des Feldes besser machen kann ist mir bekannt. Aber daran liegt es ja nicht Kann mir jemand helfen ? :roll: :? |
AW: In einer Existierenden Firebird Table ein feld ergänzen
Zuerst: Firebird kennt kein STRING (VARCHAR wäre die Entsprechung) und kein Boolean (INTEGER mit 0 und 1 oder ein CHAR mit 'T' und 'F' als Ersatz).
Zum Anderen: warum wählst du IBQuery? IBScript wäre eigentlich für sowas die richtige Wahl. Es kann sein, dass du sowohl den Tabellennamen als auch den Feldnamen in Double-Quotes (") bei DDL aufführen musst (Achtung: auf korrekte Schreibweise groß/klein achten). Bin ich auch schon mal drauf reingefallen. Ansonsten solltest du eine DDL Anweisung mit einem Semikolon abschließen (oder was sonst als Terminierungszeichen definiert ist). Grüße Mikhal |
AW: In einer Existierenden Firebird Table ein feld ergänzen
Ich tippe mal darauf, dass der Fehler kommt, weil hier bei einer verm. geöffneten Abfrage der SQL.Text geändert wird.
Stimmt das mit dem Delphi 2 ??? |
AW: In einer Existierenden Firebird Table ein feld ergänzen
Zitat:
|
AW: In einer Existierenden Firebird Table ein feld ergänzen
Wieso wird Feldtyp eigentlich als String übergeben und dann nach TFieldType geparsed? Wäre es anders herum nicht sinniger?
|
AW: In einer Existierenden Firebird Table ein feld ergänzen
Um eine Tabelle zu erweitern würde ich direkt auf die Struktur-Informationen zugreifen.
Diese sollten auf bei Firebird in einer System-Tabelle abgelegt sein. Findet man das Feld dort nicht, dann per Script die Änderung an die Datenbank schicken. Jetzt muss man alle Tabellen und Queries die diese Tabelle referenzieren einmal neu laden. (Worst Case: Close - Open) Zitat:
Sinnigerweise sollte man diese Umwandlung aber in einer eigenen Funktion erledigen. |
AW: In einer Existierenden Firebird Table ein feld ergänzen
Welche Informationen wo wie vorliegen ist mir in diesem Zusammenhang wumpe, IMO sollte die Übergabe als TFieldType erfolgen (zur Not eben, wie Du schon sagst, vorher umwandeln). Aber so wie jetzt ist die ganze Sache unnötig fehleranfällig.
|
AW: In einer Existierenden Firebird Table ein feld ergänzen
Hallo
erst mal DANKE ! Also das mit dem parsen das wird ausgelagert kommt wie richtig vermutet aus einem anderen Script. Probiert habe ich das mit einem Integer was in den Filteyp Integer richtig gewandelt wird. Eigentlich wäre mir lieber ich bastle den SQL String zusammen und los geht es.. Der Tip mit dem Script jepp das werde ich mal angehen das query war nur Hilfsweise aber jepp nicht das richtige ;-) Das mit den Hochkommas habe ich probiert aber wie man an dem SQL Monitor sieht wurde der String ja richtig übergeben und verstanden... Ich denke wirklich das wie Sir Rufo vermutet, da wird einfach was sein, was in dem Moment nicht erlaubt das Feld zu ergänzen ... Ich versuche das mal mit ibScript ..Das ibQuery war in dem Moment aber auch nur für das genutzt. Das mit dem Zugriff direkt auf die Strukturtabelle ... das muss ich mir erst mal anschauen... Lieber wäre mir ein ganz normaler SQL String ;-) Das mit dem Case sensitive das ist auch finde ich eine komische Sache, manchmal ist das bei der Datenbank so das es tatsächlich case sensitive ist und manchmal nicht. Ich schreibe jetzt einfach alles groß.. :roll: Da hat aber anscheinend die "ibconsole" auch so ihre Probleme damit... P.s. das mit dem Feldtyp hat sich dann auch erledigt wenn ich meine andere Prüfroutine nutze denn wenn ich ein Feld habe stelle ich sicher das es auch der richtige Typ ist somit brauche ich das nicht testen. mich hatte am Test eh nur interessiert ob es eine exception gibt damit ich weiß das Feld ist nicht da ... |
AW: In einer Existierenden Firebird Table ein feld ergänzen
Ich würde das ganze möglichst vereinfachen. Da man ja seine Datenbank kennt, prüft man auf das Feld was man ergänzt hat etwa so:
Delphi-Quellcode:
Die Idee, das mit einer allgemeinen Funktion zu machen ist aber grundsätzlich gut. Man muss dabei dann aber auch an die verschiedenen Datentypen (VarChar, Numeric, Blob) die weitere Parameter brauchen denken oder noch besser diese als Domains anlegen.
IBSQLUpdate.close; //IBSQL
IBSQLUpdate.SQL.Add('Select * from TabelleA'); if not ibsqlupdate.transaction.active then ibsqlupdate.transaction.starttransaction; IBSQLUpdate.ExecQuery; bfiliale:= dm.IBSQLUpdate.FieldIndex['filiale']>=0 ; //bfiliale:boolean IBSQLUpdate.Close; if not filiale then begin dm.IBSQLUpdate.Close; dm.ibsqlupdate.SQL.Clear; dm.IBSQLUpdate.SQL.Add('ALTER TABLE TabelleA Add Filiale integer'); moddatabase; // Führt die Query aus mit Transaktionssteuerung end; |
AW: In einer Existierenden Firebird Table ein feld ergänzen
Also ich habe das ganze nun auf Script umgestellt aber das gleiche Problem. Muss ich dabei alle anderen Query und tables abmelden Close machen ?
Ja ich denke mit einer extra function kann ich im Fall eines Updates einfach ein Prüfscript mitgeben und dann wird die Datenbank aktuell ... Ich kann aber das script auch genauso in der Console ausführen und es geht ... ich verstehe das nicht. Script oder query kein unterschied ... :cry: Jetzt kommt 20:30:46 | [Application: Test] : [Start transaction] 20:30:46 | [Application: Test] : [Execute] alter table TEST add FELD4 Integer 20:30:46 | [Application: Test] [Error] -607 335544351 unsuccessful metadata update STORE RDB$RELATION_FIELDS failed 20:30:46 | [Application: Test] : [Rollback]
Delphi-Quellcode:
warum kann das Script was ja richtig ankommt nicht ausgeführt werden ?
Function tsqldbform.Checkdatab_field(Tabelle:TIBQuery;Tabname:String;Feldname:String;feldtyp:String;Feldsize:integer;notwendig:Boolean):Boolean;
var _feldtyp :tfieldtype; sqlbastel : String; Begin // schauen ob das Datenfeld existiert if Tabelle.FindField(Feldname)=nil then begin // Showmessage('Feld nicht vorhanden !'); showmessage('Datenbank Feld:'+Feldname + ' nicht vorhanden ! / Wird erzeugt ! '); sqlbastel := 'alter table ' + Trim(Tabname) + ' add ' + Trim(Feldname) + ' ' + Trim(Feldtyp) +';'; ibscript1.Script.Text := sqlbastel; // Tabelle.SQL.add(sqlbastel); ibscript1.ExecuteScript; // Open ; // ExecSQL; // SQL.BeginUpdate; // ibscript1.Script.Clear; // SQL.Clear; ibmaintransaction.CommitRetaining; showmessage(ibscript1.script.text ); end; end; das muss irgend einen Grund haben. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 20:49 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz