ich versuche es nochmals, ich komme einfach nicht weiter. Ich verwende in
meiner Delphi 5 Anwendung ADO, um mich mit einem SQL-Server 2000 zu
verwenden. Die Tabellen sind miteinander verlinkt. Alles funktioniert super,
jetzt muß ich aber Oracle 9i unterstützen. Das Problem ist, dass ich
umgehend Fehlermeldungen bekomme, sobald ich die Oracle Datenbank öffne.
Egal was vorhanden ist (TAutoInc, TIntegerField, TBoolean usw.), Oracle gibt
immer nur einen Float zurück; liegt wohl an "EnableBCD". Aktiviere ich
jedoch "BCD", dann kommt nur BCD zurück. Egal was ich mache, es kommt
entweder BCD oder Float. Ich habe es schon mit SQL-Direct versucht, habe
aber dort auch Probleme mit.
Mache ich da etwas grundsätzlich falsch? Ich verstehe die Probleme einfach
nicht :(
Gruß
Paul Meyer schrieb:
> [...] Das Problem ist, dass ich umgehend Fehlermeldungen bekomme, sobald
> ich die Oracle Datenbank öffne. Egal was vorhanden ist (TAutoInc,
> TIntegerField, TBoolean usw.), Oracle gibt immer nur einen Float zurück;
> [...]
>
> Mache ich da etwas grundsätzlich falsch? Ich verstehe die Probleme einfach
> nicht :(
Die Probleme liegen darin begründet, dass Oracle weder AutoInc, Integer noch
Boolean etc. kennt.
Robert
> Egal was vorhanden ist (TAutoInc, TIntegerField, TBoolean usw.), Oracle gibt
> immer nur einen Float zurück; liegt wohl an "EnableBCD". Aktiviere ich
> jedoch "BCD", dann kommt nur BCD zurück. Egal was ich mache, es kommt
> entweder BCD oder Float.
Und wo genau hat Deine Anwendung ein Problem damit?
Die einzige tragfähige Lösung besteht meiner Erfahrung nach darin seine
Anwendung in der Hinsicht toleranter zu machen und das geht in den meisten
Fällen auch sehr leicht.
Wesentlicher Teil der Lösung ist der vollständige Verzicht auf persistente
Felder. Im Angesicht sich potentiell ändernder Datenstrukturen sowieso eine
gute Idee.
Ciao, MM
--
Marian Aldenhövel, Rosenhain 23, 53123 Bonn
http://www.marian-aldenhoevel.de
"Success is the happy feeling you get between the time you
do something and the time you tell a woman what you did."
> Die Probleme liegen darin begründet, dass Oracle weder AutoInc, Integer
> noch Boolean etc. kennt.
Oracle kennt kein Boolean? Nur Float? Was ist das für ein sch...ß? Im Ernst,
ich kann mir nicht so recht vorstellen, dass Delphi nicht mit Oracle
klarkommt. Laut Historie wurde Delphi für Oracle gemacht (zumindest was
Datenbanken betrifft) und nun soll das nicht funktionieren?
Würde ich ja gerne, aber wenn ein Boolean erwartet wird, sollte Oracle doch
auch einen liefern. Komplett auf persistente Felder zu verzichten ist vom
Kompfort her absolut unpraktisch; da geht doch fast der gesamte Vorteil der
IDE verloren ... Ich kann es mir nicht so recht vorstellen, ich denke,
irgendwo mache ich etwas falsch.
Paul Meyer schrieb:
> Oracle kennt kein Boolean?
Jep.
http://download-uk.oracle.com/docs/cd/B10501_01/server.920/a96524/c13datyp.htm
> Nur Float?
Das habe ich nicht gesagt.
> Im Ernst, ich kann mir nicht so recht vorstellen, dass Delphi nicht mit
> Oracle klarkommt. Laut Historie wurde Delphi für Oracle gemacht (zumindest
> was Datenbanken betrifft) und nun soll das nicht funktionieren?
Warum sollte das nicht funktionieren? Ich habe hier zig Anwendungen mit
Delphi realisiert, die ihre Daten auch in Oracle-Datenbanken speichern.
Robert
Paul Meyer schrieb:
> Würde ich ja gerne, aber wenn ein Boolean erwartet wird, sollte Oracle
> doch auch einen liefern. [...]
Oracle kann keinen Datentyp liefern, den es nicht kennt. Die Umwandlung oder
Interpretation obliegt Dir.
Robert
> Würde ich ja gerne, aber wenn ein Boolean erwartet wird, sollte Oracle doch
> auch einen liefern.
Preisfrage: Wie hast Du Oracle denn gesagt, daß das Feld ein Boolean sein
soll?
> Komplett auf persistente Felder zu verzichten ist vom Komfort her absolut
> unpraktisch; da geht doch fast der gesamte Vorteil der IDE verloren
Quatsch. Dann schreibt man ein paar Zeilen Code in einen OnAfterOpen-Handler.
Du kannst die entsprechenden Teile auch aus der DFM-Datei kopieren und
anpassen falls Du ein Migrationsproblem damit hast.
Persistente Felder machen auch unabhängig vom beschriebenen Problem Ärger.
Na es funktioniert doch nicht so einfach. Wenn ich mir die Historie
anschaue, dann wurde Delphi indirekt auch für Oracle gemacht. Da waren von
Anfang an Designer mit drin, also auch persistente Feld-Editoren. Wenn also
Feld-Editoren mit dabei waren und es für Oracle angepasst wurde, dann muß es
doch auch funktionieren. Das will mir nicht in den Kopf.
Paul Meyer schrieb:
> Na es funktioniert doch nicht so einfach. Wenn ich mir die Historie
> anschaue, dann wurde Delphi indirekt auch für Oracle gemacht. Da waren von
> Anfang an Designer mit drin, also auch persistente Feld-Editoren. Wenn
> also Feld-Editoren mit dabei waren und es für Oracle angepasst wurde, dann
> muß es doch auch funktionieren. Das will mir nicht in den Kopf.
Mal ganz abgesehen davon, dass es zu den Zeiten der ersten Delphi-Versionen
ADO nicht gab, funktioniert die Feldpersistenz doch auch einwandfrei mit den
nativen Datentypen von Oracle. Dass Delphi mehr Feldtypen kennt als Oracle
native Datentypen kann ja wohl nicht als Nachteil angesehen werden...
Mit entsprechenden (Event-)Methoden kannst Du ja auch die Darstellung der
Daten in der GUI von der nativen Speicherung in der Datenbank entkoppeln
(d.h. z.B. Ja/Nein wird dargestellt, aber 0/1 gespeichert).
Robert
Boolean gab es aber schon in Delphi 1, demnach muß es damals schon
irgendwann mal mit Oracle <> Delphi funktioniert haben.
Ich war's nicht, ich war's nicht :) Habe mit Hilfe des Migrationsassistenten
eine SQL-Server Datenbank importiert.
Paul Meyer schrieb:
> Boolean gab es aber schon in Delphi 1, demnach muß es damals schon
> irgendwann mal mit Oracle <> Delphi funktioniert haben.
Was sagt dass darüber aus, wie solche Informationen in Oracle gehandhabt
werden.
Lies bitte nochmals Roberts Äußerung:
| Dass Delphi mehr Feldtypen kennt als Oracle
| native Datentypen kann ja wohl nicht als Nachteil angesehen werden...
Paul ich kann Dir versichern, dass Deine 2 Gesprächspartner in diesem
Thread ihr Geschäft verstehen. Ja, auch das Duo Delphi/Oracle.
Vertraue ihnen!
Gruß, Joe
--
> Ich war's nicht, ich war's nicht :) Habe mit Hilfe des Migrationsassistenten
> eine SQL-Server Datenbank importiert.
Wie kannst Du dann behaupten, da wäre ein Boolean in Oracle? Schau Dir die
Datenstruktur doch erst mal an, die Dein Assi gebaut hat.
> Boolean gab es aber schon in Delphi 1, demnach muß es damals schon
> irgendwann mal mit Oracle <> Delphi funktioniert haben.
Daß es einen Typ TBooleanField gibt hat nichts mit Oracle zu tun.
Es obliegt der Datenbankschicht die nativen Typen auf die von Delphi zu
mappen. Es steht Dir frei eine zu schreiben, bzw. zu modifizieren, die
einen CHAR(1) zum Anlaß nimmt TBooleanFields zu erzeugen.
Das hilft Dir aber nicht. Ich bleibe dabei: Entferne die persistenten
Felder aus Deiner Anwendung, sie wird dabei wesentlich flexibler und das
Problem wird verschwinden.
Hinweis: AsBoolean ist keine Eigenschaft von TBooleanField.
Weiterer Hinweis: Es gibt kein Boolean in SQL-92.
AutoInc gibt es nicht in Oracle. Oracle verwendet da einen etwas anderen
Ansatz.
Sequences ist das Stichwort, das Du in der Dokumentation nachauen musst.
Integer gibt es in Oracle so auch nicht als Typ in Tabellen. Offenbar hat der
Migrationsassistent daraus NUMBER gemacht, was in Oracle maximal 38 Stellen
bedeutet, die dann von Delphi als Float abgebildet werden.
Boolean gibt as in Oracle ebenfalls nicht als Datentyp für Tabellenspalten.
Der Migrationsassistent hat hier wohl auch NUMBER draus gemacht.
Ansonsten solltest Du die Tabellenstruktur in Oracle mal mit Describe im
SQL*Plus ansehen. Ich habe so das Gefühl, der Assistent hat ziemlichen Müll
produziert.
>
Normalerweise verwendet man in Oracle statt Boolean char(1), evtl. noch mit
einer Constraint auf 'J'/'N', 'T'/'F' o.ä. eingeschränkt.
Man könnte auch ein Number(1) mit 1/0 als Werten verwenden. Soetwas hat wohl
auch der Assistent versucht aber offenbar mit wenig Erfolg.
Bei den Autoinc-Feldern musst Du datenbankseitig noch etwas tun, damit das
Verhalten in etwa dem des MSSQL-Servers entspricht.
Eine Option sind hier Before-Insert-Trigger, die einen neuen Wert aus der
Sequence besorgen. Hierzu kann ich bei bedarf etwas mehr schreiben.
Die Integerfelder, oder das, was daraus geworden ist, kannst Du ggf. mit
alter table in number(9) umwandeln, wenn die Tabelle leer ist.
Aus Number(9) sollte Delphi dann wieder ein TIntegerField machen, spätestens
aus Number(8). Hier könnte es aber Probleme mit den bereits abgelegten
Werten geben, wenn die nicht in Number(8) passen.
Und tschüss,
Lothar
--
Lothar Armbrüster | lothar.ar...@t-online.de
Hauptstr. 26 |
65346 Eltville |
Die wenigsten DBs kennen Boolean. Daher sollte man diesen Datentyp auch
nicht benutzen.
Delphi kommt ansosnten wunderbar mit allen Oracle-Datentypen klar, sogar
Ref-Cursor gehen.
--
Stefan Graf
> ich versuche es nochmals, ich komme einfach nicht weiter. Ich verwende in
> meiner Delphi 5 Anwendung ADO, um mich mit einem SQL-Server 2000 zu
> verwenden. Die Tabellen sind miteinander verlinkt. Alles funktioniert super,
> jetzt muß ich aber Oracle 9i unterstützen. Das Problem ist, dass ich
> umgehend Fehlermeldungen bekomme, sobald ich die Oracle Datenbank öffne.
> Egal was vorhanden ist (TAutoInc, TIntegerField, TBoolean usw.), Oracle gibt
> immer nur einen Float zurück;
eine Anwendung zuschreiben die unterschiedliche DBs unterstützt wird
schnell zur Herausforderung (insbesondere bei so unterschiedlichen DBs
wie Oracle und MS-SQL-Server). Einfach einen anderen
ADO-Connection-String zuverwenden wird die Aufgabe in den wenigsten
Fällen lösen.
Hier ist strategisches Vorgehen gefragt. Ich würde dabei 2
Haupt-Richtungen unterscheiden:
1. Wenn deine Anwendung nur ein leicht überschaubares Datenmodel
verwendet, Perfomance nur eine untergeordnete Rolle spielt und du die
Kontrolle über den Aufbau und die Struktur der Datenbank hast, dann
kannst du versuchen die DBs und dein SQL-Anweisungen so aufzubauen das
sie kompatible sind. In deinem Fall würde das z.B. unter anderem
bedeuten keine TAutoInc-, TBoolean-Felder zu verwenden).
2. Ansonsten musst du für den Datenzugriff eine Zwischenschicht
einziehen. Die die Unterscheide der DBs für den Rest deiner Anwendung
unsichtbar macht.
Der 2. Weg erfordert meistens ein komplettes Redesign der Anwendung und
evt. sogar das loslösen von den bisher verwendetet Programmiertechniken.
Das geht vom Verzicht auf Persistentefelder (würde wahrscheinlich schon
Mal dazu führen das du dein Anwendung ohne Fehlermeldung starten kannst
:-) ) über die nicht Verwendung von Datensensitiven-Komponenten bis zur
Verwendung oder Entwicklung eine Persistensframeworks.
Der 1. Weg führt eh nur selten zum Ziel und auch wenn man damit
erfolgreich gestartet ist, kann eine weitere Anforderung an deine
Anwendung dein ganzes Konzept schnell zum einstürzen bringen.
Ich möchte noch einen 3. Weg aufzeigen, der aber das eigentliche Problem
nicht löst: Tu es nicht! Unterstütze keine verschiedenen DBs. Versuche
einen Weg aufzuzeigen wie man doch den MS-SQL-Server verwenden kann
(evt. die Daten zwischen Oracle und MSSQL-Server synchronisieren?). Lege
die Kosten für die Anpassungsarbeiten so hoch an, das es dich hüpfen
lässt falls er ja sagt (es ist nachher immer noch zu wenig). Wenn der
nutzen deiner Anwendung hoch genug ist, wird sich der Auftraggeber auf
so manches einlassen. Evt. stellt sich dann sogar heraus das Oracle nur
deswegen Bedingung war, weil der Auftraggeber auch was festlegen wollte. :-)
Ciao Heinz Z.
OK akzeptiert, dann hält sich Oracle hier an die Richtlinien. Ich war mir
nicht sicher, ob Boolean in SQL-92 definiert ist.
> Normalerweise verwendet man in Oracle statt Boolean char(1), evtl. noch
> mit
> einer Constraint auf 'J'/'N', 'T'/'F' o.ä. eingeschränkt.
> Man könnte auch ein Number(1) mit 1/0 als Werten verwenden. Soetwas hat
> wohl
> auch der Assistent versucht aber offenbar mit wenig Erfolg.
NUMBER(1) akzeptiert Delphi nicht als Boolean, aber CHAR(1). Superidee,
danke!!! Wenn ich nun noch wüßte, wie ich Delphi bzw die DB.PAS dazu
überrede, Zahl 0 als FALSE und 1 als TRUE zu akzeptieren, wäre ich
glücklich. TAutoInc habe ich automatisiert auf TVariant abgeändert, das
funktioniert auch. Sequenzen usw wurden vom Assistenten angelegt.
> Die Integerfelder, oder das, was daraus geworden ist, kannst Du ggf. mit
> alter table in number(9) umwandeln, wenn die Tabelle leer ist.
> Aus Number(9) sollte Delphi dann wieder ein TIntegerField machen,
> spätestens
> aus Number(8). Hier könnte es aber Probleme mit den bereits abgelegten
> Werten geben, wenn die nicht in Number(8) passen.
Funktioniert leider mit Delphi 5 nicht, aber Delphi 7 erkennt Integer. Warum
auch immer :(
Gruß, Paul