Laden...

Forenbeiträge von GeneVorph Ingesamt 180 Beiträge

09.07.2017 - 21:45 Uhr

Hallo FZelle,

vielen Dank für deinen post!
Bevor ich dazu noch drauf eingehe, hier mal der Code meiner UpdateTable-Methode:


public void UpdateTable(string tableName, DataTable sourceTable, bool newOrEdit)
        {          
            try
            {
                string connectionPath = dbVariables.ConnectionString;
                //Connection erstellen --> der connectString gibt dabei den Pfad an.
                SQLiteConnection myConnection = new SQLiteConnection(connectionPath);

                myConnection.Open();
                                
                string myUpdateString = "SELECT * FROM " + tableName + "";
                
                SQLiteDataAdapter myAdapter = new SQLiteDataAdapter(myUpdateString, myConnection);

                SQLiteCommandBuilder comBuild = new SQLiteCommandBuilder(myAdapter);

                myAdapter.DeleteCommand = comBuild.GetDeleteCommand(true);
                myAdapter.UpdateCommand = comBuild.GetUpdateCommand(true);
                myAdapter.InsertCommand = comBuild.GetInsertCommand(true);
                

                myAdapter.Update(sourceTable);

                myConnection.Close();

                if (newOrEdit == true)
                {
                    MessageBox.Show("Klasse erstellt!");
                }
                else
                {
                    MessageBox.Show("Klasse aktualisiert!");
                }

            }
            catch (SQLiteException e)
            {
                MessageBox.Show(e.ToString());
            }

        }

Mit der Methode UpdateTable kann ich derzeit neue Einträge anlegen, bzw. angelegte Einträge bearbeiten. (Table wird ausgelesen - Eintrag dazu/bearbeitet - Table in der Datenbank geupdated) [EDIT] quatsch - ich wollte damit sagen: ich habe meinen DataTable, trage dort neue DatarRows ein oder bearbeite bestehende DataRows und schicke den so bearbeiteten DataTable an obige Methode, wo die Änderungen dann wirksam werden.

So, jetzt noch kurz eine Erläuterung, bzw. Fragen:

a)

2. Die Junx benutzen den MS Sql Server und Du SQLite, das sind 2 verschiedene Paar Schuhe.
MS Sql erlaubt das setzen von Identity Spalten nur auf Umwegen, bei SQLite kannst du da reinschreiben was du willst.

OK, das Erste verstehe ich - mit Identity-Spalten meinst du PrimaryKey, bzw. AutoIncrement usw.?

b)

  1. Das einlesen der Kompletten Datenbank ist sehr selten richtig. Wenn man die DB nicht als solche benutzen möchte, dann Benutze gleich Serialisierung.

Mein Gedanke war, dass es nicht, hm, "guter Stil" sein kann, ständig Datenbankzugriffe zu verursachen. Bspl: Für einen neuen Eintrag musste ich vorher erstmal eine Query feuern, die schaut OB überhaupt Einträge in der Datenbank sind, dann ein Query, dass die Namen der vorhandenen Einträge einer Liste übergibt, dann ein Query.... --> das führte zu dem Gedanken, mit einer Kopie der Tabelle aus der Datenbank zu arbeiten, diese nach Einträgen, Bearbeitungen und Löschungen zu updaten und wieder der Datenbank zu übergeben. Wenn ich das hier richtige verstanden habe, geht Serialisierung genau in diese Richtung?

Andererseits würde ich gerne lernen mit Datenbanken zu arbeiten und nutze meine Projekte immer als "Übungsaufgaben".

Dabei sind wir einem weiteren wichtigen Punkt: das Internet ist voll von Tutorials, Dokumentationen und YouTube zum Thema - vielleicht lehne ich mich ja weit aus dem Fenster, aber ich habe manchmal das Gefühl, man lernt mehr "falsch", wenn man sonst keine Referenzen hat, als dass man direkt Experten fragt. Der Laie sucht immer den Weg, der als erstes funktioniert - das muss ja nicht zwangsläufig ein guter Weg sein 😉

s. dazu folgendes: nachdem ich mit obiger Methode nun also Einträge hinzufügen und Editieren kann, klappt Löschen überhaupt nicht. Hier mein Code dazu:


 if (myResult == DialogResult.Yes)
            {                
                DataRow[] dr = killTable.Select("" + cmVariables.ClassName + " = '" + cmbClasses.Text + "'");                
                //Index als String übergeben - dr ist ein Array; da ein gesuchter Eintrag nur 1x vorkommen kann, muss das Array an Index 0 (erster EIntrag) abgegriffen werden.
                string indexName = (killTable.Rows.IndexOf(dr[0])).ToString();

                //String in int parsen - dadurch erhält man den Index der DataRow, die mit den Werten gefüllt ist, die für die Löschung benötigt werden
                int i = Int32.Parse(indexName);

                DataRow modifiedRow = killTable.Rows[i];

                modifiedRow.BeginEdit();
                                          
                killTable.Rows[i].Delete();

                //MessageBox.Show("hier: " + killTable.Rows[i].RowState);

                modifiedRow.EndEdit();

                killTable.AcceptChanges();                

                killClass_Execution(killTable, cmbClasses.Text, ShortClassNm);
                
            }

Ich habe mir in der - jetzt auskommentierten - MessageBox den RowState ausgeben lassen - dieser ist als Deleted markiert; warum AcceptChanges keine Wirkung zeigt - keine Ahnung. Mit meinem Code oben klappt es leider nicht...

Zu einer Anmerkung von dir noch eine kleine Anmerkung von mir:

Das erste Problem ist, das die Junks von Rheinwerk bei ADO.NET meist ziemlichen Mist schreiben und die hälfte weglassen.

Ich bin - leider - nicht in der Lage, das zu beurteilen. Aber es spricht mir doch irgendwie aus der Seele. Denn das ist das erste, aber nicht einzige Problem^^ Die Sache ist die: ich progammiere zum Spaß und weil ich mir hin und wieder mit kleinen selbstgeschriebenen Progrämmchen auch schon Arbeit gespart habe. Ich habe leider nie einen Kurs besucht (wie auch? Such mal C# an 'ner VHS...), kein Vorwissen und bin beruflich in gaaanz anderen Gefilden unterwegs: kurzum - alles ist zusammengelesen, erfragt oder aus Tutorials. "Visual C# - das umfassende Training" war mein Einstieg ins Programmieren überhaupt. Das Wörtchen "umfassend" (das habe ich dann schnell gemerkt) ist dabei noch sehr geschönt. Fachwörter mit Fachwörtern zu erklären - ganz toll. Ich habe jetzt Serialisierung gegoogelt und nach gut 30 Minuten eine ungefähre Vorstellung davon. Habe dazu ausnahmsweise in der Doku was gefunden, was in (verständlichem) deutsch geschrieben stand und zumindest nach mehrmaligem Begriffezusammensuchen dann auch Sinn ergab. Wer sich mal in den typischen Programmierlaien reinversetzen möchte, kann ja mal das das durchlesen - ist für mich Klartext, aber so wie hier bei einem Aussenstehenden erstmal 60% vorbeirauschen, geht's mir bei der Doku - didaktischer Alptraum.

beste Grüße
Vorph

08.07.2017 - 22:00 Uhr

O M G !

Zuerst möchte ich euch die Lösung posten - dann hätte ich noch ein paar Fragen, vielleicht erbarmt sich ja noch jemand einer Antwort:

Also:

  1. Ich beziehe den Table folgendermaßen:


CLASS classNewOrCreate 

public DataTable GetTable(string tableName)
        {
            string connectionPath = dbVariables.ConnectionString;

            try
            {
                //Connection erstellen
                SQLiteConnection myConnection = new SQLiteConnection(connectionPath);

                //Verbindung zur Datenbank öffnen
                myConnection.Open();

                //SELECT * FROM <Tabellenname>
                string cmdStr = "SELECT * FROM " + tableName;
                
                //DataTable-Objekt erstellen 
                DataTable myTable = new DataTable();

                SQLiteDataAdapter myAdapter = new SQLiteDataAdapter(cmdStr, myConnection);

                // DIESE ZEILE HATTE ICH NICHT
                myAdapter.FillSchema(myTable, SchemaType.Source); 

                myTable.Columns[dbVariables.ClassesID].AutoIncrement = true; 
                myTable.Columns[dbVariables.ClassesID].AutoIncrementSeed = 1; 
                myTable.Columns[dbVariables.ClassesID].AutoIncrementStep = 1; 

                myAdapter.Fill(myTable);

                myConnection.Close();

                return myTable;

            }
            catch (SQLiteException e)
            {
                MessageBox.Show(e.ToString());
                return null;
            }
        }


Die Zeile


 myAdapter.FillSchema(myTable, SchemaType.Source);

war in meinem ursprünglichen Code NICHT enthalten. Diese ist jedoch ganz wesentlich, wie man - ein paar Kapitel vor dem von mir oben verlinkten Artikel - erfahren kann. Eine neue DataRow ohne diese Zeile lässt sich nämlich problemlos erstellen und einfügen - update kann man aber scheinbar knicken. Wenn man dieses nicht weiß, ist man im besten Fall einfach nur gea..... .

Dann musste ich meinen Code von heute mittag (s. oben) noch an zwei Stellen modifizieren:


 DataRow newRow = tempDataTable.NewRow();
                    //tempDataTable.Columns[].AutoIncrement = true;
                    //tempDataTable.Columns[0].AutoIncrementSeed = -1;
                    //tempDataTable.Columns[0].AutoIncrementStep = -1;

                    newRow[dbVariables.ClassName] = txtClassName.Text;
                    newRow[dbVariables.ClassHead] = txtHeadmaster.Text;
                    newRow[dbVariables.PartnerClasses] = txtClassNames.Text;
                    newRow[dbVariables.ShortClassName] = classShort;

                    tempDataTable.Rows.Add(newRow);

                    studentDB.UpdateTable(dbVariables.TableName, tempDataTable);

(Alter Code wurde auskommentiert, zwecks besserem vorher/nachher Vergelich)

Was ich nicht verstehe ist folgendes: bei Rheinwerk finde ich zu lesen:

Die Werte, die ADO.NET erzeugt, müssen Sie als Platzhalter verstehen. Sie werden später bei der Aktualisierung der Originaldatenbank nicht mit zurückgeschrieben. Die tatsächlichen Schlüsselwerte erzeugt die Datenbank selbst.

Doch welche Werte sollten Sie in der DataTable vergeben? Eigentlich müssen Sie nur sicherstellen, dass neue Schlüsselwerte nicht mit den Schlüsselwerten in Konflikt geraten, die bereits in der DataTable enthalten sind. Sie können auch davon ausgehen, dass negative Werte in der Datenbank nicht verwendet werden. Empfehlenswert ist daher, die beiden Eigenschaften AutoIncrementSeed und AutoIncrementStep auf jeweils –1 festzulegen. Zudem sollten diese Einstellungen erfolgen, ehe das DataSet mit den Daten gefüllt wird.

Das ist eigentlich genau das, was ich getan habe, oder? Nur, dass in meinem Table unter SQLite dann negative Indices eingetragen wurden. Jetzt habe ich die negativen Werte einfach in positive abgeändert - und es funzt.

Falls mir hier jemand mit Erläuterungen weiterhelfen könnte, würde mir das schon sehr helfen!

Gruß
Vorph

08.07.2017 - 13:16 Uhr

verwendetes Datenbanksystem: SQLite3

Sodale,

ganz kurz zu dem, was ich vorhabe:

  • einem DataTable soll eine neue DataRow hinzugefügt werden. Der DataTable selbst ist eine Kopie des Tables aus der Datenbank.

Ich habe mich dabei besonders auf das Openbook von Rheinwerk gestützt und habe zwei, drei Verständnisfragen, die ihr mir vielleicht erklären könnt.

a) Prinzipiell habe ich demnach drei Möglichkeiten eine neue DataRow hinzuzufügen, wobei ich im Weiteren mich auf .NewRow() beziehen werde.
Mein DataTable enthält eine leere Tabelle mit insgesamt fünf Spalten
1 - classID, Typ Integer, Primary Key
2 - className, Typ Text, NullAllowed
3 - classHead, Typ Text, NullAllowed
4 - partnerClasses, Typ Text, NullAllowed
5 - classShort, Typ Text, NullAllowed

Erste Frage: da mein DataTable eine Kopie aus der Datenbank ist, gehe ich davon aus, dass die Metadaten der Columns übernommen werden (welche Spalte welchen Typs ist, bzw. PrimaryKey). Ist das soweit korrekt?

b) Folgende Aussage finde ich bei Rheinwerk zum Thema "Sonderfall AutoInkrement-Spalten" (s. hier):

Doch welche Werte sollten Sie in der DataTable vergeben? Eigentlich müssen Sie nur sicherstellen, dass neue Schlüsselwerte nicht mit den Schlüsselwerten in Konflikt geraten, die bereits in der DataTable enthalten sind. Sie können auch davon ausgehen, dass negative Werte in der Datenbank nicht verwendet werden. Empfehlenswert ist daher, die beiden Eigenschaften AutoIncrementSeed und AutoIncrementStep auf jeweils –1 festzulegen. Zudem sollten diese Einstellungen erfolgen, ehe das DataSet mit den Daten gefüllt wird.

Ich habe dazu folgenden Code erstellt:


 DataRow newRow = tempDataTable.NewRow();
                    tempDataTable.Columns[0].AutoIncrement = true;
                    tempDataTable.Columns[0].AutoIncrementSeed = -1;
                    tempDataTable.Columns[0].AutoIncrementStep = -1;
                   
                    newRow[dbVariables.ClassName] = txtClassName.Text;
                    newRow[dbVariables.ClassHead] = txtHeadmaster.Text;
                    newRow[dbVariables.PartnerClasses] = txtClassNames.Text;
                    newRow[dbVariables.ShortClassName] = classShort;

                    tempDataTable.Rows.Add(newRow);

                    studentDB.UpdateTable(dbVariables.TableName, tempDataTable);

Wie man sehen kann, werden nur vier Spalten erstellt; die Spalte mit dem Primärschlüssel fehlt - klar, den kenne ich zu diesem Zeitpunkt ja nicht. Ich weiß aber, das Column[0] den Primärschlüssel besitzt; im ersten Block setze ich daher diese Spalte auf AutoIncrement true, und setze Schrittweite und Seed auf -1.

Beim Ausführen des Codes erhalte ich eine Fehlermeldung:

Ein Ausnahmefehler des Typs "System.Data.NoNullAllowedExcewption" ist aufgetreten ... Spalte 'classID' lässt nicht 'nulls' zu.

Genau - das stimmt ja auch. Meine Frage nun dazu: wäre es richtig zu behaupten, dass AutoIncrement, AutoIncrementSeed, etc. sich eher wie ein Vermerk ausnehmen, der später für das Schreiben in die Datenbank wichtig wird? Weniger sich auf mein DataTable bezieht? Oder vereinfacht: mein Table "weiß", dass classID nicht null sein darf, generiert aber durch obigen Code gar keinen neuen Wert?

c) Wenn meine Vermutung aus b zutrifft, stellt sich die Frage - wie erstelle ich dann eine neue DataRow, wenn die erste Spalte nicht null sein darf, aber die Methode .NewRow auch keinen neuen Index erstellt? Irgendwoher muss der Table ja wissen, dass die erste Spalte nicht null sein darf - OK. Aber dann muss es doch möglich sein einen Wert zu generieren?

Ich habe übrigens einen "Workaround" gefunden, der aber recht, hm, unsexy ist:
ich ermittele die Anzahl der Zeilen in der Tabelle und zähle 1 dazu und übermittele diesen Wert für die erste Spalte...Bitte nicht ausflippen, ich weiß ja, dass das nix ist. Daher ja die ganze Fragerei 🙂

Ist ne Menge Text, aber es würde mir sehr weiterhelfen, dazu ein paar Antworten zu bekommen.
Vielen Dank, viele Grüße
Vorph

06.07.2017 - 23:39 Uhr

Danke, ich kämpfe mich bereits seit heute Mittag durch die Doku 😃


DataRow[] dr = tempDataTable.Select("className = t6");

string x = (tempDataTable.Rows.IndexOf(dr[0])).ToString();

MessageBox.Show(x);

Das ist das "Beste", was ich aus zig Beispielen zusammenbasteln konnte^^
(u.a. hier )

Ich weiß, dass der Name der Klasse "t6" lautet und der Spaltenheader "className" - ich brauche einfach den Primary-Key, der unter der Spalte "id" zu finden ist.

Mit meinem Code erhalte ich eine System.Data.EvaluateException: die Spalte t6 wurde nicht gefunden. Das ist auch klar, es gibt keine Spalte "t6"; t6 ist mein Wert, den ich aus Spalte 1, Reihe 2 entgegennehme.

Ich nehme an, mit meiner Syntax stimmt etwas nicht - oder ich versuche es generell über den falschen Weg?

Über konkrete Hilfe würde ich mich sehr freuen,

Gruß
GeneVorph

06.07.2017 - 22:12 Uhr

verwendetes Datenbanksystem: SQLite3

Hallo,

ich benötige Hilfe bei folgender Frage:

ich habe ein DataTable (tempTable), der die Kopie eines Tables meiner Datenbank ist. Ich möchte nun mit der Kopie arbeiten und möchte zwei strings wie folgt besetzen:

string InfoA = tempTable.Rows[?]["name"]
string InfoB = tempTable.Rows[?]["name"]

Die ? (vor allem die in meinem Kopf) sind das Problem: ich kenne zur Laufzeit die Indexwerte nicht. Bei einem SQLite-Query könnte ich mir helfen mit:

 "SELECT id FROM tempTable WHERE name = 'Fridolin'"

Es gibt auch unter C# für DataTable eine Select-Methode; leider kommt die mit WHERE nicht klar?
[Error-Message fehlender Operand nach WHERE - mein string war wie der SQLite-Beispielstring von oben aufgebaut, ist mir aber schon klar, dass man den nicht 1:1 übernehmen kann]

Noch so eine Besonderheit: jeder Eintrag ist unique. Die Strings A und B sind Bezeichnungen für Schulklassen, die in der Form immer nur genau einmal so vorkommen können.

Gruß
GeneVorph

29.06.2017 - 17:35 Uhr

Aber dass deine beiden Queries im Startpost syntaktische Fehler haben, hast du gelesen?

Oh Mann, das hatte ich total missverstanden! SORRY! Darf ich fragen, wo genau der Fehler liegt? Vielleicht bin ich vollkommen blind, aber ich verstehe nicht, wieso es beim ersten query funktioniert, beim zweiten nicht^^ Alles, was ich jetzt zu verstehen glaube, ist, dass ich beim 2. das Datum so gewählt habe, dass ich einen Eintrag größergleich (≥) 1. Januar 1996 und den anderen kleinergleich (≤) 31.Dezember 1996 gesetzt habe. Hm, aber das wäre ja wenn überhaupt ein logischer Fehler.

Seh ich den Wald vor lauter Bäumen nicht??

EDIT: SCH...

sorry, zu dumm zum Link anklicken... Ich weiß zwar, dass meine Augen schlechter geworden sind, aber das ist nur peinlich! Sorry!

UNd vielen Dank für die Hilfe!

29.06.2017 - 17:09 Uhr

Sir Rufo, also bei wird auch kein Fehler ausgegeben - nur eben nichts angzeigt. Hast du das im SQLite Manager überprüft? Oder irgendwie anders? Hattest du Daten in eine Tabelle eingetragen und wenn ja von welchem Typ (bei mir sind die Werte unter der Column time als DATETIME abgelegt - bei dir string?) Ich bin mir nicht sicher, aber ich denke mal, es dürft ja keinen Unterschied machen, ob ich meiner C# app eine Methode aufrufe, die selbige Query ausführt oder das im Manager teste. Oder liege ich da falsch? Ich habe schon befürchtet, dass das wieder so ein Fehler ist, wo irgendwas ganz anderes schiefgeht, die Frage ist nur was? Ich mache nix anderes, als meinen Query und die Tabelle im SQLit Manager zu testen?

Dennoch vielen Dank, für's ausprobieren! Vielleicht kannst du meine Fragen von oben noch beantworten, möglicherweise hilft mir das weiter.

29.06.2017 - 16:31 Uhr

verwendetes Datenbanksystem: <SQLite>

Hallo,

ich hatte mit Datumswerten noch nicht wirklich viel zu tun und habe folgende Frage zum Thema "Zeitspanne" ermitteln:

Ich habe eine Tabelle DateTime2_Table. Diese besteht aus den Spalten "id" (INTEGER) und "time" (DATETIME -- kann zwar unter SQLite Manager ausgewählt werden, aber mir will scheinen da wird nur ein String übergeben?).

Meine Tabelle enthält 10 Einträge in der Spalte time, nach dem Schema:
yyyy-MM-dd hh:mm:ss

Ein Aufruf wie:

SELECT * FROM DateTime2_Table WHERE time >= '1983-03-04' AND <= '1990-08-08'

liefert problemlos die gesuchten Einträge.

Was ich nicht verstehe:
Wieso liefert

SELECT * FROM DateTime2_Table WHERE time >= '1996-01-01' AND <= '1996-12-31'

keinen Eintrag, obwohl ein Eintrag in der Tabelle wie folgt lautet: 1996-04-06 00:00:00 ?
Tatsächlich scheint die Abfrage sich nur jeweils auf die volle Jahreszahl zu konzentrieren und Monate und Tage außer Acht zu lassen. Auch mit BETWEEN kam ich nicht weiter - das Resultat blieb das Gleiche.

Vielen Dank für eure Hilfe, ich schätze nach all den Stunden suchen stehe ich nur aufm Schlauch...
Gruß

16.07.2016 - 21:13 Uhr

Kurze Rückmeldung: ich konnte das Problem lösen! Vielen Dank an alle Helfer!

Das Problem war - wie hier schon richtig vermutet - das Warten auf ein Ereignis, das schlicht nicht eintreten konnte. Zwei Fehler gingen dem Voraus: meine Unerfahrenheit (vergessen eine Connection zu schließen) und dazwischen eine Methode, die auf einen Zugriff auf die Datenbank wartete, der aber so nicht eintreten konnte.

Ich habe zwar jetzt viel Zeit ins Debugging investiert, aber es hat sich sehr gelohnt. Aus Fehlern lernt man tatsächlich 😃

Dankeschön @ all!

12.07.2016 - 21:22 Uhr

Danke für deine Antwort. OK, ich will jetzt nicht die Geschmacksfrage stellen, muss dennoch kurz darauf zu sprechen kommen:

In Deinem funktionierenden Beispiel wird ja auch genau so verfahren.
das vielleicht schon, aber die ursprüngliche Absicht mich vor SQL-Injections abzusichern - die bleibt bei diesem Vorgehen ja außen vor. Wie würde denn ein kurzer Schnippsel Code aussehen, der das berücksichtigt?

12.07.2016 - 19:41 Uhr

Blöde Frage: Du hast die Db schon vorher erstellt, oder?

Ja, habe ich 😉

ich konnte deinen Code jetzt noch nicht testen - bin gerade erst heim gekommen. ABER: ich habe mal meinen Code, hm, "zurückgebaut" und festgestellt, dass u. a. folgender Codeblock Probleme macht, und zwar:

public object LoadDataGridView(string tableName)
        {
            try
            {
                //Connection erstellen --> der connectString gibt dabei den Pfad an.
                SQLiteConnection myConnection = new SQLiteConnection(connectStringPath);

                //Verbindung zur Datenbank öffnen
                myConnection.Open();

                //Einen Befehls-String erstellen, der den gewünschten SQLite-Befehl enthält (i.d.F.: SELECT *)
                string myCommandString = "SELECT * FROM @tableName";

                //Die Variable @tableName mittels SQLite-Befehl an einen SQLite-Parameter übergeben
                SQLiteCommand myCommand = new SQLiteCommand(myCommandString, myConnection);
                myCommand.Parameters.AddWithValue("@tableName", tableName);

                myCommand.ExecuteNonQuery();
               
                //DataAdapter erzeugen, der die Daten für das DataGridView "adaptiert" und einen DataTable der die Adapterdaten entgegennimmt
                SQLiteDataAdapter myAdapter = new SQLiteDataAdapter(myCommandString, myConnection);
                DataTable myTable = new DataTable();

                //Table füllen, Verbindung schließen und das DataTAble-Object mit Hilfe der object-Variable an die aufrufende Methode zurückgeben
                myAdapter.Fill(myTable);
                myConnection.Close();

                return myTable;
            }   
            catch(SQLiteException e)
            {
                MessageBox.Show(e.ToString());
                return null;
            }                  
        }

Das ist Code, der obigem Code zuspielt - die Problemstelle ist auch vollkommen klar, sie liegt hier:

myCommand.Parameters.AddWithValue("@tableName", tableName);

                myCommand.ExecuteNonQuery();
               

Wenn ich nämlich diese Zeilen auskommentiere und statt dem @tableName das Ganze so mache,

string myCommandString = "SELECT * FROM '" + tableName + "';

dann funktioniert es. Ich wollte mit @tableName eigenlich SQL-Injections vorbeugen. Ich hatte ähnlichen Code schon mal im Projekt verwendet, und da funktioniert es so:


SQLiteConnection myConnection = new SQLiteConnection(myConnectionString);

//Verbindung öffnen
myConnection.Open();

//String mit Variablen
string comString = "INSERT INTO Konten (id, Name, Nummer) VALUES (@id, @Name, @Nummer);

SQLiteCommand myCommand = new SQLiteCommand(comString, myConnection);

//Die Variable @tableName mittels SQLite-Befehl an einen SQLite-Parameter übergeben
myCommand.Parameters.AddWithValue("@id", id);
myCommand.Parameters.AddWithValue("@Name", Name);
myCommand.Parameters.AddWithValue("@Nummer", Nummer);

//Ausführen
myCommand.ExecuteNonQuery();

myConnection.Close();

Wie gesagt, die Chose funktioniert. ABER: ich vermute mal stark, dass ein konzeptionelles Missverständnis vorliegt - womöglich seht ihr das an meinen Kommentaren. Nach meinem Verständnis hätte es funktionieren müssen; ich weiß jetzt wie es funktioniert (s. CodeBlocks 3+4) bin aber unglücklich von dem @ abrücken zu müssen, weil man allenthalben liest, dass man so effizient Injections verhindert 😦 Sorry, wenn das sehr noobish rüwwerkommt, aber man kann sich noch so viel einlesen: vor Fehlannahmen ist man nicht gefeit. Vielleicht könnt ihr mir aber sagen, wie ich es hätte machen sollen damit es funktioniert. Meine Lösung kann nicht der einzige (richtige?) Wes sein, oder?

Danke für eure Inputs - ich werde alles sorgfältig prüfen, bzw. bin mitten im Debugging!

11.07.2016 - 20:24 Uhr

Hey Coffeebean,

vielen Dank für die Tipps - ich bin Hobby-Coder und habe gerade erst die ersten Gehversuche hinter mich gebracht. Deine Hinweise geben mir jetzt mal eine Richtung, wie ich die Fehlersuche sinnvoll angehen kann, das hilft schon eine Menge, sonst wird es ein kopfloses rumprobieren und zusammenklauben.

Weiter gibt es unzählige Beispiele im Netz zu sqlite updates. Hast du dich da an einem orientiert?

Hier muss ich sagen: leider ja. An mehreren^^ Die SQLite-Statements sind nicht umsonst deklarativ, da gibt's also nicht so viele Fragezeichen. Leider dann aber beim Arbeiten mit denselben in C#. Was viele "Erklärer" leider nicht machen, ist a) ihren Stoff didaktisch sinnvoll strukturieren und b) die Funktionsweisen erläutern. Bei mir ist das z. B. ExecuteNonQuery. Die reine Formulierung würde mich darauf schließen lassen, dass ich bei allem, was keine reine Datenbankabrage ist (Lesen) diese Methode nicht benötige. Seltsamerweise taucht sie dann doch in gut der Hälfte aller Fälle auf, wenn es um INSERT und UPDATE geht.

Konkret orientiert habe ich mich hieran, daran, und dort.

11.07.2016 - 19:57 Uhr

Hey T-Virus,

du wirst wohl leider recht haben. Ich will/wollte aber auch niemanden zum Raten anhalten - ich hatte die leise Hoffnung, bei den Pros würden die Glocken läuten, weil ich vielleicht einen ganz offensichtlichen Fehler gemacht hätte. Dem scheint leider nicht so zu sein.

Dennoch Danke für eure Hilfe.

11.07.2016 - 19:42 Uhr

Und was sagt die Fehlermeldung?

Tja...das ist mein Problem - gar nichts: das Programm friert einfach ein und ich muss in der Taskleiste VS anklicken, um das Programm händisch abzubrechen (Stopp).

Ich habe in meinen Connection-String jetzt übrigens auch mal Read Only = false eingefügt. Ändert leider auch nix...

11.07.2016 - 19:18 Uhr

Hi Th69,

mein Code schaut jetzt so aus (einzige Veränderung zu oben: ich habe int i = cmd.ExecuteNonQuery eingefügt):


string myConnectionString = @"Data Source : C:\MyDataBase\Finanzplaner.sqlite; Version = 3";

SQLiteConnection myConnection = new SQLiteConnection(myConnectionString)

SQLiteCommand cmd = new SQLiteCommand();
                    cmd.CommandText = "UPDATE Konten SET Saldo = 100 WHERE Kontoname = 'Giro_Konto'";
                    cmd.Connection = myConnection;
                    myConnection.Open();

int i = cmd.ExecuteNonQuery();

MessageBox.Show(i.ToString());


Jetzt läuft der Code nicht mehr zum Ende durch - bei der Zeile


int i = cmd.ExecuteNonQuery();

schmiert das Programm ab. Ist mir ein völliges Rätsel.

Nur mal eine doofe Anfängerfrage: ist es denkbar, dass ich mir am System was zerschossen habe? Oder: Mir kommt es fast so vor, als wäre es mir aus Visual Studio raus nur möglich lesend auf die Datenbank zuzugreifen - ist sowas möglich? Irgendwelche Admin-Rechte nötig?

Alles was ich bisher mit der Datenbank gemacht habe, waren einfache Abfragen. Insert und Update funktionieren nur, wenn ich den SQLite Manager ranziehe ("SQL ausführen").

11.07.2016 - 17:48 Uhr

Hallo,

ich nutze in Visual Studio 2015 SQLite 3. Meine Datenbank erstelle und bearbeite ich mit dem SQLite Manager unter Mozilla.

Leider habe ich derzeit folgendes Problem und komme echt nicht weiter:

Ich habe eine WinForm-Anwendung erstellt, die u. a. auf eine SQLite Datenbank zugreift. Das Lesen von der Datenbank funktioniert prima: ich fülle DataGridViews und kann einzelne Labels mit Werten aus der Datenbank füllen. Soweit also alles prima.

Problematisch wird es beim Schreiben in die Datenbank, bzw. beim Update. Folgendes Problem: ich möchte in einem Table einen Wert, der zuvor in einer Textbox zu Verfügung gestellt wird, in der Datenbank ablegen. Um das Ganze ein bisschen anschaulicher zu gestalten: stellt euch ein Konto vor. In die Textbox wird ein Betrag x eingetragen, der in einer Methode mit dem alten Betrag verrechnet wird (alt + neu also). Der Einfachheit halber habe ich jetzt auf sämtlichen SchnickSchnack verzichtet (z.B. Übergabe des Textboxinhalts per Variable und dergleichen) und in den CommandText meinen SQL-Befehl ausgeschrieben.

In diesem Fall soll der Wert "100" in den Table "Konten" geschrieben werden, in die Spalte "Kontoname", in die Zeile deren Eintrag "Giro_Konto" zugeordnet ist. Ich habe versucht das so zu lösen:



string myConnectionString = @"Data Source : C:\MyDataBase\Finanzplaner.sqlite; Version = 3";

SQLiteConnection myConnection = new SQLiteConnection(myConnectionString)

SQLiteCommand cmd = new SQLiteCommand();
                    cmd.CommandText = "UPDATE Konten SET Saldo = 100 WHERE Kontoname = 'Giro_Konto'";
                    cmd.Connection = myConnection;
                    myConnection.Open();

Der Code wird zwar durchlaufen, aber der Wert wird in der Datenbank nicht geupdated. Erschwerend kommt hinzu, dass keine Exception ausgelöst wird.

Ich habe dazu verschiedene Codeschnippsel ausprobiert, die alle die Datenbank updaten sollen - obiger ist sozusagen nur der letzte Entwurf^^ Aber ich bin mit meinem Latein gerade echt am Ende.

Ich habe den CommandText im SQLite Manager getestet - dort funktioniert er tadellos.

UPDATE Konten SET Saldo = 500 WHERE Kontoname = 'Giro_Konto'; 

Dort steht dann tatsächlich 500 an der entsprechenden Stelle, wo zuvor der alte Betrag stand.

Heute morgen hatte ich den Code-Block noch um


try
{
    if (myConnection.State == ConnectionState.Open)
     {
       //Messagebox ("OK ")
      }
      else
      {
      //Messagebox ("Fehlschlag")
       }
catch (SQLiteException e)
{
//MessageBox.Show(e.Message);
}

ergänzt. Per Einzelschritt konnte ich lediglich feststellen, dass der Code wie gewünscht durchlaufen wird - nur, dass eben nix in der Datenbank landet.

Jemand eine Idee, was ich (alles) falsch mache?
Gruß
Vorph

15.06.2016 - 13:37 Uhr

Hallo und zunächst mal Danke für die Antworten!

@Abt: War noch mal auf GitHub und dort taucht immer wieder das NAudio Toolkit auf. Das schaut recht übersichtlich aus, es gibt Beispielprojekte und jede Menge Code zum Analysieren. midi-dot-net schau ich mir auch mal an - MIDI selbst ist ja auch schon etwas "älter".

@Scavanger: Hui - jetzt bringst du mich auf eine alte Fährte zurück! Ich hatte tatsächlich schon an den Raspberry Pi gedacht (hatte mit Arduino bisher nix zu tun). Mit dem Lötkolben bin ich vertraut - das alleine wäre nicht das Problem. Ich hatte eher den Gedanken: wozu einen Einplatiner, wenn ein USB-Relais reicht? Zumal man ein 8Kanalrelais für 30 Euro bei Conrad abstauben kann. Dennoch: ich hatte auch schon mit der Idee geliebäugelt. Vlt. kannst du mir ja noch ein paar Pro-Statements liefern - wie gesagt, bin da noch offen.

viele Grüße

13.06.2016 - 21:39 Uhr

Hallo,

heute habe ich ein (hoffentlich) ganz einfaches Problem, zumindest klingt es banal, auch wenn das natürlich täuschen kann.

Mein Vorhaben:
Ich werkele zur Zeit an einem Home-Recording Studio rum. Herzstück ist ein Digitalmischpult (ein Tascam Dm3200, das leider nicht mehr hergestellt wird). Das Studio wird später aus zwei Räumen bestehen, die so konstruiert wurden, dass sie relativ schalldicht sind.
Ich möchte daher in einem Raum eine Lampe/LED o.ä. anbringen, die immer genau dann aufleuchtet, wenn ich am Digipult die "Aufnahme"-Taste betätige.

Nun ist es glücklicherweise so, dass das Digipult sämtliche Transport-Befehle (Vor, Zurück, Start, Stopp und AUfnahme) per MIDI via USB-Anschluss an den Computer sendet. Hier kam mir jetzt die Idee, diese MIDI-Befehle abzufangen und für meinen Zweck zu verwenden.

Im Prinzip bräuchte ich doch nur ein USB-Relais und entsprechenden Code, der die MIDI-Befehle ausliest und beim entscheidenden Befehl das Relais schaltet.

Liege ich da richtig?

Meine Frage bezüglich C#: es scheint mehrere Möglichkeiten zu geben eine MDI-Lib per using-Direktive einzubinden (Naudio? Ich kann mich leider nicht mehr an den Namen erinnern). Bereits hier bräuchte ich Hilfe.

Die MSDN-Referenz erschlägt mich hier eher statt zu helfen: ich hätte einen Aufnahme-Befehl im MIDI-Stream erwartet, aber laut Referenz gibt's da keinen Eintrag "record". Oder ich schau schlicht unter dem falschen Stichwort nach...

Falls mir jemand Tipps geben könnte, wie ich mich am besten an dieses Projekt heranwage, schon mal jetzt vielen Dank!

Vielleicht hat ja jemand schon mal was ähnliches gemacht und kann mir ein USB-Relais empfehlen?

viele Grüße
Vorph

13.06.2016 - 21:18 Uhr

Zwar spät, aber dennoch: Danke für eure Antworten! Ich habe mich jetzt über verschiedene Quellen eingelesen - und ihr hattet (natürlich) recht 😃 State-Machine ist genau das, was ich gesucht habe: ist aber um Längen komplexer, als ich gedacht hätte. Aber: packen wir's an! Vielen Dank für eure Hilfe!!

19.05.2016 - 23:48 Uhr

Hallo,

ich programmiere derzeit an einem kleinen RPG im Pen&Paper-Stil. Vielleicht erinnern sich einige: Würfel, Papier, Monster metzeln 😉

Jedenfalls: ich habe eine User-Form mit einem Button, der eine Zufallszahl (int) zwischen 1 und 20 generiert (also als 20seitiger Würfel fungiert).
Außerdem ein zweiter Button, der zu Testzwecken derzeit lediglich eine Methode startet, die überprüft ob der Spieler oder der Computer den rundenbasierten Kampf eröffnet.

Button 2 ruft folgende Methode auf:


public void Kampfrunde(bool initSieger, int LPSpieler, int LPComp int TPSpieler, int TPComp)
        {
            //Initiativrunde
            if (initSieger == true)
            {
                MessageBox.Show("Du greifst an! Würfle mit W20 unter deinen Attacke-Wert...");
                //btnW20 = AT_Spieler;
                //btnW20 = Pa_Comp;

                Attacke(5,5);
            }
            else
            {
                Parade(7,8);
            }

            //Folgerunden

        }

Mich beschäftigt eigentlich nur eine Frage - ich befürchte sogar, ich weiß die Antwort, aber ich wollte noch euere Bestätigung bzw. ggf euer Veto:

  • nach der MessageBox müsste der Spieler eigentlich Button 1 (die Würfelschaltfläche) betätigen, BEVOR die Methode Attacke() aufgerufen wird. Gibt es eine Möglichkeit, dies an dieser Stelle abzufragen/einzubauen?
    Vom Gefühl her denke ich mal eher nein - meines Wissens ist es nicht angebracht ein Warten zu erzwingen; ich habe zwar eine Lösung die funktioniert, nur ist die sehr viel "umständlicher" (?) programmiert.

lg
Vorph

16.11.2015 - 21:45 Uhr

Nochmals vielen Dank! Dank deiner Hilfe hatte ich heute mein erstes (Datenbanks-)Erfolgserlebnis 😄 SQLite ist genau richtig und diese Tutorials waren echt Gold wert! Nach ca. einer Stunde Einarbeitung konnte ich mein Prog jetzt endlich mal MIT DB testen.
Ich fall vom Stuhl 😄

Problem gelöst!

16.11.2015 - 08:12 Uhr

Das Problem ist, das das in der IDE zu einfach gemacht wird und dann einsteigern die nicht wissen was das einzelne ist, regelrecht ins offene Messer laufen.

Ich befürchte, ich bin nicht zum ersten Mal in dieses Messer gelaufen^^

  1. Vergessen die Leute dann das man zum betrieb der DB einen Server installieren muss ( der auch noch LocalDB können muss ).

Ich fürchte, dass genau das passiert ist - extra etwas installiert habe ich nämlich nicht. Und die Hinweise im Programm (Verbunden mit Datenbankdatei [Datei - alles klar! Das wird mir jetzt erst richtig bewusst]) hat sein übriges getan, um die Konfusion aufrecht zu erhalten.

Danke für den Hinweis bezüglich SQLite - ich hatte dazu mehrfach im Forum Einträge dazu gelesen, wähnte mich aber durch meine IDE bereits als vollausgestattet 😉 Werde ich mir noch heute installieren.

Einstweilen vielen Dank, FZelle!

Viele Grüße

15.11.2015 - 20:51 Uhr

Danke für deine Antwort, FZelle.

Wie meine ich das zu machen? Hm, Datei-->Alles Speichern (bzw. das Icon in der Menüleiste mit den zwei Disketten...). Nach oben erwähntem Video-Tut wähnte ich mich damit auf dem richtigen Weg. Doch nicht richtig?

Bezüglich deiner zweiten Frage: ich würde dir das gern beantworten, kann es leider nicht. Dazu fehlt mir vermutlich Kenntnis/Basiswissen; ich hatte gehofft, meine Angaben dahingehend würden das abdecken - sorry, wenn das nicht der Fall ist. Gehe ich im Server-Explorer dazu über eine neue Verbindung hinzuzufügen (mit Datenbank verbinden), finde ich unter Datenquelle im "Verbindungen hinzugen"-Dialog lediglich den Eintrag Microsoft SQL Server-Datenbankdatei (SqlClient). Verbinde ich falsch? Muss da noch ein Schritt vorher dazu?

Ich würde gerne mal was Richtung lokale Datenbank machen und im Netz hat es Unmengen von Tutorials, aber wenn ich diese nachvollziehen möchte, scheitert es (mal abgesehen von meinen Kenntnissen) oft daran, dass ich die Schritte auch technisch nicht nachvollziehen kann.

15.11.2015 - 16:45 Uhr

verwendetes DB-System: Microsoft SQL Server-Datenbankdatei

Visual Studio Community Version (2015)

Hallo,

leider ist mein Problem nicht ganz neu; in der Tat, wenn ich die entsprechenden Begriffe in die Suche eingebe, komme ich immer wieder bei einem Thread raus, den ich selbst vor vier Monaten gestartet hatte. Damals war die Sachlage ein kleinwenig anders, zwischenzeitlich bin ich nicht mehr zum Coden gekommen (reines Hobby), wollte aber jetzt den Faden nochmal aufnehmen.

Folgendes:
Ich möchte einfach eine lokale Datenbank erstellen, darin eine Tabelle anlegen und darauf zugreifen. Im Prinzip beziehe ich mich dabei immer noch auf das Rheinwerk-Video, das ich damals schon angesprochen habe.
Hab' mir grad eben den Thread noch mal durchgelesen - falls der Admin Abt das hier liest: ich schätze, ich hab dein Hilfe-Tipp entweder nicht richtig verstanden oder bei mir ist evtl. was falsch eingerichtet.

Und so gehe ich vor:

  1. Neues Projekt (Windows Forms Application)
  2. Im Projektmappen-Explorer Rechtsklick auf mein Projekt
  3. "Hinzufügen --> Neues Element --> Dienstbasierte Datenbank"
  4. Bei Name gebe ich "TestDB" ein
  5. Auf "Hinzufügen" klicken
  6. Im Server-Explorer wird die Datenbank angezeigt (mit einem roten X)
  7. Datenbank wird angeklickt (Unterordner werden ausgeklappt, das rote X verschwindet und wird durch einen kleinen grünen Pfeil ersetzt, der offenkundig anzeigt, dass nun eine Verbindung vorliegt)
  8. Rechtsklick auf den Tabellen-Ordner
  9. "Neue Tabelle hinzufügen"
  10. In der Tabelle mache ich dann zwei, drei Testeinträge und speichere dann alles
  11. Es erscheint der Speicherndialog: unter Dateiname steht als default "dbo.Table.sql"; diesen ersetze ich durch FirstTable und klicke auf Speichern
  12. Obwohl der Dialog geschlossen und die Datei FirstTable tatsächlich erstellt wird (kann ich im Win Explorer finden), bleibt im Tabellen-Tab weiterhin der Name "dbo.Table Entwurf" stehen mit einem Sternchen dahinter; auch nach "Aktualisieren" befindet sich die Tabelle nicht im Ordner "Tabellen" im Server-Explorer

Was genau mache ich falsch? Hab ich zuvor einen Schritt vergessen? Als Datenquelle bekomme ich "Microsoft SQL Server-Datenbankdatei(SqlClient) angezeigt, aber das müsste eigentlich stimmen, oder?

Jedenfalls: für sachdienliche Hinweise bin ich sehr dankbar

Gruß
Vorph

19.07.2015 - 21:24 Uhr

Danke, Abt, das werde ich tun. Schade, dass man im Rheinwerk-Tutorial nicht darauf hingewiesen wird - ich finde das dort etwas kurz skizziert (es gibt auch noch Folgevideos, mit denen man als Anfänger zwar recht schnell Erfolge erzielt, aber - leider - nicht wirklich was versteht...)

viele Grüße
Vorph

19.07.2015 - 19:00 Uhr

Hm, ich glaube, so langsam kommt dabei ein Bild raus. Ich versuche mal, nach bestem Wissen zu antworten:

@Abt:

Verbindest Du Dich direkt auf eine MDF-Datei (was nicht zu empfehlen ist) oder ist diese an einem DB-Server "attached" ?

Ich mach's so, wie im Video:

  1. Im VS den Datenbanken-Explorer öffnen
  2. "Mit Datenbank verbinden" --> hier kann ich im Dialogfenster nach der Datenbankdatei suchen (ist in einem eigenen Ordner" und klicke dann "öffnen". Ursprünglich funktionierte das - jetzt halt die Fehlermeldung. Kurze Antwort auf deine eigentliche Frage: ich befürchte ja?

@RED-BARON
Also, ich habe mit Hilfe der msdn-Gewusst wie versucht das Problem zu lösen; danach habe ich deinen Lösungsvorschlag gestartet (nach einem Neustart des PCs). Aus irgendeinem Grund bekomme ich dieselbe Fehlermeldung. Dann ist mir aufgefallen, dass ich im Fenster SQL-Server-Objekt-Explorer unter der Serverinstanz meines PCs unter "Datenbanken" --> "Systemdatenbanken" --> "Test" tatsächlich meine Datenbank finde, mitsamt der Tabellen - hier aber jeweils dbo.<Tabellenname>. Scheints hat sich hier was verschlimmbessert? Jedenfalls: so wie im Video, einfach per drag&drop die Tabelle auf ein Datagridview ziehen is so nicht; das ging scheinbar nur aus dem Datenbank-Explorer heraus?

Was mich halt wundert: im Datenbank-Explorer wird mir unter Datenverbindungen absolut nichts angezeigt, wohingegen im SQL-ServerOE sowohl Datenbank, als auch Tabellen vorhanden sind. Evtl. muss ich die Datenbank mit Code ansprechen, vielleicht generiert das einen aussagekräftigeren Fehler.

Bin leider etwas ratlos.

Und der msdn-Artikel aus meinem 1. Post? Ist das ein Ausganspunkt?

19.07.2015 - 16:03 Uhr

Hallo,

ich versuche mich derzeit etwas intensiver in das Thema Datenbanken einzuarbeiten.

Ich habe für mein Projekt mit Hilfe des SQLServer Management Studio eine Datenbank erstellt (Test.mdf). Dabei habe ich mich an die Vorgaben dieses Videos gehalten.

Das hat soweit funktioniert und ich konnte die Datenbank später in Visual Studio in mein Projekt einbinden.

Jetzt das Problem: später habe ich dann im Management Studio zwei neue Tabellen hinzugefügt. Diese werden zwar im Management Studio angezeigt, nicht aber später im Projekt in VS. Alles Aktualisieren hat leider nicht geholfen. Die Datenbank löschen und die Verbindung neu herstellen geht leider auch nicht, dann erhalte ich folgende Fehlermeldung:

Fehlermeldung:
Test.mdf
Die Datei wird verwendet.
Geben Sie einen anderen Namen ein, oder schließen Sie die Datei in dem anderen Programm.

Leider kann ich mir nicht ansatzweise vorstellen, was mir diese Fehlermeldung sagen will: ich habe kein Programm geöffnet, von dem ich wüsste, dass es auf die Datenbankdatei zugreift. Ich habe jetzt stundenlang Internetrecherche betrieben und bin lediglich bei diesem Thema der msdn-Dokumentation hängengeblieben. Ich werde leider nicht schlau drauß, ob das genau mein Problem schildert. Eigentlich hätte ich gedacht, dass ein nachträgliches Hinzufügen einer Tabelle eher einen "gewöhnlichen" Vorgang darstellt; nun bin ich wieder schlauer und stelle fest: Datenbanken werden "Pen&Paper" geplant^^

Für sachdienliche Hinweise vielen Dank im Voraus,
Gruß
Vorph

10.02.2015 - 14:47 Uhr

Oh Mann! Bin ich doof! Ich habe versucht den exakt gleichen Wert einzugeben, wa? Kann es sein, dass damit der Key zweimal vergeben wird? Dann dürfte das die Erklärung sein...kanns leider erst heute abend testen 😦

Falls ich richtig liege: gibt's da ne elegantere Lösung, als das mit einer Ausnahme abzufangen? Für mein Vorhaben sind sporadisch auftretende gleiche Werte im wahrsten Sinne des Wortes vorprogrammiert!

Sollte ich komplett daneben liegen: post me 😉

Gruß
Thorsten

10.02.2015 - 14:37 Uhr

Hallo robbyrc und coffeebean,

durch euere Hinweise bin ich ein Stückchen weitergekommen! Vielen Dank dafür.

Zunächst einmalt: es war tatsächlich der Initial Catalog, der letztlich zu fehlen schien! Ich habe diese Codezeile dahingehend geändert, das Programm gestartet und siehe da: kein Gemeckere mehr, das hat funktioniert!

Ich habe allerdings eine Sache festgestellt, deren Logik mir sich noch nicht so ganz erschließt:

wenn ich in meine Textbox den Wert 1000 schreibe und das Buttonevent auslöse, dann schreibt das Programm den Wert in die betreffende Spalte der Tabelle.
Das funktioniert für alle Werte verschieden von 1000; so könnte ich - hintereinander - die Werte 60, 400, 289,67 oder 10000 eingeben: brav werden diese entgegengenommen. Gebe ich aber z. B. 10 ein und gleich anschließend nochmal 10, bekomme ich folgende Fehlermeldung:

Fehlermeldung:
"Ein Ausnahmefehler des Typs "System.Data.SqlClient.SqlException" ist in System.Data.dll aufgetreten.

Zusätzliche Informationen: Verletzung der PRIMARY KEY-Einschränkung 'PK_tblOverview'. Ein doppelter Schlüssel kann in das dbo.tblOverview-Objekt nicht eingefügt werden. Der doppelte Schlüsselwert ist (2000.00).

Die Anweisung wurde beendet."

[Anmerkung: ich hatte zweimal hintereinander den Wert 2000 eingegeben]

Meine Frage diesbezüglich: der eingegebene Wert sollte den Key der Spalte doch gar nicht beeinflussen, oder (Spalte = Primary Key)? Werden da irgendwelche Zugriffsrechte verletzt? Wie im ersten Post beschrieben: ich habe EINE Datenbank mit EINER Tabelle, die genau ZWEI Spalten hat, wobei diese den Primary-Key hat (s. JPEG).

Gruß
Thorsten

P.S: @Coffeebean: Danke für die Links - das mit der Drei-Schicht-Architektur finde ich dort endlich mal sehr anschaulich beschrieben! Danke!

09.02.2015 - 22:15 Uhr

verwendetes Datenbanksystem: MS SQL Server

Hallo,

dies ist mein erster Post hier im Forum. Ich habe bislang vorrangig mit VBA zu tun gehabt und unternehme seit kurzem meine ersten Gehversuche mit C#.

Ich taste mich noch an C# heran und bin derzeit bei einem Problem angelangt, bei dem ich einfach nicht den richtigen Zugang zur Lösung bekomme.

Im Prinzip ist mein Setting ganz einfach (Beschreibung des erwarteten Verhaltens):
ich habe eine Windows Forms Anwendung, bestehend aus einer Form nebst zwei Textboxen und einem Button. Der Button soll beim Auslösen des Click-Events Zifferneingaben des Users in den Textboxen an eine Tabelle einer Datenbank übermitteln.

Mit dem MS SQL Server Management Studio habe ich eine Datenbank erstellt, die derzeit lediglich eine Tabelle mit zwei Spalten beinhaltet. Diese Tabelle möchte ich ansprechen.

Ich habe in Visual Studio 2013 eine Verbindung zur Datenbank hergestellt und die Datenbankdateien in den Projektordner kopiert.
Wie gesagt, die Anwendung wurde zum Ausprobieren angelegt und ist daher sehr simpel. Hier mein Code unter Form1.cs:


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
// von mir hinzugefügter Code:
using System.Data.SqlClient;

namespace Datenbank_Test
{
    public partial class Form1 : Form
    {
        SqlConnection conDB = new SqlConnection("Data Source=ARBEITS-PC;Integrated Security=True;Connect Timeout=15;Encrypt=False;TrustServerCertificate=True");

        public Form1()
        {
            InitializeComponent();
        }

        private void btnToDB_Click(object sender, EventArgs e)
        {
                SqlCommand cmdDB = new SqlCommand("Insert into tblOverview (accStatus, savingsStatus) Values(@accStatus, @savingsStatus)", conDB);

                cmdDB.Parameters.AddWithValue("@accStatus", Convert.ToDecimal(txtGiro.Text));
                cmdDB.Parameters.AddWithValue("@savingsStatus", Convert.ToDecimal(txtSavingsVal.Text));

                conDB.Open();
                cmdDB.ExecuteNonQuery();
                conDB.Close();
                
            
        }
    }
}

Den Pfad der Datasource habe ich aus der Eigenschaftenbox des SQL Server-Objekt-Explorers entnommen und einfach kopiert.

Fehlerbeschreibung:
Der Code wird ausgeführt, jedoch mit einer Fehlermeldung abgebrochen. Hier der Wortlaut:> Fehlermeldung:

Ein Ausnahmefehler des Typs "System.Data.SqlClient.SqlException" ist in System.Data.dll aufgetreten.

Zusätzliche Informationen: Ungültiger Objektname 'tblOverview'.

Nach dem Beenden der Anwendung ist die Zeile

cmdDB.ExecuteNonQuery();

markiert. Die von mir eingegebenen Werte wurden jedoch nicht in die Datenbanktabelle übernommen (Null).

Was mich gänzlich irritiert ist der Hinweis "Ungültiger Objektname". Der Name der Tabelle tblOverview ist korrekt, aber scheinbar habe ich einen entscheidenden Verweis o.ä. übersehen. Oder denke ich komplett in die falsche Richtung? Jedenfalls: "Ungültiger Objektname" lässt mich jetzt schon seit gestern nach einem Fehler bei der Implementierung suchen - aber vlt. renne ich auch gerade in die falsche Richtung^^

für sachdienliche Hinweise schon mal vorab vielen Dank,

Gruß
Thorsten