Avatar billede keepy Seniormester
19. maj 2011 - 22:59 Der er 21 kommentarer og
1 løsning

SQL og Database

Håber her er nogle der kan hjælpe lidt med hvordan jeg læser rækker ud af en access database med SQL kommandoer.

Jeg har en stor database med mange kolonner og rækker, jeg vil gerne søge på indholdet af en bestemt kolonne, og hver gang det søgte findes, skal hele rækker printes ud i et listview.

Håber i forstår.
På forhånd tak

Jeg har følgende kode.

Mdbsti = Application.StartupPath + (char)92 + "Database.mdb";
            MessageBox.Show(Mdbsti);
            OleDbConnection MyConnection = new OleDbConnection(@"Provider=Microsoft.Jet.OLEDB.4.0; User Id=; Password=; Data Source=" + Mdbsti);
            OleDbCommand odbcom = new OleDbCommand("SELECT * FROM Film",MyConnection);
         
            MyConnection.Open();

            OleDbDataReader myReader = odbcom.ExecuteReader(CommandBehavior.SingleRow);
            if (!myReader.IsClosed)
            {
                switch (value)
                {
                    case 1:
                        odbcom.CommandText = searchFor;
                        myReader.Close();
                        var rec = odbcom.ExecuteNonQuery();
                        break;
                    case 2:
                        odbcom.CommandText = searchFor;
                        rec=odbcom.ExecuteNonQuery();
                        break;
                    case 3:
                        odbcom.CommandText = searchFor;
                        rec=odbcom.ExecuteNonQuery();
                        break;
                }
               
                MyConnection.Close();
                myReader.Close();
                myReader.Dispose();
              }
Avatar billede aaberg Nybegynder
19. maj 2011 - 23:12 #1
Nedenstående er ikke testet. Jeg har skrevet direkte i tekstboksen. Men du skal gøre noget lignende dette:

Mdbsti = Application.StartupPath + "\\Database.mdb";
using (OleDbConnection MyConnection = new OleDbConnection(@"Provider=Microsoft.Jet.OLEDB.4.0; User Id=; Password=; Data Source=" + Mdbsti))
using (OleDbCommand odbcom = MyConnection.CreateCommand())
{
  odbcom.CommandText = "SELECT * FROM Film where title = ?";
  odbcom.Parameters.Add("title", "Ghost Busters");

  MyConnection.Open();
  OleDbDataReader myReader = odbcom.ExecuteReader();

  while(reader.Read())
  {
      string title = reader.GetString(reader.GetOrdinal("title"));
      int filmId = reader.GetInt32(reader.GetOrdinal("id"));

      // Her kan du tilføje til listviewet.
  }
}
Avatar billede aaberg Nybegynder
19. maj 2011 - 23:16 #2
Lidt forklaring.

using(...) blokken gør, at når koden kommer ud af blokken, bliver Dispose på objekterne i blokken kaldt. Det vil altså sige, i dette tilfælde, at Dispose på MyConnection og odbcom bliver kaldt. Dette vil lukke din connection (Derfor behøver du ikke kalde Close).

I min løsning går jeg ud fra at du søger på title-kolonnen i databasen (Hvis du altså har sådan en), og at du også har en id kolonne.

Den henter ikke alle film ind i c# programmet, for at søge igennem dem der. I stedet er der specificeret i sql kommandoen, hvad det er du søger efter.
Avatar billede aaberg Nybegynder
19. maj 2011 - 23:20 #3
Avatar billede keepy Seniormester
20. maj 2011 - 22:29 #4
Tak Tak det virker bare super.
Kender du denne fejl Objektreferencen er ikke indstillet til en forekomst af et objekt.
JEg får denne fejl når jeg via et event vil skrive til listview1
fejlen kommer når jeg kalder metoden med alle data fra databasen.



UpdateListview(xtitle, xgenre, xspilletid, xskuespiller, xsprog, xundertekster, xregkode);

public delegate void DelegateListview(String title, String genre, int spilletid, String skuespiller, String sprog, String undertxt, int regkode); 
      public event DelegateListview UpdateListview;


dbc.UpdateListview += new DatabaseConnection.DelegateListview(UpdateListview);


public void UpdateListview(String title,String genre, int spilletid, String skuespiller, String sprog, String undertxt, int regkode)
        {
            ListViewItem list1 = new ListViewItem();
            list1.SubItems.Add(title);
            list1.SubItems.Add(genre);
            list1.SubItems.Add(spilletid.ToString());
            list1.SubItems.Add(skuespiller);
            list1.SubItems.Add(sprog);
            list1.SubItems.Add(undertxt);
            list1.SubItems.Add(regkode.ToString());
            listView1.Items.AddRange(new ListViewItem[] { list1 });
         
        }
Avatar billede aaberg Nybegynder
20. maj 2011 - 23:13 #5
Ja, den fejl kender jeg. jeg tror det er den hyppigste fejlmeddelelse i .NET :)

Det betyder at du prøver at gøre noget på et object som er NULL. Hvis eksempeltvist at "spilletid" parameteren til UpdateListView metoden er NULL, vil du få denne fejl, fordi du kalder spilletid.ToString(). Du kan ikke kalde ToString() på NULL.

Højest sandsynlig har du et tomt felt i databasen. Når det kommer ind i dit program, er bliver variablen NULL.

Når du programmere i Visual Studio, fortæller den dig på præcist hvilken linje i koden fejlen sker, dette bør give dig en pegepind på hvilken parameter som er NULL.
Avatar billede keepy Seniormester
21. maj 2011 - 21:25 #6
Nej der er noget i alle felter og jeg kan se at variablerne indeholde de rigtige data
Avatar billede aaberg Nybegynder
21. maj 2011 - 21:49 #7
Fejlen bliver kaldt fordi du kalder en metode på et objekt der er null. Det er ganske sikkert.

Brug debuggeren i Visual Studio, eksekver koden linje for linje, følg med på hvad alle variabler indeholder. Så finder du helt sikkert fejlen. Dette er en god øvelse i debugging :) noget som alle skal igennem.
Avatar billede keepy Seniormester
21. maj 2011 - 22:48 #8
kan det ikke være noget andet for jeg er helt sikker på at variablerne ikke er null
Avatar billede aaberg Nybegynder
22. maj 2011 - 08:54 #9
På hvilken linje sker fejlen?
Avatar billede keepy Seniormester
22. maj 2011 - 15:51 #10
Linjen hvor jeg kalder motoden

UpdateListview(xtitle, xgenre, xspilletid, xskuespiller, xsprog, xundertekster, xregkode);
Avatar billede aaberg Nybegynder
22. maj 2011 - 20:40 #11
Jeg kan desværre ikke se hvad fejlen er, ud fra den information jeg har.

Der er ikke andet for end lave en step by step debugging igennem din kode. Find ud af præcist hvornår den fejler og hvor den fejler. Sæt et breakpoint i koden, så den breaker lige før den fejler. Tjek at alle variabler er i orden. Læs hele fejlmeddelelsen, også det der står i "inner exception".

Der findes mange debugging tutorials rundt omkring på nettet.
http://www.dotnetperls.com/debugging
http://www.codeproject.com/KB/cs/MasteringInDebugging.aspx

Hvis du til død og pine ikke finder ud af det, så zip hele projektet inklusiv database, og læg det op på en server hvor jeg kan downloade det. eksempeltvis http://www.easy-share.com/ . Så skal jeg prøve at finde fejlen.
Avatar billede keepy Seniormester
22. maj 2011 - 20:41 #12
alle variablerne har indhold men den siger at UpdateListview er null, men det må være fordi metoden ikke er kørt endnu??
Avatar billede aaberg Nybegynder
22. maj 2011 - 21:42 #13
Ok. Jeg har fundet problemet.

På linje 36 i Form1.cs sætter du eventet UpdateListView på den instans af DatabaseConnection klassen som hedder dbc, og ligger lokalt i Form1.

Inde i Title klassen opretter du en anden instans af DatabaseConnection klassen. Og det er denne instans du kalder DatabaseConnectionRead metoden på. Og denne instans af klassen, har ikke fået tildelt nogen delegate til UpdateListView eventet.

Du retter det enkelt ved at fjerne databasecon variablen fra Title klassen, og i stedet have den som parameter i Find_Title metoden. Title klassen kommer til at se sådan ud:

class Title
{
    public String Title1;

    public void Find_Title(String xTitle, DatabaseConnection databasecon)
    {
        if (xTitle.Contains("%"))
        {
            Title1 = "SELECT * FROM Film WHERE Title LIKE '" + xTitle + "'";//s%'
        }

        else if (!xTitle.Contains("%"))
        {
            Title1 = "SELECT * FROM Film WHERE Title='" + xTitle + "'";
        }
        databasecon.DatabaseConnectionRead(2, Title1);
    }
}


På linje 40 i Form1.cs, tilføjer du dbc til metodekaldet:
if (!textBox1.Text.Equals(""))
            { t.Find_Title(textBox1.Text, this.dbc); }


Gør tilsvarende for Film og Medvirkende klasserne.
Avatar billede aaberg Nybegynder
22. maj 2011 - 21:48 #14
Hvis jeg ellers skal komme med lidt konstruktiv kritik, så tror jeg du gør dette en del mere kompliceret end det egentlig er.

Hvis du har lyst, kan jeg godt lave et lille eksempel på, hvordan jeg ville have lavet projektet? Og dette er på en måde, jeg tror de fleste vil synes er lettere at læse og forstå.
Avatar billede keepy Seniormester
22. maj 2011 - 22:04 #15
ok sejt fundet, men hvad med IGenre?? den er ikke glad for DatabaseConnection databasecon
Avatar billede keepy Seniormester
22. maj 2011 - 22:07 #16
Uuuuu det må du meget gerne, alt input er godt jeg er helt ny i dette
Avatar billede aaberg Nybegynder
22. maj 2011 - 22:11 #17
IGenre er et interface. Der skal du tilføje DatabaseConnection til parameterlisten på getGenre metoden:

public interface IGenre
{
    void getGenre(String i, DatabaseConnection databasecon);

    void getDescription();
}


i filmklassen gør du tilsvarende:
public class Film : IGenre
{

    String Genre;


    #region IGenre Members

    public void getGenre(String xGenre, DatabaseConnection databasecon)
    {

        //Database kommandoer for genre søgning, Iterator pattern


        if (xGenre.Contains("%"))
        {
            Genre = "SELECT * FROM Film WHERE Genre LIKE '" + xGenre + "'";//s%'
        }

        else if (!xGenre.Contains("%"))
        {
            Genre = "SELECT * FROM Film WHERE Genre='" + xGenre + "'";
        }
        databasecon.DatabaseConnectionRead(1, Genre);
    }


    public void getDescription()
    {

        //Database kommandoer for Description søgning, Iterator pattern

    }
    #endregion
}
Avatar billede keepy Seniormester
22. maj 2011 - 22:23 #18
ja, men det giver mig denne fejl Error    1    Inconsistent accessibility: parameter type 'FilmDatabase.DatabaseConnection' is less accessible than method 'FilmDatabase.IGenre.getGenre(string, FilmDatabase.DatabaseConnection)'
Avatar billede aaberg Nybegynder
22. maj 2011 - 22:41 #19
Lav alle dine klasser public

public class Film...
Avatar billede aaberg Nybegynder
22. maj 2011 - 22:43 #20
Har du visual studio 2010?

Jeg har lavet et lille eksempel til dig, men jeg har kun VS2010, da jeg måtte reformatere for ikke så lang tid siden. Men VS2008 kan ikke åbne VS2010 solutions.
Avatar billede keepy Seniormester
22. maj 2011 - 22:54 #21
det er bare super husk nu lige at smid et svar :o) taaaak
Avatar billede aaberg Nybegynder
22. maj 2011 - 23:14 #22
Hehe, her kommer svaret. Jeg har lagt en besked i din inbox med et link.

:)
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
IT-kurser om Microsoft 365, sikkerhed, personlig vækst, udvikling, digital markedsføring, grafisk design, SAP og forretningsanalyse.

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester