Laden...

Wie kann ich bei einem Datenbank-Update-Query mit OleDb alle erforderlichen Parameter mitgeben?

Erstellt von knrd__ vor 3 Jahren Letzter Beitrag vor 3 Jahren 1.511 Views
K
knrd__ Themenstarter:in
3 Beiträge seit 2020
vor 3 Jahren
Wie kann ich bei einem Datenbank-Update-Query mit OleDb alle erforderlichen Parameter mitgeben?

verwendetes Datenbanksystem: <SQL>

Hallo erstmal, ich bin neu hier, also geht gut mit mir um, wenn ich etwas falsch mache. Ich muss mich hier erstmal einfinden 😃
Ich habe alle grundlegenden Regeln und Hinweise gelesen, bitte aber trotzdem um Entschuldigung, wenn ich etwas falsch gemacht habe. Bitte weist mich auch darauf hin- Vielen Dank 😃

Ich bin gerade in meiner Ausbildung und im Zuge dieser Ausbildung gerade in einer Projektarbeit, in der man ein Lagersystem programmieren soll.
Dazu sollen wir die "Forms-Apps" nutzen, in der ich das auch hier gerade programmiere.
Mein Fehler gerade besteht darin, dass ich keine Ahnung habe, wieso mir die ganze zeit die folgende Fehlermeldung ausgegeben wird:

Fehlermeldung:
System.Data.OleDb.OleDbException: "Für mindestens einen erforderlichen Parameter wurde kein Wert angegeben."

Ich versuche gerade mithilfe eines OleDBCommands und eines Update-Befehls, Daten in die Datenbank zu schreiben. Das Prinzip und alles ist klar, aber irgendwo muss ich, laut der Fehlermeldung, etwas vergessen haben.
Wäre cool, wenn mir jemand oder wenn ihr mir weiterhelfen könntet.
Hier der vollständige Code der Form "ArtikelBearbeiten":
Tut mir leid, falls das etwas unaufgeräumt aussieht, aber das liegt dann an der Seite, weil ich immer versuche meinen Code perfekt ordentlich zu halten 😃
Der Fehler tritt also in den letzten Zeilen auf, bei der "cmd.ExecuteNonQuery();" steht.

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;
using System.Data.OleDb;

namespace Projektarbeit2020
{
    public partial class ArtikelBearbeiten : Form
    {
        OleDbConnection con = new OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=database.accdb");
        OleDbCommand cmd = new OleDbCommand();
        OleDbDataReader dr = null;
        OleDbDataAdapter adapter = new OleDbDataAdapter();
        DataSet ds0 = new DataSet();
        DataSet ds1 = new DataSet();
        DataSet ds2 = new DataSet();
        public ArtikelBearbeiten()
        {
            InitializeComponent();
        }

        private void ArtikelBearbeiten_Load(object sender, EventArgs e)
        {
            NummerComboBox.Items.Clear();
            try
            {
                //Füllen der Combobox (Nummern)
                cmd = new OleDbCommand("SELECT Artikel_Nummer FROM Artikel", con);
                con.Open();
                dr = cmd.ExecuteReader();
                while (dr.Read())
                {
                    NummerComboBox.Items.Add(dr.GetInt32(0));
                }
                con.Close();
            }
            catch (Exception a)
            {
                MessageBox.Show("Combobox-Füll-Fehler: \n" + a);
                con.Close();
            }

            //Einheitstabelle füllen
            try
            {
                adapter = new OleDbDataAdapter("SELECT Einheit_Nummer, Einheit_Bezeichnung FROM Einheit", con);
                adapter.Fill(ds0, "EinheitUebersicht");
                Einheitstabelle.DataSource = ds0;
                Einheitstabelle.DataMember = "EinheitUebersicht";
            }
            catch (Exception a)
            {
                MessageBox.Show("Einheitstabelle-Füll-Fehler: \n" + a);
            }

            //Lagertabelle füllen
            try
            {
                adapter = new OleDbDataAdapter("SELECT Lager_Nummer, Lager_Bezeichnung FROM Lager", con);
                adapter.Fill(ds1, "LagerUebersicht");
                Lagertabelle.DataSource = ds1;
                Lagertabelle.DataMember = "LagerUebersicht";
            }
            catch (Exception a)
            {
                MessageBox.Show("Lagertabelle-Füll-Fehler: \n" + a);
            }


        }

        private void NummerComboBox_SelectedIndexChanged(object sender, EventArgs e)
        {
            try
            {
                adapter = new OleDbDataAdapter("SELECT * FROM Artikel WHERE Artikel_Nummer=" + NummerComboBox.SelectedItem, con);
                ds2.Clear();
                adapter.Fill(ds2, "Artikel");
                Bezeichnung.Text = ds2.Tables["Artikel"].Rows[0]["Artikel_Bezeichnung"].ToString();
                Lagerpreis.Text = ds2.Tables["Artikel"].Rows[0]["Artikel_Lagerpreis"].ToString();
                Einkaufspreis.Text = ds2.Tables["Artikel"].Rows[0]["Artikel_Einkaufpreis"].ToString();
                Meldebestand.Text = ds2.Tables["Artikel"].Rows[0]["Artikel_Meldebestand"].ToString();
                AktuellerBestand.Text = ds2.Tables["Artikel"].Rows[0]["Artikel_Aktueller_Bestand"].ToString();
                Einheitsnummer.Text = ds2.Tables["Artikel"].Rows[0]["Artikel_Einheit_Nummer"].ToString();
                Lagernummer.Text = ds2.Tables["Artikel"].Rows[0]["Artikel_Lager_Nummer"].ToString();
                AktivCheckb.Checked = (bool)ds2.Tables["Artikel"].Rows[0]["Artikel_Ist_Aktiv"];
            }
            catch(Exception a)
            {
                MessageBox.Show("NummerComboBox-Füll-Fehler: \n" + a);
            }
        }

        private void Speichern_Click(object sender, EventArgs e)
        {
            bool CbZustand;
            if (AktivCheckb.Checked == true)
            {
                CbZustand = true;
            }
            else
            {
                CbZustand = false;
            }
            /*    
            adapter.UpdateCommand = new OleDbCommand("UPDATE Artikel SET Artikel_Bezeichnung=" + Bezeichnung.Text + ", Artikel_LagerPreis=" + Lagerpreis.Text + ", Artikel_EinkaufPreis=" + Einkaufspreis.Text + ", Artikel_Meldebestand=" + Meldebestand.Text + ", Artikel_Aktueller_Bestand=" + AktuellerBestand.Text + ", Artikel_Einheit_Nummer=" + Einheitsnummer.Text + ", Artikel_Lager_Nummer=" + Lagernummer.Text + ", Artikel_Ist_Aktiv=" + CbZustand + " WHERE Artikel_Nummer='" + NummerComboBox.SelectedItem + "'", con);
            
            
            con.Open();
            adapter.UpdateCommand = con.CreateCommand();
            adapter.UpdateCommand.CommandText = "update Artikel set Artikel_Bezeichnung=Hallo where Artikel_Nummer=1";
            adapter.UpdateCommand.ExecuteNonQuery();
            con.Close();
            */

            con.Open();
            OleDbCommand cmd = new OleDbCommand("UPDATE Artikel SET Artikel_Bezeichnung=" + Bezeichnung.Text + ", Artikel_LagerPreis=" + Lagerpreis.Text + ", Artikel_EinkaufPreis=" + Einkaufspreis.Text + ", Artikel_Meldebestand=" + Meldebestand.Text + ", Artikel_Aktueller_Bestand=" + AktuellerBestand.Text + ", Artikel_Einheit_Nummer=" + Einheitsnummer.Text + ", Artikel_Lager_Nummer=" + Lagernummer.Text + ", Artikel_Ist_Aktiv=" + CbZustand + " WHERE Artikel_Nummer='" + NummerComboBox.SelectedItem.ToString() + "'", con);
            cmd.ExecuteNonQuery();
            con.Close();
        }
    }
}

Falls ihr noch Informationen braucht, bin ich aufgeschlossen diese bereitzustellen 😃
Danke LG
knrd

16.806 Beiträge seit 2008
vor 3 Jahren

Du gibst an, dass Du mit SQL arbeitest - MSSQL?
Wenn ja, wieso verwendest Du dann OleDb? Es gibt für alle großen SQL Server ordentliche ADO.NET Implementierungen.
OleDb brauchst Du fast nie (wenn dann zB für Excel oder Access).

Ansonsten: bitte keine String-Frickerelein bei SQL Statements.
[Artikelserie] SQL: Parameter von Befehlen
Dein Code ist voll von SQL Injection Risks - neben Folgefehlern von Typbehandlungen (Du behandelst quasi alle Strings im SQL Command falsch).

Wenn Du ordentlich mit Parametern arbeitest, dann wird vermutlich der Fehler von alleine verschwinden.

Allgemein: Datenbank-Code hat im UI Code nichts zu suchen.
[Artikel] Drei-Schichten-Architektur

PS: aus

bool CbZustand;
            if (AktivCheckb.Checked == true)
            {
                CbZustand = true;
            }
            else
            {
                CbZustand = false;
            }

Kann man einfach

bool CbZustand = AktivCheckb.Checked; 

machen.

Prefixe an Variablen macht man in C# normalerweise nicht; das kommt leider aus anderen Sprachen rüber geschwappt.
[Artikel] C#: Richtlinien für die Namensvergabe

K
knrd__ Themenstarter:in
3 Beiträge seit 2020
vor 3 Jahren

Alles klar, danke.
Es ist bloß so, dass ich noch so ziemlich am Anfang bin und wir lernen das so. Da kann ich ja nichts dafür 😄
In meiner Ausbildung bekommen wir das so beigebracht. Vielleicht sind die Lehrer auch einfach etwas weniger in der heutigen Zeit vorhanden ;D

Ich hatte das vorher einfach auch verwechselt. Wir arbeiten mit einer Access Datenbank im Hintergrund. Somit hilft mir das leider nicht.
-> Wir lernen das leider so und anders kenne ich das auch nicht.

Man soll zwar nicht nach fertigen Antworten fragen, aber ich habe den Post extra erstellt um diesen Fehler aus der Welt zu bringen.
Ich habe an diesem Fehler auch schon 4 Stunden gesessen, weil mein Teampartner und ich das nicht herausfinden, wo dieser Fehler herkommt.

Ist mir denn ein so offensichtlicher Fehler im Code unterlaufen, dass wir beide den komplett übersehen. Nach dem Motto: "Zu einfach für das Gehirn" 😄

LG

16.806 Beiträge seit 2008
vor 3 Jahren

Offensichtlich Fehler ist primär:
Ihr erzeugt nicht nur potentiell unsicheren SQL Code, sondern vor allem auch ungültigen SQL Code, weil ihr den SQL Command - besonders im Falle der Strings - falsch zusammen baut.
Die Werte der Typen landen nicht im korrekten Format im SQL Code, zB. fehlen überall bei Strings Hochkomma => Resultiert im SQL Fehler.

Das kann nicht passieren, wenn ihr mit Parametern arbeitet.
Steht alles in [Artikelserie] SQL: Parameter von Befehlen
Geht auch mit Access.

Umschreiben werde ich Dir Deine Hausaufgaben aber nicht, sorry 😃
Du sollst selbst was dabei lernen.

K
knrd__ Themenstarter:in
3 Beiträge seit 2020
vor 3 Jahren

Hier nochmal das Bild, zur Vollständigkeit zu liebe

16.806 Beiträge seit 2008
vor 3 Jahren

Ich hab das extern verlinkte Bild gemäß der Hinweise in [Hinweis] Wie poste ich richtig? entfernt.

Aber nochmal:
Verwende Parameter und der Fehler ist vermutlich weg.

16.806 Beiträge seit 2008
vor 3 Jahren

Welchen Sinn hat es, dass Du meinen Beitrag mit dem Kommentar meldest, dass ich Deine Frage nicht beantworten würde?

5.657 Beiträge seit 2006
vor 3 Jahren

Du solltest dir die verlinkten Artikel wirklich mal anschauen, bevor du dich beschwerst. Abt hat die ja nicht für umsonst gepostet.

Weeks of programming can save you hours of planning