Laden...

Wie erstelle ich ein korrektes INSERT Statement mit Access?

Erstellt von Heino01 vor 3 Jahren Letzter Beitrag vor 3 Jahren 1.218 Views
H
Heino01 Themenstarter:in
7 Beiträge seit 2020
vor 3 Jahren
Wie erstelle ich ein korrektes INSERT Statement mit Access?

Hallo zusammen,

ich hätte da mal eine dumme Anfängerfrage. Habe schon gegoogelt, aber ich finde nichts dazu...

Und zwar kommt, sobald ich "Art" hinzufüge immer der Fehler "Datenkonflikt in Kriterienausdruck". Was ist damit genau gemeint ? Könntet ihr mir auf die Sprünge helfen was ich falsch mache ? Lasse ich nur den "Titel" drin fügt er mir das automatisch in die Datenbank ohne Probleme.

Benutze bei der Datenbank Access und Ausgabe erfolgt in einer Datagridview.

Bin relativ am Anfang mit Datenbanken. Deshalb blicke ich da noch nicht so durch...

Vielen Dank !

private void cmd_speichern_Click(object sender, EventArgs e)
        {
            try
            {
                con.Open();                             // Verbindung herstellen zur Datenbank
                OleDbCommand cmd = con.CreateCommand();
                cmd.CommandType = CommandType.Text;
                cmd.CommandText = @"insert into Aufgabe (Titel, Art) values ('" + txt_titel.Text + "','" + txt_art.Text + "')";  
                cmd.ExecuteNonQuery();
                MessageBox.Show("Auswahl hinzufügen erfolgreich");
                con.Close();

                this.Close();                           //Schließen des zweiten Fensters
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
                return;
            }
        }
16.807 Beiträge seit 2008
vor 3 Jahren

Deutsche Fehlermeldung sind nicht immer optimal, daher empfiehlt es sich immer auf das deutsche SDK zu verzichten.

Der Fehler wird aber womöglich daher kommen, weil Du den SQL Befehl leider genau so zusammen baust, wie man es nicht tun soll 😉
=> [Artikelserie] SQL: Parameter von Befehlen

H
Heino01 Themenstarter:in
7 Beiträge seit 2020
vor 3 Jahren

Vielen Dank, dann werde ich das mal Umstellen...

C
2.121 Beiträge seit 2010
vor 3 Jahren

Grund ist wahrscheinlich dass Art keinen String haben will, aber du übergibst einen.
Testweise kannst du die ' ' um txtArt.Text weglassen und schauen obs dann funktioniert.
Dann aber auf jeden Fall in Parameter umändern!

16.807 Beiträge seit 2008
vor 3 Jahren

Einfach niemals SQL Strings von Hand zusammen bauen, sondern immer Parameter verwenden.
Immer.

463 Beiträge seit 2009
vor 3 Jahren
  
cmd.CommandText = @"insert into Aufgabe (Titel, Art) values ('" + txt_titel.Text + "','" + txt_art.Text + "')";    
  

Ich schreibe SQL Befehle immer komplett in Großbuchstaben, ist leichter zu lesen. Wobei dies hier nicht das Problem ist - nur als Hinweis/Tipp.

Die Lösung hat dir Abt ja bereits gegeben.

C
2.121 Beiträge seit 2010
vor 3 Jahren

Natürlich sollte man Befehle nie so zusammensetzen. Wirklich nie.

Aber verstehen warum es hier einen Fehler gibt, sollte man trotzdem auch.

H
Heino01 Themenstarter:in
7 Beiträge seit 2020
vor 3 Jahren

Ja, genau. Ohne 'Art' funktioniert es problemlos... Sobald ich dies jedoch dazu nehmen buggt es. Ich versuche jetzt nochmal die Parameter auszuschreiben und schaue dann ob es funktioniert... Danke auf jeden Fall für die Hilfe, auch wenn ich gerade ein ziemliches Brett vor dem Kopf habe...

Ist halt nur verwirrend, weil es in dem Buch womit ich mir das beibringe bisschen anders steht.

H
Heino01 Themenstarter:in
7 Beiträge seit 2020
vor 3 Jahren

Ich verstehe noch nicht ganz den Übergang aus dem Beispiel zu Access. Ich habe den Befehl jetzt auseinander gebaut. Doch der Fehler liegt an der Deklarierung. Ich habe das mal anders aufgebaut, jedoch verstehe ich jetzt mein Fehler nicht..


namespace Projekt_DB
{
    public partial class cmd_add : Form
    {
        OleDbConnection con = new OleDbConnection(@"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\Users\Mike\source\repos\Projekt_DB\VerwaltungAufgaben_2020.accdb"); // Connection Databse

        string Titel;
        string Art;

        public cmd_add()
        {
            InitializeComponent();
            txt_prio.Items.Add("1");
            txt_prio.Items.Add("2");
            txt_prio.Items.Add("3");                // Hinzufügen Kombobox
        }


        public void cmd_speichern_Click(object sender, EventArgs e)
        
        {
            try
            {
                con.Open();                                                                     // Verbindung herstellen zur Datenbank
                OleDbCommand cmd = new OleDbCommand("INSERT into Aufgabe (Titel, Art)");        // Hinzufügen in Datenbank
                cmd.CommandText = ("VALUES (@txt_titel, @txt_art");                             //Textbox auslesen

                cmd.Parameters.AddWithValue("@txt_titel", Titel);                               // @ -> Positionsparameter
                cmd.Parameters.AddWithValue("@txt_art", Art);

                cmd.ExecuteNonQuery();
                MessageBox.Show("Auswahl hinzufügen erfolgreich");
                con.Close();

                this.Close();                                                       //Schließen des zweiten Fensters

            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
                return;
            }
        }

J
251 Beiträge seit 2012
vor 3 Jahren
  
  
                OleDbCommand cmd = new OleDbCommand("INSERT into Aufgabe (Titel, Art)");        // Hinzufügen in Datenbank  
                cmd.CommandText = ("VALUES (@txt_titel, @txt_art");                             //Textbox auslesen  
  
                
  

Hast Du Dir mal den CommandText im Debugger angeschaut?

T
2.219 Beiträge seit 2008
vor 3 Jahren

Dein SQL Statement wird hier falsch erstellt.
Durch cmd.CommandText = überschreibst du deinen im Konstruktor von OleDbCommand erstellten Text.

Warum machst du das Insert mit Values nicht vollständig im Konstruktor?
Dann brauchst du auch die Zeile mit dem CommandText nicht noch zusätzlich.
Ebenfalls solltest du an der Benennung der Parameter arbeiten.
Ich würde die empfehlen diese immer den entsprechenden Spaltennamen zu geben, damit klarer wird was der Parameter bedeutet und wo er hingehört.

T-Virus

Developer, Developer, Developer, Developer....

99 little bugs in the code, 99 little bugs. Take one down, patch it around, 117 little bugs in the code.

H
Heino01 Themenstarter:in
7 Beiträge seit 2020
vor 3 Jahren

Ja, beim debuggen habe ich eben gesehen, dass der Wert 0 weitergeben wird. Also trifft das zu, dass es überschrieben wird. Aber es hieß doch, dass ich keinen SQL - String benutzen soll, sondern Parameter. Wie verknüpfe ich das dann, dass es nicht überschrieben wird ?

Dann werde ich in Zukunft die Parameter umbenennen

16.807 Beiträge seit 2008
vor 3 Jahren

In dem Link steht alles drin, was Du beachten musst. und da steht nirgends, dass Du nen Teil vom SQL über den Konstruktor setzt und den anderen über die Eigenschaft.
Das hast selbst erfunden 😉 siehe Hinweis von T-Virus.

Du musst eigentlich nur den Code aus dem Beispiel kopieren und die Parameternamen anpassen.

H
Heino01 Themenstarter:in
7 Beiträge seit 2020
vor 3 Jahren

Habe das ganze wie im Link beschrieben in Db Provider geändert. Immer noch der gleiche Fehler


 public partial class cmd_add : Form
    {
        OleDbConnection con = new OleDbConnection(@"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\Users\Heino\source\repos\Projekt_DB\VAG_AFG.accdb"); // Connection Databse

        public string Titel;
        public string Art;

        public cmd_add()
        {
            InitializeComponent();
            txt_prio.Items.Add("1");
            txt_prio.Items.Add("2");
            txt_prio.Items.Add("3");                // Hinzufügen Kombobox
        }


        public void cmd_speichern_Click(object sender, EventArgs e)
        
        {
            try
            {
                
                con.Open();                                                  // Verbindung herstellen zur Datenbank

                StringBuilder sb = new StringBuilder();
                sb.AppendLine("INSERT INTO Aufgaben ([Titel], [Art])");
                sb.AppendLine("OUTPUT INSERTED.ID");
                sb.AppendLine("VALUES (@txt_titel, @txt_art");


                OleDbCommand cmd = new OleDbCommand(sb.ToString(), con);
                cmd.Parameters.AddWithValue("@Titel", Titel);                             
                cmd.Parameters.AddWithValue("@Art", Art);
                cmd.ExecuteNonQuery();
                
                MessageBox.Show("Auswahl hinzufügen erfolgreich");
                con.Close();

                this.Close();                                                       //Schließen des zweiten Fensters

            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
                return;
            }
        }

5.657 Beiträge seit 2006
vor 3 Jahren

Du solltest dir den Beispiel-Code noch mal anschauen. Du hast zuviele "@" und falsche Parameternamen. Du mußt schon in der SQL-Anweisung und bei der Parameter-Zuweisung die gleichen Namen verwenden.

Weeks of programming can save you hours of planning

T
2.219 Beiträge seit 2008
vor 3 Jahren

Ebefalls kannst du dir den StringBuidler sparen.
Wenn du Mehrzeilige Strings schreiben willst, nutzt das @ dafür.


string sql = @"SELECT * FROM Tabelle
WHERE ID=@Blub";

Nachtrag:
Was mich auch stört ist, dass dein MessageBox.Show vor dem Close der Verbindung kommt.
Ebenfalls solltest du das ganze in eine using packen, dann wird die Verbindung auch ohne expliziten Close Aufruf geschlossen.
Die Objekte werden von dir auch nicht disposed, dafür müsstest du ihne das using noch explizit Dispose aufrufen.

Vom Drei-Schichten-Modell will ich noch nicht anfangen, würde es aber der Sorgfalt halber erwähnen.

T-Virus

Developer, Developer, Developer, Developer....

99 little bugs in the code, 99 little bugs. Take one down, patch it around, 117 little bugs in the code.

16.807 Beiträge seit 2008
vor 3 Jahren

Ich bin mir nicht sicher, was das OUTPUT im SQL Code soll (ich hab aber mit Access auch nichts am Hut); aber im Endeffekt sollte Dein Code am Ende vom Tag einfach so aussehen:
Ganz simpel, wenige Zeilen Code.

public void AddTaskToDatabase(OleDbConnection connection, string taskTitle, int taskArt) // musste raten welcher Datentyp Art sein soll
{
    using (OleDbCommand cmd = new OleDbCommand("INSERT INTO Aufgaben ([Titel], [Art]) OUTPUT INSERTED.ID VALUES (@TITLE, @ART)", connection))
    {
        cmd.Parameters.AddWithValue("@TITLE", taskTitle);
        cmd.Parameters.AddWithValue("@ART", taskArt);
        cmd.ExecuteNonQuery();
    }
}

Hab mit Absicht unterschiedliche Bezeichner an den Stellen gewählt, damit Du den Überblick hast, wo was hin gehört.

Man kann das ingesamt noch besser machen ( [Artikel] Drei-Schichten-Architektur ) aber solltest erst mal verstehen, was der Code macht.
Aber wie gesagt; hätte eigentlich nur den Code aus dem Beispiel übernehmen müssen und die Parameternamen 1:1 ersetzen müssen.

T
2.219 Beiträge seit 2008
vor 3 Jahren

@Abt
Wie aus dem Bilderbuch 😃
Genau so sollte der Code im Endeffekt aussehen.
Einfach und sauber.

T-Virus

Developer, Developer, Developer, Developer....

99 little bugs in the code, 99 little bugs. Take one down, patch it around, 117 little bugs in the code.

709 Beiträge seit 2008
vor 3 Jahren

Zusätzlich fehlt im VALUES-Teil auch noch eine schließende Klammer.

5.657 Beiträge seit 2006
vor 3 Jahren

Ich bin mir nicht sicher, was das OUTPUT im SQL Code soll

Das kommt aus dem Artikel.

Zusätzlich wird dort bei der Parameterzuweisung auf das "@" verzichtet:

cmd.Parameters.AddWithValue("Birthday", birthday);

Ich weiß auch nicht, wie es bei Access richtig ist, damit habe ich glücklicherweise seit längerem nichts mehr zu tun gehabt.

Allgemein würde ich von Acces auch dringend abraten. Es ist ein Office-Programm und keine Datenbank. Es gibt mittlerweile wesentlich bessere und kostenlose Alternativen.

Weeks of programming can save you hours of planning

H
Heino01 Themenstarter:in
7 Beiträge seit 2020
vor 3 Jahren

Vielen Dank, es funktioniert super !