Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Delphi Crystal Reports XI + Delphi und unterschiedliche Datenbanken (https://www.delphipraxis.net/97094-crystal-reports-xi-delphi-und-unterschiedliche-datenbanken.html)

cytrinox 4. Aug 2007 14:33

Datenbank: alle von Zeos untersützten DB • Zugriff über: Zeos

Crystal Reports XI + Delphi und unterschiedliche Datenbanken
 
Hi,

ich hab ein recht kompliziertes Problem mit Crystal Reports und Delphi.

Wir haben eine recht große Applikation in Delphi (Win32) die intern die Zeos Komponenten benutzt. Sinn der Sache ist der, dass man momentan nur eine embedded Firebird Datenbank einbindet (für Einzeplplatz-Versionen) oder einen Firebird-Server (für Netzwerk-Versionen mit mehreren Clients). Später sollen dann MSSQL und Oracle dazukommen. D.h. Die Application ist so ausgelegt, dass man im Prinzip jede Datenbank, die Zeos untersüttzt, auch anbinden kann.

Im Programm drin gibt es ein Benutzersystem, hunderten von Zugriffsrechen usw. auf bestimmte Teile des Programms und damit auch auf die Datenbestände/Tabellen an sich.


Jetzt sollen mit Crystal Reports diese Daten ausgewertet werden. Das sind ca. 200 Auswertungen und Statistiken, die ich schon alle erstellt und die auch schon mit dem Programm zusammen ausgeliefert werden.

Dazu hab ich die Delphi Komponente für CRXI verwendet, da gibts TCrpe und TCrpeDS.

Und zwar hat man bei CR ja die Möglichkeit, über integrierte Treiber oder über ODBC, JDBC usw. eine Datenbank anzubinden. D.h. Crystal kann in dem Fall direkt mit der verbunden Datenbank über SQL kommunizieren.

In meinem Fall hab ich ja aber keine Ahnung welche Datenbank angebunden ist, zumal noch die Zugriffsgeschichte reinfällt.

D.h. ich hab für jede Tabelle ein *.ttx File angelegt, das die Feldgröße, Feldname usw. beinhaltet. Diese Dateien kann man als eine Felddefinitionsdatei in einen Report laden und kann damit auch einen kompletten Report erstellen.
Erst wenn der Report in einem Programm per TCrpe Komponente geladen wird, wird dynamisch die Datenquelle zugewiesen.

Dazu stellt die Crpe Komponente alle Tabellen, die in dem Report vorkommen, zu Verfügung, dann kann man einfach ein vorhandenes TDataSet damit per DataPointer damit verbinden.

Also hab ich z.B. eine Tabelle MY_DATA in dem Report defniert, muss ich zuerst eine ZQuery erstellen, ein "SELECT * FROM MY_DATA"; ausführen und das daraus resultierende Dataset in ein TCrpeDS Object packen. Dieses repräsentiert sozusagen die Datenquelle für den Report und diese kann ich nun der Tabelle die mir TCrpe ausgibt, zuweisen (tableByName('MY_DATA').DataPointer := myTcrpeDSobj).

Somit ist es für mich beim Report-Erstellen und auswerten völlig schnurz, welches DBMS dahinter steht, die Applikation gibt mir ja immer das passende Dataset zurück.

Manchen wird es schon aufgefallen sein: Wenn ich einen Report erstellen muss, der zwei Tabellen braucht die per INNER JOIN z.B. verknüpft werden bedeutet das in meinem Fall, dass ich zuerst ein SELECT * FROM tbl1 mache und das Dataset zuweise, dann ein SELECT * FROM tbl2 mache und das Dataset wiederum zuweise.

Crystal macht jetzt den INNER JOIN selbst aus den zwei Datasets die es bekommt. Bei 100000 x 10000 Datensätzen dauert das eine halbe Ewigkeit.
Das Problem liegt daran, dass Crystal - wenn es eine SQL fähige Datenbank hat - direkt einen SQL INNER JOIN Befehl zusammenbaut und den an die Datenbank schickt. Genau DAS ist hier nicht der Fall - es geht technisch einfach nicht.

Und genau hier muss ich jetzt ansetzen...

Es wird langsam untragbar, das eine Auswertung, die über SQL eigentlich 2-3 Sekunden braucht, bei unseren Kunden oft über 15-30 Minuten dauert.


Da ich nicht nur richtige Server anbinden muss, sondern auch eine embedded Firebird Datenbank habe, die schon durch das Programm geöffnet ist, fällt ein direkter Zugriff von CRXI auf die Datenbank weg - ganz zu schweigen von den ganzen Zugriffsrechen usw.

Ein Zugriff über diese *.ttx Files ist aber auch nicht tragbar wegen der Geschwindigkeit.

D.h. ich müsste eine Möglichkeit schaffen, dass CRXI direkt seine SQL Statements an die Applikation senden kann, diese an die Datenbank schickt und das Resultset wieder an Crystal gibt.

Daher wäre meine Idee:

Die Applikation bekommt eine Netzwerkschnittstelle verpasst, so dass ein zusätzlicher Thread auf Port 5678 hört.
Dann schreibe ich einen ODBC-Treiber, der sich auf diesen Port verbinden kann und entsprechende Statements an die Applikation weitergeben kann.

So kann ich in Crystal diesen ODBC Treiber einbinden und damit arbeiten, SQL Statements die CRXI an den ODBC Treiber sendet, landen über die TCP Verbindung in dem Thread der Applikation, hier wird das Statement an die Zeos Library weitergegeben und das Resultset über TCP an den ODBC Treiber zurückgeben.


Damit hätte ich alle Voraussetzungen:
+ Crystal hat eine (vorgetäuschte) SQL Datenbank
+ Statt 10 Statements bei 10 Tabellen die verknüpft werden müssen, wird nur noch ein SQL Statement erzeugt
+ die Datenbank übernimmt dei Datenverknüfung und CRXI muss das nicht mehr selbst machen.


So, zu dieser Vorgehensweise hätte ich ein paar Fragen:

1. Was halten die eingefleischten Datenbanktechniker hier von dieser Idee?
2. Hat jemand einen besseren Vorschlag?
3. Hat jemand mal einen ODBC Treiber entwickelt? ich hab mich damit mal etwas beschäftigt, sieht recht heftig aus, vor allem weil ich ja noch ein eigenes Protokoll entwickeln muss, das die Kommunikation zwischen ODBC Treiber und Applikation herstellt.
4. Sind ODBC Treiber überhaupt zu empfehlen? Irgendwo hab ich gelesen die sind veraltet - aber einen Ersatz hab ich noch nicht gefunden.
5. Angenommen ich habe eine embedded Firebird Datenbank, kann ich maximal eine ZConnection erstellen. ich hab aber die Applikation und meinen zusätlichen Thread für die TCP Verbindungen der die SQL Statements an die Datenbank schicken muss - geht das überhaupt? Ich müsste dann eine ZConnection über zwei Threads benutzen, soweit ich weiß sind die Dinger nicht threadsave - muss ich mir hier meine eigenen Locks einbauen?
6. Lässt sich per ODBC irgendwie die Syntax der generierten SQL Statements festlegen? Zum Beispiel versteht eine Oracle Datenbank nicht alles was Firebird versteht - und umgekehrt. Wie kann ich Crystal sagen wie das SQL Statement aufgebaut sein muss? Oder benötige ich da einen Wrapper im der Applikation die mir den SQL String analysiert und auf die gerade aktive Datenbank umschreibt? -> Gibt es dafür schon Komponenten? die Zeos haben so etwas soweit ich weiß nicht.

Gremlin 11. Aug 2007 21:29

Re: Crystal Reports XI + Delphi und unterschiedliche Datenba
 
So wie du dir das ausgedacht ist ist es meiner Meinung nach nur schwer lösbar und wenn es gehen sollte wird es sicher sehr fehleranfällig sein, dh. es darf wirklich nichts falsch laufen, damit ein Ergebnis vorhanden ist.

Warum machst du nicht einfach einen Script (den Ihr vorgebt und der Anwender gegebenenfalls ändern kann), wobei ich aber nicht den Umfang deiner Anwendung bzw. Datenbank kenne, der die entsprechenden Tabellen mittels SQL-Abfragen in dein gewünschtes Tabellenformat exportieren kann (BDE, ADO, DBF-nativ, etc. etc.) und auf die der CRXI zugreifen kann? Dann wärst du von allen Schwierigkeiten für Zugriffsrechte, Schnittstellen und zusätzlichen Client-Lizenzen entbunden.

Grüssle Gremlin

cytrinox 11. Aug 2007 22:03

Re: Crystal Reports XI + Delphi und unterschiedliche Datenba
 
Nunja, es sind rund 150 Tabellen und 200 Auswertungen, und die Auswertungen sollen vom Endbenutzer erweitert bzw. neue hinzugefügt werden.
D.h. ich müsste generell für jeden Report, der aufgerufen wird, den kompletten Datenbestand in eine zweite Datenbank kopieren, z.B. in eine embedded Firebird Datenbank und beim Aufruf des Reports über den Firebird ODBC Treiber drauf zugreifen. Da es sich hier um recht große Datenbanken handeln kann ist dies wohl von der Geschwindigkeit her genauso wie es jetzt auch ist :/

Als Notlösung die auf deinen Vorschlag passt, könne ich mir vorstellen dass jeder Report um eine gleichnamige INI Datei erweitert wird in der drin steht: "Brauche Tabelle: foo_1, bar_2, ..."

Wird der Report aufgerufen wird eine firebird datenbank angelegt in die ich lediglich die angegebenen Tabellen kopiere. Das ist allerdings nicht besonders kundenfreundlich, über einen eigenen ODBC Treiber wären wirklich alle Metainfos aus der richtigen Datenbank in CRXI zu Verfügung, d.h. $Kunde kann sich bequem per Drag&drop seinen Report zusammenstellen.
Weiterer Grund der dagegen spricht, ist dass die Datenbankoperationen dann alle lokal ausgeführt werden, obwohl eigentlich 30 Meter weiter ein besser ausgerüsteter, extra angeschaffter Datenbankserver steht...

Trotzdem danke für den Ansatz, an eine lokale Datenbank hatte ich so noch nicht gedacht, vielleich lässt sich das wirklich vorerst mal so wie oben beschrieben umsetzen.


Kann vielleich noch einer was speziell zu den ODBC Fragen sagen? :)

Bernhard Geyer 11. Aug 2007 22:06

Re: Crystal Reports XI + Delphi und unterschiedliche Datenba
 
Würde einen ähnlichen Vorgehen wie Gremlin empfehlen.

Ignorier die SQL-Fähigkeit von CR und befüll es selbst mit deinen schon passenden Daten (von denen du selbst weist wie du diese trotz Rechtevergabe und Multi-DB-Support am besten bestimmst). CR sollte auch ohne den Umweg über Textdateien mittels "virtueller Datenanbindung" befüllbar sein.

Einen eigenen Datenbanktreiber (ODBC) zu schreiben der wiklich full ODBC-Complient ist wird vermutlich bis er wirklich funktioniert (die Probleme liegen im Detail) einige Mannmonate arbeit verursachen, wenn nicht sogar Mann-Jahre.

cytrinox 11. Aug 2007 22:29

Re: Crystal Reports XI + Delphi und unterschiedliche Datenba
 
Zitat:

Zitat von Bernhard Geyer
Würde einen ähnlichen Vorgehen wie Gremlin empfehlen.

Ignorier die SQL-Fähigkeit von CR und befüll es selbst mit deinen schon passenden Daten (von denen du selbst weist wie du diese trotz Rechtevergabe und Multi-DB-Support am besten bestimmst). CR sollte auch ohne den Umweg über Textdateien mittels "virtueller Datenanbindung" befüllbar sein.

Nein, genau da liegt das Problem. Über Textdateien, einzele Tabellendateien usw. dauert die Auswertung von verknüpfen Daten ewig, da CRXI dann mit mehreren Tabellen arbeiten und sich das Resultset erst selbst zusammenstellen muss. Mit SQL verschiebt CRXI diese Arbeit in die Datenbank. Ich hab das sogar mal ausprobiert. Auswertung von "non-SQL" Daten: ca. 12min, die selben Daten nur über nen Firebird ODBC Treiber ca. 2 Sekunden.

Genau aus diesem Grund brauche ich _unbedingt_ die Möglichkeit, Datenbankoperationen (Joins, gruppierungen usw.) auch von einer Datenbank ausführen zu lassen.

Gremlin 11. Aug 2007 23:25

Re: Crystal Reports XI + Delphi und unterschiedliche Datenba
 
@cytronix

Du wirst nicht alle 200 Tabellen für eine einzelne Auswertung benötigen. Du erstellst als Grundlage für jede Auswertung einen Script, in dem deine Auswertungsergebnisse Platz finden (zb. jeweils die Kunden und die Jahreszahlen für eine einfache Umsatzstatistik, ergo 2 Tabellen), die dein CRXI nur als "dummer" Reportgenerator anzeigen muss. Dazu solltest du VOR der Auslieferung an den Kunden, einen passenden Report für diese Daten erstellen (Tabellen zu neuem Report zufügen, schnell verknüpfen, Formeln setzen und ein wenig auf dem Formular die Felder hin und herschieben bis es passt).
Wenn dann in deinem Programm dieses Modul ausgeführt werden soll, rufst du einfach den Script auf, der wiederum die angegebenen zwei Tabellen exportiert (wobei die beiden Tabellen natürlich für sich betrachtet eine eigene Auswertung ergeben, die der CRXI dann nicht mehr ausführen muss). Sollte diese Tabellenerstellung geklappt haben, so rufst du nur den CRXI mit der Angabe des passenden Reports auf und freust dich der Ausgabe.
Auf keinen Fall exportierst du stur nur die Tabellen die der CRXI vielleicht für seine Auswertung benötigen könnte. Du machst die Auswertung mit deinem Script, ist ja auch einfacher wir mit dem CRXI und du benötigst keine zusätzliche Verbindung zur Datenbank (sprich Lizenz)

Wie du auf eine lokale Auswertung der Daten kommst kann ich nicht nachvollziehen. Lies es einfach noch einmal durch :-D


Gruss Gremlin

PS: So eine einfache Auswertung über Script dauert auch nicht viel länger als direkt mit Delphi.

cytrinox 11. Aug 2007 23:35

Re: Crystal Reports XI + Delphi und unterschiedliche Datenba
 
hm ok, ich versuchs anders zu erklären:

Kunde hat Programm + CRXI
Kunde möchte CRXI öffnen
Datei neu, Datenbank auswählen, Verkünpfungen/Gruppierungen einrichten, Felder rüberziehen, eine Vorschau erstellen, abspeichern
neuen Report im Programm eintragen
Auswerten drücken.

Zur Not kann ich ja z.B. wie schon erwähnt eine INI Datei hinzufügen in der ein paar Infos untergebracht sind. Tatsache ist aber, dass sämtliche Verknüfpungen, Gruppierungen usw. in CRXI eingestellt werden müssen.

Bernhard Geyer 12. Aug 2007 09:38

Re: Crystal Reports XI + Delphi und unterschiedliche Datenba
 
Ok, der Kunde kann mit CR XI (eigentlich auch ohne dein Programm) vollkommen selbstdefinierte Reports sich anlegen. Dann ist er auch selbst dafür verantwortlich dies so durchzuführen das seine Performance passt. Hier würde ich mir nicht den Schuh anziehen ihm hier mit teuer selbstimplementierter SW (ODBC-Treiber) die Mängel/Unvermögen von CR hier "vorrauszusehen" was nun die beste und schnellste Abfrage ist. Ich würde ihm anbieten mit eigener Implementierung (ohne direkte DB-Zugriffsmöglichkeiten von CR) diesen Report zu realisieren. Übernimmst du auch die Garantie bei einem CR-Fehler welche die Datenbank löscht hier gerade zu stehen?

cytrinox 12. Aug 2007 12:57

Re: Crystal Reports XI + Delphi und unterschiedliche Datenba
 
Boh, wiso schreib ich eigentlich so viel und es versteht trotzdem keiner?!

Es gibt einen Grundsatz an Auswertungen die schon dem Programm beiliegen. und entweder bekommt der Kunde gegen Entgelt zusätzliche Auswertungungen oder er erstellt diese selbst. Aber ALLE Auswertungen müssen vom Programm aus geöffnet und angezeigt werden.

Ich kann also keinem sagen, hier kümmer dich mal selbst wie es mit der Anbindung aussieht, außerdem muss die Datenbankverbindung IMMER übers Programm laufen - siehe embedded Datenbanken & Rechte wie ich es oben geschildert hab.

Ich wiederhole es aber gern: Die embedded Datenbank ist während das Programm läuft schon geöffnet. Selbst wenn ich beim Kunden einen Firebird ODBC Treiber installiere, selbst wenn er es hinbekommt eine Verbindung einzurichten kann er die Auswertung nicht ausführen, da die Datenbank gelockt ist!

Ich wollte hier über ein Problem diskutieren welches genau diese Randbedingungen hat: Datenverbindung geht übers Programm (tuts jetzt auch schon über die TCrpeDS Komponente, aber eben ohne SQL), unterschiedliche Datenbanken die angebunden sind (inkl. embedded Datenbanken) und was mir fehlt ist eine Möglichkeit, SQL Befehle an das Programm und damit an die Datenbank weiterzureichen.
Deine Lösungsansätze sind schön, aber sie passen nicht auf mein Problem.

Ich kann dem Kunden nicht die Lösungssuche für die Performance zuschieben, denn ich hab selbst 200 Auswertungen die eine bessere Performance nötig haben.
Ich kann dem Kunden nicht die direkte Datanbankanbindung anbieten, denn unter Umständen arbeitet er mit einer embedded Datenbank.


Und die Aussage " Mängel/Unvermögen von CR" kann ich so auch nicht im Raum stehen lassen, denn CR ist in erster Linie eine SQL Anwendung. Wenn ich mit einer SQL Anwendung Daten auswerten möchte, die nicht mit SQL angesprochen werden können, gehts halt nicht oder nur eingeschränkt.
Word ist auch zum Schreiben von Text/Briefen gedacht, oder hast du schonmal versucht in Word eine komplizierte Excel-Tabelle umzusetzen?

Der Grund, dass ich sowas versuche (muss), ist einfach die Randbedinung dass mehrere Datenbanken angebunden werden müssen, oft welche, von denen ich jetzt zum Zeitpunkt der Berichterstellung nicht mal weiß, dass sie irgendwann unterstützt werden.

Vielleicht sind es ungeschickte Randbedingungen, aber sind sind nunmal da und dafür brauche ich eine Lösung, notfalls mit eigenen ODBC Treiber.

Zitat:

Ok, der Kunde kann mit CR XI (eigentlich auch ohne dein Programm) vollkommen selbstdefinierte Reports sich anlegen.
Jain, anlegen kann er sie nur mit CRXI, auswerten NUR mit dem Programm. Die Sache mit der Vorschau (und damit die Möglichkeit due Auswertung ja auch direkt in CRXI zu machen) würde nur ein eigener ODBC Treiber mit sich bringen. D.h. man würde zuerst das Programm starten, der lauscht dann auf einem tcp port und CRXI verbindet sich per ODBC Treiber mit dem Programm welches den Austausch von SQL und Resultsets zwischen CRXI und der Datenbank übernimmt.

Bernhard Geyer 12. Aug 2007 14:22

Re: Crystal Reports XI + Delphi und unterschiedliche Datenba
 
Ich glaub du verstehst uns nicht ganz genau :-)

Jedes vernünftige Reportingtool kann auch ohne "normales" Dataset arbeiten, sprich man kann den Report mit "virtuellen" Datasets befüllen. Evtl. kann man auf diesen "virtuellen" Datasets den Kunden anpassungen vornehmen lass(Der ReportBuilder kann sowas z.B.).

Wir haben als Lösung uns einen eigene auf unsere Anwendung abgestimmten Reportdesigner entwickelt. Damit haben wir 100% Kontrolle über die Reports und haben auch mit mehreren tausend Reportseiten keine Resourcenprobleme mehr. Und wir haben auch mehrere unterstützte DB's und auch DB's die bis zu 50 GB an Volumen haben.


Alle Zeitangaben in WEZ +1. Es ist jetzt 09:50 Uhr.
Seite 1 von 2  1 2      

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz