FbDataReader - reader.HasRows zawesze zwraca true

0

Mam problem ze sprawdzeniem czy dane ID istnieje w bazie. W funkcji checkID tworzona jest nowa instancja obiektu itemdata, jeśli ID, które jest parametrem funkcji checkID istniej w bazie, nowo utworzony obiekt itemdata jest wypełniany danymi z bazy, jeśli nie wypełniane jest tylko ID obiektu. Taki obiekt jest zwracany.

W bazie co prawda jest pętla while(reader.Read()) ale wiersz powinien być zawsze jeden. Przy każdym zapisie sprawdzam obecność ID w bazie, jeśli nie ma to wykonuję INSERT, jeśli jest to wykonuję UPDATE, dzięki czemu while(reader.Read()) wykona się tylko raz.

        public itemdata checkID(string ID)
        {
            
            MainData itemdata = new MainData();
            
            using(FbConnection conn = new FbConnection(connText))
            {
                conn.Open();
                
                using(FbCommand cmd = conn.CreateCommand())
                {
                    cmd.CommandType = System.Data.CommandType.Text;
                    cmd.CommandText = "select * from MAINDATA where ID_ITEMS= '"+ID+"'";

                        
                    using(FbDataReader reader = cmd.ExecuteReader())
                    {
                        if (reader.HasRows)
                        {
                            while(reader.Read())
                            {
								//pobranie i wypełnienie zmiennych
								itemdata.SetData(pobrane zmienne);
                            }
                        }
                        else
                        {
                        	itemdata.SetID(ID);
                        }
                    }
                }
            }
            return itemdata;
        }

Problem w tym że bez znaczenia czy ID istnieje w bazie czy nie, reader.HasRows zawsze zwraca true.

Może ktoś określić co robię źle ?

0

Witam,

Może powiedz co chcesz osiągnąć bo to co widać to jakaś masakra

Pozdrawiam,

mr-owl

0

Chcę zwrócić obiekt itemdata, z tym że jeśli już id istnieje w bazie to itemdata wypełniany jest danymi z bazy, jeśli nie to tylko pole ID w obiekcie itemdata zostaje ustawione.
Ale wygląda na to że problem okazuje się leżeć w samym firebirdzie. Tu właściwość hashrows nie jest obsługiwana, jest zaimplementowana tylko dla zgodności i zwraca zawsze true. Taką notlkę znalazłem na jednym z angielskojęzycznych forów. Idąc okrężną drogą zrobiłem zapytanie count(*) zwracające ilość rekordów dla określonego ID. Jeśli większe od 0 to wypełniam obiekt danymi z bazy, jesli nie to ustawiam samo ID w obiekcie.

0

Witam,

A nie możesz olać tego sprawdzania?

public itemdata CheckId(int id)
{
  MainData itemdata = new MainData();
  itemdata.SetID(ID);
 
  using(FbConnection connection= new FbConnection(connText))
  {
    connection.Open();
 
    using(FbCommand command = connection.CreateCommand())
    {
      command.CommandType = CommandType.Text;
      command.CommandText = "SELECT * FROM MAINDATA WHERE ID_ITEMS= @ID";
      command.CommandTimeout = 600;

      command.Parameters.Add("@ID", FbType.Integer).Value = id;

      using(FbDataReader reader = command.ExecuteReader())
      {
        while(reader.Read())
        {
          //pobranie i wypełnienie zmiennych
          itemdata.SetData(pobrane zmienne);
        }
      }
    }
  }
  return itemdata;
}

To tak z grubsza,

Pozdrawiam,

mr-owl

P.S. Możesz jakoś tak inaczej nazywać funkcje i inaczej ustawiać stan obiektu (konstruktor, właściwości). Słowa kluczowe w SQL pisane wielką literą a wszystkie nazwy tabel i kolumn małą wyglądają lepiej i łatwiej się to czyta. Zapytanie nie powinno powstawać przez łączenie znaków tylko przez podstawianie parametrów (https:*en.wikipedia.org/wiki/SQL_injection, https:*en.wikipedia.org/wiki/Prepared_statement).

0

Tak, tu trochę zamieszałem z nazewnictwem. Czasem analizując kod staram się poprawiać takie błędy stylistyczne, jednak brak mi nawyku używania właściwej konwencji nazewnictwa.

1 użytkowników online, w tym zalogowanych: 0, gości: 1