Laden...

Access Datenbank Abfrage nach mehreren Faktoren

Erstellt von Beccy vor 13 Jahren Letzter Beitrag vor 13 Jahren 6.526 Views
B
Beccy Themenstarter:in
10 Beiträge seit 2011
vor 13 Jahren
Access Datenbank Abfrage nach mehreren Faktoren

Ich arbeite mit Microsoft Visual Studio 2010 und programmiere C#

Hallo,

ich habe ein Programm zur Dateienverwaltung geschrieben. Hierzu gibt es eine Klasse Datei in der ich die zur Datei beschreibenden Attribute definiert habe. Bspw. Ersteller, Dateiname, Erstelldatum, etc. Diese Faktoren sind in der Access Datenbank die Spalten. Das hineinschreiben in die Access Datenbank funktioniert soweit. Das Aufrufen, Schließen und Speichern auch. Jetzt habe ich eine Eingabemaske mit Windows.Forms programmiert um nach Dateien suchen zu können, also nach den Attributen der Klasse Datei (Ersteller, Datum, etc). Jetzt soll die Access Datenbank nach diesen Attributen durchsucht werden und als Suchliste alle Treffer ausgegeben werden. Hierzu kann der Benutzer aber auch nur zwei Felder von 4 ausfüllen. Wie formulier ich das denn am geschicktesten?


        public Personen suchePersonenNachName(string wie)
        {
            string command = "SELECT * FROM Person WHERE Name like '" + wie + "'";
            //SQL-Kommando erzeugen
            return suchePersonenSQL(command);
        }

Mit diesem Codefrakment kann ich nur nach einem Wert suchen. Ich möchte aber möglichst alles auf einmal abdecken. Meine zweite Idee sah wie folgt aus

        public static void SucheDatei(string[] args)
        {
            ArrayList mm_liste = new ArrayList();
            OleDbCommand mCommand = new OleDbCommand(sql, mConnection);

            OleDbDataReader mReader = null;
            mReader = mCommand.ExecuteReader();

            while (mReader.Read())
            { //Bei GetString() ist der Wert in der Klamme die Spaltenzahl
                if (SuchDatei.Ersteller != "0")
                    SuchDatei.Ersteller = mReader.GetString(14);
                if (SuchDatei.Erstelldatum != "0")
                    SuchDatei.Erstelldatum = mReader.GetString(2);
                if (SuchDatei.Erstelluhrzeit != "0")
                    SuchDatei.Erstelluhrzeit = mReader.GetString(3);
                if (SuchDatei.Genre != "0")
                    SuchDatei.Genre = mReader.GetString(4);
                if (SuchDatei.Album != "0")
                    SuchDatei.Album = mReader.GetString(5);
                if (SuchDatei.Anlass != "0")
                    SuchDatei.Anlass = mReader.GetString(7);
                if (SuchDatei.Band != "0")
                    SuchDatei.Band = mReader.GetString(6);
                if (SuchDatei.Dateiname != "0")
                    SuchDatei.Dateiname = mReader.GetString(1);
                if (SuchDatei.Gruppierung_1 != "0")
                    SuchDatei.Gruppierung_1 = mReader.GetString(8);
                if (SuchDatei.Gruppierung_2 != "0")
                    SuchDatei.Gruppierung_2 = mReader.GetString(9);
                if (SuchDatei.Gruppierung_3 != "0")
                    SuchDatei.Gruppierung_3 = mReader.GetString(10);
                if (SuchDatei.Gruppierung_4 != "0")
                    SuchDatei.Gruppierung_4 = mReader.GetString(12);
                if (SuchDatei.Gruppierung_5 != "0")
                    SuchDatei.Gruppierung_5 = mReader.GetString(13);
            }
            // Close the Reader when done. 
            mReader.Close();
            // Close the connection when done. 
            return mm_liste;
        }

war aber beides nicht Zielführend. Ich hoffe ich konnte meine Frage verständlich rüberbekommen. Schon mal danke im Voraus für jegliche Hilfe.

Grüße Beccy

3.430 Beiträge seit 2007
vor 13 Jahren

Hallo,

willkommen bei myCSharp.de

Du kannst in SQL auch mehrere Vergleiche in der WHERE-Clause machen.
D.h. du kannst sie mit OR bzw. AND kombinieren.

In deinem Fall musst du einfach checken ob der User was in dem Betreffenden Feld eingegeben hat. Wenn ja, dann fügst du am Ende der Query noch ein " AND MeinFeld='MeinWert'" dazu

PS: Anstatt die Abfrage mit + zusammenzufügen ist es besser die SqlParameter zu verwenden.
Damit bist du sicher dass du kein Opfer von SQL-Injection wirst

Gruß
Michael

B
Beccy Themenstarter:in
10 Beiträge seit 2011
vor 13 Jahren

Hey,

Vielen Dank schon mal. Die AND - Verknüpfung kann ich doch nur machen, wenn alle Felder ausgefüllt sind. Ansonsten wird das doch ein Spaghetticode mit den ganzen Vorabfragen.
Das mit den SQLParametern ist mir nicht ganz klar, hab erst mit SQL angefangen.

Ich möchte das als ein Unterprogramm verpacken das alles mit auffängt, die Abfrage (also die evtl. auch nicht Eingabe von Feldern) das Suchen und die Ausgabe in einer tabellarischen Form.

Hab etwas gegoogelt nach den Begriffen von dir, bin aber nicht wirklich schlauer daraus geworden. Ich hoffe du kannst mir hier nochmal bisschen helfen 😉

Danke schön, Grüße

Beccy

PS.: Vielleicht programmier ich ja auch zu kompliziert, aber ich versuch möglichst einfach das umzusetzen wie ichs mir vorstelle...

Hab dir mal angehängt, wie ichs bisher habe.

Klasse Datei mit den Spezifikationen


    class Datei
    {
        /* hier werden nur die Eingabemöglichkeiten definiert der Klasse Datei 
         * dies soll ein neuer Variablentyp sein
         */

        public string Dateipfad;
        public string Dateiname;
        public string Erstelldatum;
        public string Erstelluhrzeit;
        public string Ersteller;
        public string Genre;
        public string Album;
        public string Band;
        public string Anlass;
        public string Gruppierung_1;
        public string Gruppierung_2;
        public string Gruppierung_3;
        public string Gruppierung_4;
        public string Gruppierung_5;
    }

Und hier ist mein Datenbank Programm bisher

    class Datenbank
    {
        OleDbConnection mConnection;
        // Pfad der Access Datei
        string Pfad = "D:\\HTW\\1. Semester\\M3_Softwareentwicklung\\Projekt\\Datenbank.mdb";

        // Schliesst die Verbindung zur Access Datenbank
        public void closeConnection()
        {
            mConnection.Close();
        }


        // Stellt die Verbindung zur Access Datenbank her
        public bool OpenConnection()
        {
            try
            {
                string source = "Provider=Microsoft.JET.OLEDB.4.0;" + "data source='" + Pfad + "' ";
                //Erzeugen des Objektes
                mConnection = new OleDbConnection(source);
                //Öffnen der Datenbank
                mConnection.Open();
            }
            catch
            {
                return false;
            }
            return true;
        }


        // Unterprogramm zum eine neue "Datei" hinzuzufügen
        public bool NeueAnlegen(Datei neueDatei)
        {
            // Hier werden die einzelnen Spezifikationen der Klasse Datei an Access übergeben.
            string sql = "INSERT INTO datei ([Dateiname], [Gruppierung 1]) VALUES('" + neueDatei.Dateiname +"', '" + neueDatei.Gruppierung_1 + "')";
            OleDbCommand mCommand = new OleDbCommand(sql, mConnection);
            mCommand.ExecuteNonQuery();

            return true;
        }


        // Programm zum Suchen in Access
        //public Datei sucheDatei(string sql, Datei SuchDatei)
        /*public static void SucheDatei(string[] args)
        {
            ArrayList mm_liste = new ArrayList();
            OleDbCommand mCommand = new OleDbCommand(sql, mConnection);

            OleDbDataReader mReader = null;
            mReader = mCommand.ExecuteReader();

            while (mReader.Read())
            { //Bei GetString() ist der Wert in der Klamme die Spaltenzahl
                if (SuchDatei.Ersteller != "0")
                    SuchDatei.Ersteller = mReader.GetString(14);
                if (SuchDatei.Erstelldatum != "0")
                    SuchDatei.Erstelldatum = mReader.GetString(2);
                if (SuchDatei.Erstelluhrzeit != "0")
                    SuchDatei.Erstelluhrzeit = mReader.GetString(3);
                if (SuchDatei.Genre != "0")
                    SuchDatei.Genre = mReader.GetString(4);
                if (SuchDatei.Album != "0")
                    SuchDatei.Album = mReader.GetString(5);
                if (SuchDatei.Anlass != "0")
                    SuchDatei.Anlass = mReader.GetString(7);
                if (SuchDatei.Band != "0")
                    SuchDatei.Band = mReader.GetString(6);
                if (SuchDatei.Dateiname != "0")
                    SuchDatei.Dateiname = mReader.GetString(1);
                if (SuchDatei.Gruppierung_1 != "0")
                    SuchDatei.Gruppierung_1 = mReader.GetString(8);
                if (SuchDatei.Gruppierung_2 != "0")
                    SuchDatei.Gruppierung_2 = mReader.GetString(9);
                if (SuchDatei.Gruppierung_3 != "0")
                    SuchDatei.Gruppierung_3 = mReader.GetString(10);
                if (SuchDatei.Gruppierung_4 != "0")
                    SuchDatei.Gruppierung_4 = mReader.GetString(12);
                if (SuchDatei.Gruppierung_5 != "0")
                    SuchDatei.Gruppierung_5 = mReader.GetString(13);
            }
            // Close the Reader when done. 
            mReader.Close();
            // Close the connection when done. 
            return mm_liste;
        }*/

        public static void sucheDatei(Datei SuchFeld)
        {
            //string command = "SELECT * FROM Datei WHERE Dateiname like '" + SuchFeld.Dateiname + "'";
            SELECT * FROM Datei WHERE Dateiname = "C:\IO.SYS" 
        }
    }
}

Das Programm zum in der Datenbank zu suchen soll von der Klasse Suchen aufgerufen werden. 

class Suchen
    {
        public static void SSuchen()
        {
            // Suchen Variable deklarieren
            Datei mm_Suchen = new Datei();

            // Eingabemaske aufrufen und Variable befüllen
            new Eingabemaske().ShowDialog();

            // Das Suchen in der Access Datenbank
            Datenbank.sucheDatei(mm_Suchen);

            // Aufrufen von Öffnen Dateipfad muss als Variable übergeben werden
            Öffnen.Ö_Öffnen(mm_Suchen.Dateipfad);
        }
    }


3.430 Beiträge seit 2007
vor 13 Jahren

Hallo,

ja, der Code ist schon nicht wirklich gut strukturiert, aber das eignet man sich schon mit der Zeit an.

Die AND - Verknüpfung kann ich doch nur machen, wenn alle Felder ausgefüllt sind. Ansonsten wird das doch ein Spaghetticode mit den ganzen Vorabfragen

Ja das wird es. Du könntest die Abfrage evtl. in eine extra Methode auslagern, aber das ist dann immer noch etwas Spaghetticode 😃

Da müsste man schon das ganze Programm umstrukturieren

Gruß
Michael

B
Beccy Themenstarter:in
10 Beiträge seit 2011
vor 13 Jahren

Hey,

so schlimm 😉 Besten Dank!

Kannst du mir ein Bsp geben, wie du das Abfragen würdest? Erst alle Abfragen und dann die AND - Verknüpfungen oder integriert. Ich tue mich an diesem Punkt echt schwer.

Danke, Grüße
Beccy

F
155 Beiträge seit 2009
vor 13 Jahren

Hallo,

Das mit den SQLParametern ist mir nicht ganz klar, hab erst mit SQL angefangen.

sieh dir dazu diesen Artikel an [Artikelserie] Parameter von SQL Befehlen

fz

"We better hurry up and start coding, there are going to be a lot of bugs to fix."

B
Beccy Themenstarter:in
10 Beiträge seit 2011
vor 13 Jahren

Hey,

also die Vernküpfung der Parameter mit dieser Formel habe ich verstanden.


        public void sucheDatei(Datei SuchFeld)
        {           
            string command = "SELECT ID FROM Datei WHERE Dateiname like '" + SuchFeld.Dateiname + "' AND Erstelldatum '" + SuchFeld.Erstelldatum + '"';
            //string command = "SELECT * FROM Person WHERE Name like '" + wie + "'";
        }

Über AND kann ich jetzt beliebig viel anhängen.
Wie kann ich die Lsg dazu in einer WINDOWS Feld ausgeben, so dass man eine Datei auswählen und öffnen kann?

Besten Dank für jegliche Hilfe!
Beccy

T
156 Beiträge seit 2010
vor 13 Jahren

Hallo,
sorry, aber Deine String-Verkettung hat gar nichts mit einer parametrisierten Abfrage zu tun. Das müsste dann schon so aussehen:


OleDbCommand cmd = new OleDbCommand("SELECT ID FROM Datei WHERE Dateiname LIKE ? AND Erstelldatum = ?;", conn);
cmd.Parameters.AddWithValue("@Dateiname", SuchFeld.Dateiname);
cmd.Parameters.AddWithValue("@Erstelldatum", SuchFeld.Erstelldatum);

Beachte aber dabei, dass der Dateiname nur gefunden wird, wenn der Dateiname exakt gefunden wird (ansonsten müsstest Du dies machen:)


cmd.Parameters.AddWithValue("@Dateiname", "%" + SuchFeld.Dateiname + "%");

Und mit dem Datum: Ich denke, dass nur eine Datei gefunden wird, wo das Datum und die Zeit ( sekundengenau?) passt. Also Vorsicht.
Wo möchtest Du die Ergebnisse anzeigen lassen?
LG, Marko

B
Beccy Themenstarter:in
10 Beiträge seit 2011
vor 13 Jahren

Hey,

ich möchte alle gefundenen Daten als Tabelle ausgeben. Um dann eine Datei auswählen zu können die geöffnet werden soll. Das Öffnen ahbe ich auch schon geschrieben, aber ich benötige dazu den Pfad der in einer Spalte der Tabelle abgelegt ist.

Besten Dank schon mal.

Grüße

B
Beccy Themenstarter:in
10 Beiträge seit 2011
vor 13 Jahren

Hey,

ich habe die Abfrage jetzt anders gelöst. Ich habe eine Abfrage geschrieben die alle Spalten kontrolliert und das Ergebnis in eine neue Tabelle in Access schreibt. Nun aber eine neue Frage, wie kann ich eine Tabelle in einer Access Datenbank öffnen aus C# um dort eine Zeile zu markieren und hier die Spalte Pfad in einen String auszulesen?

Ich weiß, mein Programm ist etwas verkorkst, aber ich bin immerhin Anfängerin 😉

Grüße und besten Dank für jedwede Hilfe!!!

Beccy

T
156 Beiträge seit 2010
vor 13 Jahren

Hallo Beccy!

Ich habe eine Abfrage geschrieben die alle Spalten kontrolliert und das Ergebnis in eine neue Tabelle in Access schreibt. Wozu denn das? Das ist ziemlich sinnlos und bringt Dich in Deinem Fall auch nicht weiter. Denn ob Du nun aus der neuen Tabelle die Daten abfragst oder aus der Originaltablelle ist doch egal.

Also, wenn Du Deine Abfrage an die Access-Datenbank schickst, bekommst Du ein Resultat zurück. Und das kannst Du doch einfach per DataReader durchgehen, daraus eine Liste erstellen und sie dann halt irgendwo anzeigen lassen.

Dazu wäre es natürlich sehr sinnig, dass Du in dem Command nicht nur die Id des Datensatzes abfragst, sondern alle Spalten, die Du denn benötigst.
LG, Marko