Autor Beitrag
mocede
Hält's aus hier
Beiträge: 7

Windows 7
C# (VS 2010 #Express )
BeitragVerfasst: Mi 31.12.14 15:51 
Hallo Freunde,

ich habe ein kurioses Problem beim Schreiben von Daten aus TextBoxen in eine Datenbank.

Eigentlich ist dies ja gar nicht schwer und wurde von mir auch erfolgreich bereits einige male durchgeführt. Das Problem ist, dass ein und der gleiche Quelltext, nur bei 2/3 Datenbanken funktioniert. Ich begreiff das nicht!

Aber immer der Reihe nach:

Als erstes lese ich aus einer großen Form alle Textboxen aus und weise den Inhalt jeweils einer string- oder int-Variable von einem neu erstellten Objekt einer selbstgeschriebenen Klasse zu.
Als nächstes rufe ich eine eigene Methode für die Datenbankverbindung auf, welcher ich lediglich noch den SQL-String übergebe. Die SQL Anweisung schreibt mir die Inhalte aus den Textboxen in meine Datenbank. Leider klappt das nur bei 2 von 3 Datenbanken. Warum kann ich mir nicht erklären. Es gibt keine Fehlermeldungen, es fliegen keine Exceptions und wie gesagt - bei 2 anderen Datenbanken funktioniert es.

Zu Testzwecken versucht erstmal ein Feld, den Namen der Person, in die Datenbank zu schreiben. Wenn das klappt, sollte der Rest simultan sein, jedoch finde ich meinen Fehler nicht.

Bei Klick des Buttons:
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
        //Button "Add"
        private void btn_AddNewPerson_Add_Click(object sender, RoutedEventArgs e)
        {
            Personen person = new Person();

            //Zuweisung der Eingaben zur neuen Person
            person.bezeichnung = txt_AddNewPerson_bezeichnung.Text;
            person.firma = txt_AddNewPerson_firma.Text;
            ...
            
            person.fabrikationsnummer = Convert.ToInt32(txt_AddNewPerson_fabrikationsnummer.Text);
            person.baujahr = Convert.ToInt32(txt_AddNewPerson_baujahr.Text);
            ...
 
            //Test-SQL Anweisung zum Probieren
            string sqlcommand = string.Format("INSERT INTO Personen(Bezeichnung) VALUES ('{0}')", person.bezeichnung);

            DBQuery insert = new DBQuery();
            int erg = insert.DB_Add_Person(sqlcommand);

            if (erg == 1)
                MessageBox.Show("Hinzufügen erfolgreich!");
            else
                MessageBox.Show("Fehler!");
        }


Meine Klasse Personen (gekürzt)
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
    internal class Personen
    {
        public string bezeichnung;
        public string firma;
        ...

        public int fabrikationsnummer;
        public int baujahr;
        ...
    }


..und zu guter letzt meine Methode für den DB Query:
ausblenden volle Höhe C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
        //Methode zum Hinzufügen von Personen
        public int DB_Add_Person(string sqlcommand)
        {
            string path = Environment.CurrentDirectory;
            string db_name = "DB101.MDF";

            //Connection-Objekt zum Verbindungsaufbau zur DB ohne Informationen zur Datenquelle
            SqlConnection con = new SqlConnection();

            //ConnectionString für SqlConnection-Konstruktor mit allen Informationen zur Datenquelle
            con.ConnectionString = @"Data Source=.\SQLEXPRESS;" +
                                   @"AttachDbFilename=" + path + @"\" + db_name + @";" +
                                   "Integrated Security=True;" +
                                   "Connect Timeout=30;" +
                                   "User Instance=True";

            SqlCommand cmd = new SqlCommand(sqlcommand, con);
            //cmd.CommandText = sqlcommand;
            //cmd.Connection = con;

            //Fehlerbehandlung
            try
            {
                con.Open();

                //Man muss aufpassen cmd.ExectueNonQuery nicht zwei mal aufzurufen, da jedes mal Datensätze geschrieben werden!
                int erg = cmd.ExecuteNonQuery();

                if (erg > 0)
                {
                    con.Close();
                    return erg;
                }
                else
                {
                    con.Close();
                    return 0;
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("Fehlermeldung: {0}", ex.Message);
                con.Close();
                return 0;
            }
        }


Meine Datenbank ist ein mittels Visual Studio erzeugtes .MDF File, welches auch der Projektmappe hinzugefügt wurde.
Die Datenbank erhält lediglich - wie gesagt, sind erstmal alles noch Testzwecke um die Fehlerquellen zu minimieren - eine Tabelle namens "Personen" mit einer Spalte namens "Bezeichnung" von Typ nchar(10) (NULL ist nicht zugelassen).

Versuche ich die Änderungen in die Northwind Datenbank zu schreiben (natürlich unter Anpassung der Pfade und des SQL Strings) gibt es keine Probleme. (Sogesehen gibt es die laut dem Compiler und der IDE auch hier nicht, nur die Änderungen werden halt nicht gemacht, was also eine fehlerhafte Funktionalität darstellt).

Es scheint mir, dass der Fehler irgendwo an der Datenbank liegt. Falsche Einstellungen? Wenn ja, welche müssen hier getätigt werden?

Über Hilfe wäre ich sehr dankbar!

Beste Grüße und guten Rutsch!:-)

Edit 1: Mir ist gerade aufgefallen, dass die beiden anderne Datenbanken, welche nicht in meinem Projektmappen-Explorer (und somit im Projekt?!) hinterlegt sind, sondern nur über den Datenbank-Explorer erreichbar sind, die sind, in welche ich problemlos schreiben kann.
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4700
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: Mi 31.12.14 16:16 
Wenn sie zum Projekt gehören hast du das wahrscheinlich so eingestellt das du die Datenbank bei jedem Start in den Ausgabeordner kopierst. Heißt dein Code ändert die Datenbank zwar korrekt im Ausgabe Ordner des Projekts aber beim nächsten Start kopierst du wieder die zum Projekt gehörende (und nicht veränderte) über die geänderte im Ausgabeordner.

In den Datei Properties der Datenbank solltest du mal 'Copy to Output Directory' auf 'Copy if newer' stellen anstatt 'Copy always'.
mocede Threadstarter
Hält's aus hier
Beiträge: 7

Windows 7
C# (VS 2010 #Express )
BeitragVerfasst: Mi 31.12.14 16:37 
Gesagt, getan, doch leider keine Besserung :-/

Moderiert von user profile iconTh69: Beiträge zusammengefasst

Edit 1:

Ich glaube das Problem etwas gelockert zu haben.

In meiner Projektordner gibt es die Datenbank zwei mal - einmal im "gesamten Projektordner" und einmal im bin/Debug/-Ordner. Ich habe die DB aus dem bin/Debug/-Ordner mal entfernt und die aus dem Hauptverzeichnis umbenannt.
Beim Neustart von Visual Studio fehlten beide Datenbanken natürlich. In den Datenbank-Explorer habe ich nun die DB aus dem Projektordner wieder hinzugefügt. Beim Ausführen des Programmes kopiert sich diese in den bin/Debug/-Ordner. Wenn ich mir jetzt die Daten im Datenbank-Explorer ansehe, wurden alle Eintragungen gemacht. Im Projektmappen-Explorer von Visual Studio wird DB100.mdf samt sein DB100_log.mdf anscheinend nicht mehr richtig erkannt. Zumindest besitzen diese beiden Dateien jetzt ein Icon in Form eines weißen Blattes mit einem gelben Ausrufezeichen. Klicke ich wiederum dort drauf, erscheint die gleiche Datenbank nochmals im Datenbank-Explorer, allerdings ohne die Eintragungen.

Alles etwas strang hier, aber ich glaube in der Tat das es etwas mit diesen von Dir angesprochenen Kopieren der Datenbank zu tun hat...

Edit 2:

Hoppla, ausversehen einen Doppelpost erzeugt...
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4700
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: Mi 31.12.14 17:18 
Dann ersetze mal 'Copy if newer' durch 'Do not copy' und kopiere bei Bedarf die Datenbank manuell in den Ausgabe Ordner.
Hab das nochmal in der Doku nachgeschlagen und auch nur ein reinschauen in die Datenbank (z.B. per DB Explorer) ändert die Filetime :( Copy if newer hätte Sinn gemacht wenn nur bei tatsächlichen Änderungen (Daten oder Metadaten) die DB als geändert angenommen wird.

Programm und Daten im selben Ordner zu halten ist übrigens eine schlechte Idee (wegen Write Schutz durch das OS, Backupstrategien etc.).
mocede Threadstarter
Hält's aus hier
Beiträge: 7

Windows 7
C# (VS 2010 #Express )
BeitragVerfasst: Mi 31.12.14 17:29 
Hallo Ralf,

danke für deine Hilfe.

Wieso wird überhaupt die Datenbank kopiert? Ich kann mir gut vorstellen das man das ggf. haben möchte, aber wieso ist das die Standardeinstellung? Hat das eine tiefere Bewandnis?
Warum machst du ein langes Gesicht wenn es die Filetime beim reinschauen in die Datenbank ändert?
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4700
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: Mi 31.12.14 17:40 
Zitat:
Warum machst du ein langes Gesicht wenn es die Filetime beim reinschauen in die Datenbank ändert?


Weil es ein Änderungsdatum sein soll und die Datenbank hat sich ja logisch nicht geändert sondern nur physisch. Es ist schade das Visual Studio hier alle Dateien einfach gleich behandelt und bestimmte Filespezifika (z.B. eben die von Datenbankdateien) nicht berücksichtigt bzw. nicht berücksichtigen kann.