Hallo Forum,
ich arbeite für mein Unternehmen an der Portierung einer Software von VBA Richtung C++. Dabei muss ich den Aufwand schätzen und einen Projektplan entwickeln. Ein paar Dinge machen mir Bauchschmerzen, daher hier mal eine Frage aus dem Bereich "Datenbanken":
Bisher werden Daten in verschiedenen Excel-Listen gehalten. Die Auswahl der Daten kann praktisch über Dropdownfelder (erste Zeile der Tabelle enthält die Spaltenüberschriften) gelöst werden. Die Rechnungen beruhen dann auf einer bestimmten Zeile, deren Daten eingelesen werden. Diese Tabelle greift dann wiederum auf vorgegebene Zeilen von zwei weiteren Tabellen zu. Soweit sogut.
Excel soll als Rechenkern abgelöst werden, vielleicht aber nicht als Viewer für die Daten. Es wäre also möglich, csv-Dateien zu generieren, die nur zur Anzeige eingelesen werden, das C++ Programm kann ebenfalls einfach mit den Textdateien umgehen. (Meine angedachte Lösung ist es, ganz von Excel weg zu gehen und in Qt eine eigene Applikation zu schreiben).
Nun die Frage, wie ich in C++ den Zugriff auf die Matrizen der csv-Dateien organisiere. Ist das noch sinnvoll bei 4000 Zeilen und 50 Spalten oder wäre eine "echte" Datenbank angebracht? Wie sieht es mit SQLite aus?
Ich bin absoluter Neuling und würde als primitivste Lösung tatsächlich die csv-Datei öffnen, Zeile für Zeile lesen, nach verschiedenen Kriterien die geforderte Zeile (oder mehrere Zeilen) suchen und dann die Daten (in den Spalten) auslesen.
Vielen Dank für eure Tipps!
Heimelchen schrieb:
Wo ist da genau der Mehrnutzen gegenüber einem foreign key? Der verhindert (zumindest bei MSSQL) auch, dass die Tabellen inkonsistent werden, also ich kann nix löschen oder einfügen, was zu einer Inkonsistenz führen würde.
Ein Foreign Key erfordert nur, daß die referenzierte ID in der entsprechenden Tabelle existieren muß, und das ein bestimmtes Verhalten beim Löschen erfüllt sein muß. In Deinem Fall, daß Tabelle2:Ref -> Tabelle1:SpaltenID verweist, und Tabelle2:Ref immer korrekte Werte von Tabelle1:SpaltenID enthält.
Mit einem Trigger kann man nun weitere Prüfungen einbauen. Man benutzt ihn zusätzlich zum Foreign Key. Wenn Eintrag in Tabelle2 geändert/eingefügt wird, dann führe Trigger aus. Trigger prüft, ob Tabelle1:SubID eine bestimmte Bedingung erfüllt. Damit dies mit einem Trigger funktioniert, muß sich die Bedingung für Tabelle1:SubID berechnen lassen. Wenn diese Bedingung nicht erfüllt ist, dann wird das Ändern/Einfügen des Datensatzes in Tabelle2 verhindert.
AndyDD schrieb:
Zunächst vielen Dank für die schnelle Antwort. Diese Art und Weise bedingt, dass ja schon SQL-Serverkomponenten bzw. MDAC auf der Maschine installiert sein müssen. Ich hab den Artikel mal weiter durchforstet und bin auf folgendes gekommen:
http://www.codeproject.com/KB/database/sqlsrvenumerator.aspx
Dort werden zumindest alle Instanzen korrekt angezeigt. Allerdings kann ich nicht auf die einzelnen Databases einer Instanz zugreifen, da er die nicht findet. Muss da noch was sprezielles beachtet werden?
Ok, wenn man an der entsprechenden Stelle _T("DATABASE:Database=") gegen _T("DATABASE:Datenbank=") austauscht, dann gehts.
Ich würde, wie schon vorgeschlagen 1. Tabelle (tabellensatz) machen, mit
allen Feldern die da gebraucht werden.
Für die einzelnen Versionen würde ich dann eine View mit den für diese
Version notwendigen Infos über die Originaltabelle legen und gut is.
Also wenns nur um ein offline Spiel geht ohne zentrale Datenbank ( das lese ich eher raus ), dann nimm doch einfach sqlite. Relativ einfach zu verwenden, wenn Du SQL bereits kennst und die API ist auch nicht sehr schwer. Tools um die Datenbanken erstmal zu erstellen gibt es auch.
http://sqlitebrowser.sourceforge.net/
Wäre mein Tipp. Ich finde SQLite sehr gut, arbyte mich da auch grade rein.
rya.
wenn du mit dem BCB 6 arbeitest ist es eigentlich recht einfach:
Vorschlag 1 (zum selbstbauen):
mittels OLE-Automation oder TExcelApplication kannst du die Verbindung zu deiner Exceldatein herstellen, dazu gibts im VCL-Forum auch Beiträge
oder du verwendest den Excel-Wrapper aus der VCL-FAQ
dann kannst du mit ADO auf die Paradox-DB zugreifen und die gewünschten Daten importieren
Vorschlag 2:
lass den Beitrag ins Projekteforum verschieben und setz einen Preis an
So, die MSDN AA liefert wohl ein kaputtes Image aus, eieiei. Nunja, nun hab ich eben die Developer-Edition von dort downgeloadet (selber Funktionsumfang, andere Lizenz, ohnehin egal, weil MSDN AA ohnehin eine studentische Verwendung vorschreibt). Jetzt geht's prima
Danke an euch und vor allem Zeus für eure Nerven.
MfG SideWinder
bei MSSQL ab 2008 gibts "MERGE"
davor kann man den "insert-select-where-not-exists" trick verwenden:
INSERT tab (pk, a, b, c)
SELECT value_for_pk, value_for_a, value_for_b, value_for_c
WHERE NOT EXISTS (SELECT * FROM tab WHERE pk = value_for_pk)
IMO deutlich besser als die IF(EXISTS) lösung, da es nur ein statement ist, und daher "atomar" sein sollte (IIRC macht MSSQL für jedes statement implizit ne transaction mit automatischem commit, so lange man keine explizite transaction offen hat)
danke mit camstudio.org kam ich schon recht weit...
aber mit debut video capture hab ich absolut keine ahnung was das sein soll.
auf das erste gehe ich lieber nicht ein:::
Sich selbst antworten ist war doof, aber ich habs ganz elegant:
SELECT
ConstraintName = OBJECT_NAME(constraint_object_id),
ParentTable = OBJECT_NAME(parent_object_id),
ParentColumn = COL_NAME(parent_object_id, parent_column_id),
ReferencedTable = OBJECT_NAME(referenced_object_id),
ReferencedColumn = COL_NAME(referenced_object_id, referenced_column_id)
FROM sys.foreign_key_columns
Also wir haben in unserer Datenbank auch solche deleted-Spalten und ich halte sie mittlerweile für sehr nützlich. Es kommt doch leider öfters mal vor, dass unabsichtlich Daten gelöscht werden und auf diese Art und Weise können wir sie schnell wiederherstellen.
Als Alternative zu solchen deleted-Spalten könnte man die gelöschten Einträge auch in eine eigene deleted-Tabelle "verschieben", dann würde die richtige Tabelle auf Dauer nicht "zugemüllt" werden.
statt die ganzen zeilen kannst auch ne 2. tabelle nehmen in der nur die ids für die erste tabelle liegen dann hast auch nicht nen ganz so großen overhead...
so wars gedacht...
+-+-+-+
|1|a|2|
|2|b|1|
+-+-+-+
+-+
|1|
|1|
|2|
+-+
naja viel spaß beim frickeln
das Problem hat man aber immer, da auch der SQL-Syntax in anderen Fällen nicht kompatibel ist. z.B.
MySQL: select * from tabelle limit 100 -> Zeigt 100 Zeile an
MSSQL: select top 100 * from tabelle -> Zeigt 100 Zeile an
Ich weiß nicht was die "USING"-Klausel sein soll, scheint mir jedenfalls kein SQL92 zu sein. Versuchs mal mit:
SELECT * FROM W1 INNER JOIN W2 ON W1.PID = W2.PID
MfG SideWinder