Dynamisch neue SQL Tabelle erstellen
-
Hallo,
ich habe eine .net Anwendung die mittels DataSet SQL Tabellen anspricht.
Eine Tabelle soll als Journal dienen und jährlich neu initialisiert werden. Das vorhandene Schema soll exakt übernommen werden.
Wie realisier ich das am Besten? Muss ich die vorhandene erst umbenennen und mit createTable arbeiten? Kann ich das vorhandene Schema übergeben?
Oder ist es ratsam eine gespeicherte Prozedur zu erstellen?
Ich möchte das gerne über das DataSet in VisualStudio realisieren und den Nutzer vom Programm auffordern , beim Jahreswechsel ein neues Journal zu beginnen.
Danke im Voraus!
-
Dappeljuh schrieb:
Ich möchte das gerne über das DataSet in VisualStudio realisieren
Warum? Ich hab mich jetzt jahrelang nicht mehr intensiv mit .NET beschäftigt, zumindest nicht mit Datenbankanwendungen und weiß jetzt nicht, was da alles an APIs dazugekommen ist (da hat sich aber einiges getan). Aber ein DataSet benutzen zu wollen hört sich für mich nicht nach einer Anforderung an. Hört sich für mich eher so an, als ob du eine Tastatur benutzen wollen würdest, um das Vorhaben umzusetzen.
Es gibt auf jeden Fall verschiedene Möglichkeiten. Du lieferst zu wenige Informationen, um eine sinnvolle Empfehlung zu geben, und ich kenne mich aktuell zu wenig aus, als dass ich auch mit zusätzlichen Informationen eine sinnvolle Empfehlung geben könnte
1. Tabellen kann man schon kopieren, z.B. mit SELECT INTO newTable FROM existingTable where 1=2. Das kopiert aber keine Indizes usw., ist also nicht wirklich eine gute Lösung.
2. Ich bin kein Fan von Stored Procedures. Ich will normalerweise einen Überblick über das Projekt haben. Stored Procedures, Trigger usw. ist für mich etwas, was irgendwie nebenbei abläuft und keiner kennts oder denkt dran. Ich hätt die Logik lieber im Code, und nicht die Hälfte davon in der Datenbank. Es gibt durchaus viele große Projekte, die eben anders umgesetzt sind und wo viel Logik in der Datenbank ist (und das kann auch durchaus sinnvoll sein). Ist aber echt keine einfache Entscheidung. Also wenn es keine besondere Gründe dafür gibt und bisher sowas im Projekt nicht verwendet wurde, würde ich auch keine stored procedures verwenden.
3. Ich glaub, zur Zeit ist das entity framework in .NET "in", wenn die Information nicht schon wieder veraltet ist. Das ist ein ORM Framework und hat sicher auch Funktionen zum Erstellen des Schemas in der Datenbank drin. Keine Ahnung, was du machst, macht evtl. eh Sinn, ein ORM Framework zu verwenden, und vielleicht musst du dich dann sowieso daran orientieren. Aber da müsstest du dich genauer reindenken.
4. Du kannst auch irgendwo SQL Scripte hinterlegen und die dann ausführen. Das hätte ich so gemacht, aber mit dem Hintergrund, dass ich C++ und unser eigenes "ORM" verwende, hängt also stark vom Kontext ab.
-
Warum
Weil es ein bestehendes .Net Programm ist, das erweitert werden soll.
Du lieferst zu wenige Informationen, um eine sinnvolle Empfehlung zu geben, und ich kenne mich aktuell zu wenig aus, als dass ich auch mit zusätzlichen Informationen eine sinnvolle Empfehlung geben könnte
Die Funktion:
Das Journal kann man sich wie ein Tagebuch vorstellen. Jeden Tag kommen ca. 50-100 Einträge dazu. Am Jahresanfang ist der Index 0. Am 02.01. des Folgejahres wird das Journal geschlossen und archiviert. Im Anschluss wird ein neues Journal angelegt.Die Umsetzung:
Im Management Studio habe ich eine SQL Tabelle angelegt, welche 20 Elemente beherbergt. Diese Elemente nehmen die Benutzereingaben auf. Im VisualStudio verwende ich ein Dataset den TableAdapter und eine BindingSource um die Daten an Steuerelemente zu binden. Soweit funktioniert auch alles.Meine Frage:
Wie kann ich dem User ermöglichen, zum Jahresanfang eine neue Tabelle zu erstellen, welche die im Management Studio angegebenen Elemente enthält?Zu 1:
An so etwas habe ich auch schon gedacht. Die archivierte Tabelle muss aber 1:1 kopiert werden, samt Indizes. Außerdem kann ich ja mit Sicherheit nicht zwei Tabellen mit gleichem Namen verwenden. Ich muss die Tabelle ja umbenennen. In meinem Fall wäre das Jahr als Bezeichner interessant. Z.B. Journal2016, Journal2017, etc...Zu 2:
Die gespeicherte Prozedur wäre für mich deswegen interessant, da ich die SQL Abfrage dann "gekapselt" habe. (Ich weiß nicht ob man das so nennen darf... )Zu 3: Leider gibt es so viele tolle Frameworks, aber nur so wenig Zeit sich das alles anzueignen... Ich habe zwar kurz reingeschaut, würde aber nach Möglichkeit erst meine jetzigen .Net und SQL Kenntnisse vertiefen wollen.
Ich denke das ich mein Problem relativ einfach lösen kann, nur wie?Zu 4: Was wäre der Vorteil gegenüber der gespeicherten Prozedur? Ich persönlich finde da die Prozedur schöner, aber wie du schon sagst Geschmackssache.
-
Hi,
ich würde gerne erfahren, wieso du unbedingt jedes Jahr eine neue Tabelle erstellen willst. Wäre es nicht einfacher, in einer weiteren Tabelle pro Jahr einen Zähler hochzählen zu lassen und in den Journal-Datensätzen dann auf den Zähler zu verweisen? So hast du auch eine Gruppierung. Du kannst an den Zähler auch noch die Jahreszahl hängen, sodass du weißt, in welchem Jahr welcher Zähler entstanden ist.
Was spricht aus deiner Sicht dagegen?
-
Dappeljuh schrieb:
Zu 4: Was wäre der Vorteil gegenüber der gespeicherten Prozedur? Ich persönlich finde da die Prozedur schöner, aber wie du schon sagst Geschmackssache.
Wie kommt die stored procedure in die Datenbank? Brauchst du dann nicht eben auch ein Setup Script, um die reinzubekommen?
Und du siehst die stored procedure nicht. Sie ist vielleicht da, vielleicht nicht, vielleicht hast du sie vergessen, oder dein Kollege kennt sie gar nicht. Wenn du in den Code debuggst und da wird ein SQL Script von Platte geladen, dann siehst du das beim Debuggen, kannst dir auch das Script anschauen, du siehst obs geklappt hat... Der Code ist einfach weniger verstreut und man hats besser im Griff.Ich hätt dafür jetzt auch nicht eigene Tabellen angelegt. Kannst doch einfach nach Jahr gruppieren oder filtern. Du hast sehr wenige Daten, damit kommt jede Datenbank völlig problemlos zurecht.
-
Erst einmal danke für euer Interesse.
Da jedes Jahr eine Zusammenfassung erstellt wird und das Jahr damit abgeschlossen wird, sollen die Daten unveränderbar, also als ReadOnly zur Verfügung stehen. Die Tabelle ist letztlich über das Management Studio weiterhin veränderbar, aber in meinem Programm wird das dann nicht möglich sein. Jeder Eintrag enthält ein aktuelles DateTime Objekt. Ich könnte das als Filter in die Abfrage einbauen.
Da ich soetwas ähnliches schon einmal programmiert habe, allerdings mit .XML Dateien, dachte ich es wäre vielleicht sinnvoller die Tabelle jedes Jahr neu anzulegen. Bei Dateien ist das natürlich kein Problem, da ich da einfach nur den Dateinamen mit einem Suffix versehen muss. Wie mir scheint ist das bei Datenbanken keine gute Idee.
@Hinterfrager: Wie findest du den Ansatz mit dem DateTime Filter? Spricht was dagegen? Dann könnte ich mir die zweite Tabelle sparen, oder?
@Mechanics: Ich habe die Prozedur jetzt einfach dem DataSet hinzugefügt. Also mittels Designer in VisualStudio. Dann kann ich diese im DataSet sehen und auch testen.
Wie wäre deine Herangehensweise?
-
Dappeljuh schrieb:
@Hinterfrager: Wie findest du den Ansatz mit dem DateTime Filter? Spricht was dagegen? Dann könnte ich mir die zweite Tabelle sparen, oder?
Erst einmal danke dafür, dass du auf alles eingehst, was wir hier schreiben. Und das sehr detailliert. Top! Das tut gut.
Ja, ein Filter auf DateTime anstatt einer Tabelle pro Journal hört sich für mich sinnvoller an.
Wenn man es ganz genau machen will, könnte man eben auch den Ansatz mit einer Journal-ID machen, sodass die Journals wirklich auch eindeutig gruppiert werden können. Die Frage ist, ob dir das Jahr als Gruppierungskriterium reicht oder ob es z. B. auch dazu kommen kann, dass ein Journal-Eintrag am 01.01.2017 um 00:00:01 geschrieben wird und der eigentlich noch in's alte Journal mit rein soll. Dieser Gedanke kam mir auf, weil du geschrieben hast, dass du den Benutzer dazu auffordern willst, ein neues Journal anzulegen. Vielleicht sollen die Journals auch Namen erhalten können? Dann wäre eine Tabelle mit Journals, auf die du in deiner Tabelle mit den Journal-Einträgen verweist, auf jeden Fall sinnvoll.
Was meinst du dazu?
-
Dappeljuh schrieb:
@Mechanics: Ich habe die Prozedur jetzt einfach dem DataSet hinzugefügt. Also mittels Designer in VisualStudio. Dann kann ich diese im DataSet sehen und auch testen.
Wie wäre deine Herangehensweise?
Sorry, hab vergessen zu antworten... Meine Herangehensweise bezogen worauf genau? Die stored procedure hinzuzufügen?
Dass das über den Designer in Visual Studio geht, wusste ich nicht. Ich denke eher ans Deployment beim Kunden. Die Anforderungen unterscheiden sich je nachdem, ob du die Software für dich selber oder einen Kunden schreibst, oder für viele Kunden. Unsere Software wird von vielen (hunderte) Kunden benutzt, und wir unterstützen unterschiedliche Datenbanken. Deswegen denke ich bei sowas an Datenbankscripte, die wir mit ausliefern und die Consultants beim Kunden einspielen können. Und wir haben auch einen Installer, der das auch machen kann, wenn man schon während der Installation auf die Datenbank zugreifen kann.
-
@Hinterfrager:
Die Frage ist, ob dir das Jahr als Gruppierungskriterium reicht oder ob es z. B. auch dazu kommen kann, dass ein Journal-Eintrag am 01.01.2017 um 00:00:01 geschrieben wird und der eigentlich noch in's alte Journal mit rein soll
Das Programm wird von bis zu 10 Mitarbeitern in meinem Betrieb benutzt. Da wir nur von 08:00 bis 18:00 geöffnet haben sollten Eintragungen nur von ca. 07:00 - 20:00 erfolgen.
Vielleicht sollen die Journals auch Namen erhalten können?
Das Journal soll den Suffix des aktuellen Jahres bekommen - also in etwa "Journal-2016". Ich könnte mir auch monatliche Views vorstellen. Also in etwa "Journal-März2016". Ich würde das jetzt aus dem DateTime Objekt erstellen.
@Mechanics:
Ihr macht das auf jeden Fall um einiges professioneller . Ich arbeite alleine an dem Programm. Allerdings wächst die Anwendung mit den Jahren immer weiter. Übersichtlichkeit ist das schon ne schöne Sache...
Ich glaube für kleinere/private Projekte ist das DataSet ganz gut geeignet. Hab das immer ignoriert und mit eigenen Klassen gearbeitet, aber im Nachhinein muss ich gestehen, dass das echt schnell und sauber zu implementieren ist!Jetzt hätte ich nur noch eine Frage:
Der Primary Key läuft ab 1 los. Ich möchte gerne die Positionen in der Übersicht mit angeben können.Ein Auszug aus dem Tabellen Header:
PrimaryKey|Tagesnummer|Tagesposition|GesamtpositionDie Tagesnummer ist fortlaufend und beginnt jährlich bei 1. Es werden nur Tage mit Einträgen iteriert.
Die Tagesposition beginnt täglich bei 1. Es wird jeder tägliche Eintrag iteriert.Das funktioniert auch soweit.
Die Gesamtposition soll jährlich bei 1 starten und jeden Eintrag des Jahres zählen. Macht es Sinn diesen Wert in der Tabelle als separaten Eintrag zu speichern? Oder ist es möglich den Primary Key nach einem Format wie 16-1 (also 2016, erster Eintrag),16-2,16,3, etc.) bzw. 17-1,17-2, etc. zu erstellen?
Oder ist das Blödsinn?Vielen Dank für eure Mühe!
-
Hi,
warum willst Du die vorhandene Tabelle als Archiv nehmen und ne neue anlegen?
Mach es doch umgekehrt, speichere alles aus der aktuellen Tabelle mittels "select * into Archiv2015 from AktuelleTabelle" in die zu archivierende Tabelle, bei der brauchst Du Dir ja um Indexe und sonstiges keien Kopf mehr zu machen.
Anschließend mach die aktuelle Tabelle mit "Delete from AktuelleTabelle" leer und los gehts von neuem. Dann behält die aktuelle Tabelle alle die Verknüpfungen, Indexe... die sie braucht und im Archiv stehen nur die reinen Daten.
Eventuell musst Du nach dem Leeren noch den AutowertINdex wieder irgendwie zurücksetzen. Das ist dann abhänig von der jeweiligen Datenbank, da können sicher andere besser helfen. Aber gehen müsste es eigentlich bei allen Datenbanken.Gruß Mümmel
-
Dappeljuh schrieb:
Jetzt hätte ich nur noch eine Frage:
Der Primary Key läuft ab 1 los. Ich möchte gerne die Positionen in der Übersicht mit angeben können.Ein Auszug aus dem Tabellen Header:
PrimaryKey|Tagesnummer|Tagesposition|GesamtpositionDie Tagesnummer ist fortlaufend und beginnt jährlich bei 1. Es werden nur Tage mit Einträgen iteriert.
Die Tagesposition beginnt täglich bei 1. Es wird jeder tägliche Eintrag iteriert.Das funktioniert auch soweit.
Die Gesamtposition soll jährlich bei 1 starten und jeden Eintrag des Jahres zählen. Macht es Sinn diesen Wert in der Tabelle als separaten Eintrag zu speichern? Oder ist es möglich den Primary Key nach einem Format wie 16-1 (also 2016, erster Eintrag),16-2,16,3, etc.) bzw. 17-1,17-2, etc. zu erstellen?
Oder ist das Blödsinn?Vielen Dank für eure Mühe!
Ich kann dir nicht ganz folgen. Wieso brauchst du so viele Spalten? Genügt nicht eine Spalte als Primärschlüssel, eine Spalte für Datum/Uhrzeit und eine Spalte für den Eintrag selbst? Damit hast du doch alle Informationen, die du brauchst.
Für die Tagesnummer (falls das die Nummer des Tages innerhalb des jeweiligen Jahres ist), kannst du mit DATEDIFF arbeiten.
Tagesposition ergibt sich aus der Zeilennummer, die die Zeile innerhalb aller Einträge des Tages sortiert nach Uhrzeit hat.
Gesamtposition ist dann logischerweise die Position innerhalb aller Datensätze.
Je nachdem, welches DBMS du verwendest, gibt es Hilfsfunktionen, die dir die Zeilennummer gleich in der Query liefern (beispielsweise ROW_NUMBER() in MS SQL Server).
Um die Frage "Ist das Blödsinn?" beantworten zu können, bräuchte ich nähere Informationen zum Zweck deiner genannten Spalten.
Und um auch auf deine Frage wegen des Primärschlüssels zu antworten: Du kannst einen Primärschlüssel über mehrere Spalten anlegen. Damit kannst du dann sozusagen die Kombinationen "12-1, 12-2, 13-1, 13-2, ..." abbilden.