Wątek przeniesiony 2017-08-01 15:19 z Bazy danych przez somekind.

Dynamiczny parametr w zapytania SELECT

0

Witam,
Chciałbym w prowadzić do pętli zapytanie do bazy danych, które będzie miało iteracje po indeksie.
usiłowałem wprowadzić zmienną i do zapytania, ale nie działa.

 List<string> data = new List<string>(); // lista opcji z ComboBoxa
                for (int i = 0; i < 4; i++)         // 
                {
                    cmd.CommandText = "SELECT first_name FROM users_tab WHERE User_id=i";
                    cmd.Connection = con;

                    cmd.CommandType = System.Data.CommandType.Text;

                    OracleDataReader dr = cmd.ExecuteReader();

                    dr.Read();
               
                    data.Add(dr.GetString(0));

                }
0

cmd.CommandText = $"SELECT first_name FROM users_tab WHERE User_id={i}"

Zanim zabierzesz się za bazy danych warto najpierw poznać podstawowe operacje takie jak formatowanie stringów ze zmiennych.

0

po zmianie na

cmd.CommandText = $"SELECT first_name FROM users_tab WHERE User_id={i}"

dostałem wyjątek

 ze względu na bieżący stan obiektu operacja nie prawidłowa
0

Pewnie dlatego, że masz zamknięte połączenie do bazy.

0

Połączenie z bazą było otwarte. Na statycznym parametrze działa, ale jak daje parametr "i" to mam błąd. chyba ze przedobrzyłem i nie można listy kombo wczytywać bezpośrednio z bazy danych pętlą for.

 private void cBox_his_user_Loaded(object sender, RoutedEventArgs e)     // ladowanie listy do ComboBoxa - w trakcie przebudowy
        {
            try         // próba połaczenia z baza Oracle
            {   // autoryzacja polaczenia

                string connectionString = "Data Source = (DESCRIPTION = " +
               "(ADDRESS = (PROTOCOL = TCP)(HOST = <host>)(PORT = 1521))" +
                " (CONNECT_DATA = " +
                 "(SERVER = DEDICATED)" +
             "(SERVICE_NAME = XE)" +
            ")" +
               ");User Id=user; password=pwd;";
          
            OracleConnection con = new OracleConnection();
            con.ConnectionString = connectionString;

            con.Open();     // otwarcie bazy

                OracleCommand cmd = new OracleCommand();
       
            List<string> data = new List<string>(); // lista opcji z ComboBoxa
                for (int i = 0; i < 4; i++)         // petla tworzaca  opcje do ComboBoca - finalnie bedzie pobierac nazwe usera z bazy
                {


                    cmd.CommandText = $"SELECT first_name, last_name FROM users_tab WHERE User_id={i}";
                    cmd.Connection = con;

                    cmd.CommandType = System.Data.CommandType.Text;

                    OracleDataReader dr = cmd.ExecuteReader();

                    dr.Read();
                                     
                    data.Add(dr.GetString(0) + " " + dr.GetString(1));
                   

                    // con.Close(); // zamkniecie bazy danych

                }
                var combo = sender as ComboBox; // zmienna przyjmujaca wartosc z ComboBoxa
                combo.ItemsSource = data;       // zrodlo opcji do wyboru
                combo.SelectedIndex = 0;        // aktualnie wybrana opcja (domyslnie 0 czyli pierwsza)

            }
            catch (Exception Ex)
            {
                MessageBox.Show("Lista ComboBoxa nie połaczyła się z bazą danych\n " + Ex.Message, "Error 1");
            }
0

A userzy o tych id w ogóle istnieją? W ogóle to bardzo odważne założenie, żeby ładować dane z bazy na podstawie iteratora pętli.

Może jednak spróbuj zrobić to sensownie, czyli pobrać wiele rekordów z bazy w jednym zapytaniu, a potem w pętli dodać je do comboboxa.

0

Masz racje, User o ID = 0 nie istnieje (SQL numeruje indeksy od 1, a nie od 0)
doszedłem do tego dziś o 4 nad ranem :D

0

ale wiesz, że jak masz pole autoincrement i np. podczas dodawania rekordu coś pójdzie nie tak to następny wstawiony poprawnie będzie miał kolejny numer i będzie dziura w ID. BTW czemu nie chcesz zrobić jak pisał wcześniej @somekind i pobrać jednym zapytaniem wszystkich userów?

0

nie pomyślałem o unikalności indeksów.
sądziłem ze generowanie obiektu przechowującego pobrane dane to trochę marnowanie miejsca, ale macie racje to bezpieczniejsze rozwiązanie.
A do czego najlepiej pobrać tych użytkowników ? do tablicy stringów czy sugerujesz coś innego ?

0

A użytkownicy są stringami?
Ja bym pobrał do tablicy użytkowników.

0

W bazie użytkownicy to varchar2 wiec myślę ze na stringi są konwertowane nie jawnie

 List<string> data = new List<string>(); // lista opcji z ComboBoxa
                for (int i = 0; i < 4; i++)         // petla tworzaca  opcje do ComboBoca - finalnie bedzie pobierac nazwe usera z bazy
                {
 
                    cmd.CommandText = $"SELECT first_name, last_name FROM users_tab WHERE User_id={i}";
                    cmd.Connection = con;
 
                    cmd.CommandType = System.Data.CommandType.Text;
 
                    OracleDataReader dr = cmd.ExecuteReader();
 
                    dr.Read();
 
                    data.Add(dr.GetString(0) + " " + dr.GetString(1));
 
                    // con.Close(); // zamkniecie bazy danych
 
                }
                var combo = sender as ComboBox; // zmienna przyjmujaca wartosc z ComboBoxa
                combo.ItemsSource = data;       // zrodlo opcji do wyboru
                combo.SelectedIndex = 0;        // aktualnie wybrana opcja (domyslnie 0 czyli pierwsza)
0
Azreal napisał(a):

W bazie użytkownicy to varchar2 wiec myślę ze na stringi są konwertowane nie jawnie

Czy Ty jesteś stringiem? Czy może Twoje imię jest stringiem?

0

Widzę , że pełnia błąd na czymś oczywistym i banalny ale nie do końca rozumiem w czym rzecz.
mógłbyś rozwinąć kwestie tej tablicy na wyniki z zapytania select ?
mam zrobić to w tablicy (SQL) użytkowników czy tablice generyczną z użytkownikami (c#)?
bo szczerze już się zakręciłem ( jak zapewne widać na załączonym obrazku) ;)

1

Ja bym utworzył klasę User z odpowiednimi polami (Id, FirstName, LastName), a potem czytał do niej konwertując jednocześnie kolumny z tabeli na właściwości klasy. Coś na zasadzie user.Id = dr.GetInt32(0); user.FirstName = dr.GetString(1);, itd.
Czytałbym w pętli while(dr.Read()) a nie for(int i = 0; i < 4; i++), bo to pozwoli odczytać wszystkie rekordy ze źródła, a for w tym przypadku nie ma żadnego sensu.

0

Wielkie dzięki, pętla ```
while(dr.Read())

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