Inne połączenie OleDbConnect i OleDbCommand dla różnych if'ów

0

Wesołych Świąt!
Mam kilka "if'ów", które łączą się z nadrzędnym (ifem) do jednej bazy i za pomocą innych zapytań do innej bazy. Czy możliwym jest taka konstrukcja by połączenia, warunkowość i zapytania nie wchodziły z sobą w konflikt?

  • Według założenia pierwszy if sprawdza czy pola tekstowe są puste.
  • Else od tego if'a wykonuje if'y podrzędne.
  • Poprzez zapytanie zawarte pod np using (cmd2) {i kolejne} if podrzędny ma sprawdzić czy wynik zapytania SELECT będzie inny niż zawartość TextBox12, a jeśli będzie inny to by inną zawartość zapisywał do BD "logi"
  • Identyczność wyniku zapytania z zawartością pola tekstowego przejawiać ma się w braku jakiejkolwiek reakcji

Coś jednak nie działa i w BD (zamiast zapisu tylko "różnych niż") zapisują się wszystkie dane wprowadzone w pola tekstowe i dropDownList.

Czy to z powodu zagęszczenia ifów? Czy może z użycia innego zapytania do każdego z ifów (taka deklaracja jest w ogóle możliwa?)?


        protected void Button1_Click(object sender, EventArgs e)
        {
            string sText1 = DropDownList1.SelectedItem.Text;
            string sText2 = DropDownList2.SelectedItem.Text;
            string sText3 = DropDownList3.SelectedItem.Text;
            string sText4 = DropDownList4.SelectedItem.Text;

            string SID = sText4;

            string connection_string1 = @"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=D:\projekty.accdb";
            string connection_string2 = @"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=D:\logi.accdb";

            OleDbConnection con1 = new OleDbConnection(connection_string1);
            OleDbConnection con2 = new OleDbConnection(connection_string2);

            string weryfikacja_zawartosci_nazwa_projektu = "SELECT Nazwa_projektu FROM projects WHERE " +
                                                            "Nazwa_projektu = " + DropDownList4.SelectedItem.Text + "";
            string weryfikacja_zawartosci_wlasciciel = "SELECT Wlasciciel FROM projects WHERE " +
                                                            "Nazwa_projektu = " + DropDownList4.SelectedItem.Text + "";
            string weryfikacja_zawartosci_data_rozpoczecia = "SELECT Data_rozpoczecia FROM projects WHERE " +
                                                            "Nazwa_projektu = " + DropDownList4.SelectedItem.Text + "";
            
            string zapytanie1 = "UPDATE projects " +
                            "SET Nazwa_projektu = @Nazwa_projektu, Wlasciciel = @Wlasciciel, Data_rozpoczecia = @Data_rozpoczecia, " +
                            "Data_zakonczenia = @Data_zakonczenia, Cel_projektu = @Cel_projektu, Project_manager = @Project_manager, " +
                            "Team_manager = @Team_manager, Executive = @Executive WHERE Nazwa_projektu = @SID";
            string zapytanie2 = "INSERT INTO historia_akcji (Czas_akcji, Nazwa_uzytkownika, Rodzaj_wartosci, Nowa_wartosc) values (@a,@b,@c,@d)";

            OleDbCommand cmd1 = new OleDbCommand(zapytanie1, con1);
            OleDbCommand cmd2 = new OleDbCommand(weryfikacja_zawartosci_nazwa_projektu, con1);
            OleDbCommand cmd2a = new OleDbCommand(zapytanie2, con2);
            OleDbCommand cmd3 = new OleDbCommand(weryfikacja_zawartosci_wlasciciel, con1);
            OleDbCommand cmd3a = new OleDbCommand(zapytanie2, con2);
            OleDbCommand cmd4 = new OleDbCommand(weryfikacja_zawartosci_data_rozpoczecia, con1);
            OleDbCommand cmd4a = new OleDbCommand(zapytanie2, con2);

            con1.Open();
            con2.Open();
if (string.IsNullOrEmpty(sText1) || string.IsNullOrEmpty(sText2) || string.IsNullOrEmpty(sText3))
            {
                Label12.Text = "Dane wprowadzone niepoprawnie. Uzupełnij dane. Pola nie mogą być puste.";
            }
            else
            {
                using (cmd2)
                {
                    if (weryfikacja_zawartosci_nazwa_projektu != TextBox12.Text)
                    {
                        using (cmd2a)
                        {
                            cmd2a.Parameters.AddWithValue("@a", DateTime.Now.ToString("yyyy/MM/dd, dddd, HH:mm:ss"));
                            cmd2a.Parameters.AddWithValue("@b", DropDownList1.SelectedItem.Text); 
                            cmd2a.Parameters.AddWithValue("@c", "Nazwa_projektu");
                            cmd2a.Parameters.AddWithValue("@d", TextBox12.Text);

                            cmd2a.ExecuteNonQuery();
                        }
                    }
                }
                using (cmd3)
                { 
                    if (weryfikacja_zawartosci_wlasciciel != TextBox2.Text)
                    {
                        using (cmd3a)
                        {
                            cmd3a.Parameters.AddWithValue("@a", DateTime.Now.ToString("yyyy/MM/dd, dddd, HH:mm:ss"));
                            cmd3a.Parameters.AddWithValue("@b", DropDownList1.SelectedItem.Text); 
                            cmd3a.Parameters.AddWithValue("@c", "Wlasciciel");
                            cmd3a.Parameters.AddWithValue("@d", TextBox2.Text);

                            cmd3a.ExecuteNonQuery();
                        }
                    }
                }
                using (cmd4)
                {
                    if (weryfikacja_zawartosci_data_rozpoczecia != TextBox3.Text)
                    {
                        using (cmd4a)
                        {
                            cmd4a.Parameters.AddWithValue("@a", DateTime.Now.ToString("yyyy/MM/dd, dddd, HH:mm:ss"));
                            cmd4a.Parameters.AddWithValue("@b", DropDownList1.SelectedItem.Text);
                            cmd4a.Parameters.AddWithValue("@c", "Data_rozpoczecia");
                            cmd4a.Parameters.AddWithValue("@d", TextBox3.Text);

                            cmd4a.ExecuteNonQuery();

                            //con2.Close();
                        }
                    }
                }
                else {}
1

Na pewno można przy pomocy OleDB operować na dwóch oddzielnych bazach danych. Nie powinno być z tym żadnego problemu.

Próbuję od kilku minut zrozumieć o co chodzi w tym kodzie i chyba okres świąteczny mi w tym przeszkadza.
Może na początek jakaś mała refakturyzacja ! :)

2

Pomijając inne rzeczy to zobacz pod debugerem co tak naprawdę porównujesz w tych ifach.

0

@jacek.placek: Debugger podaje mi zbyt ogólnikowy błąd, ale domyśliłem się, że błąd może polegać na tym, że w if'ach porównuje ciąg zapytania zamiast jego wynik. Zmieniłem więc np.:
weryfikacja_zawartosci_nazwa_projektu (który = "SELECT Nazwa_projektu FROM projects WHERE Nazwa_projektu = " + DropDownList4.SelectedItem.Text + "") na cmd2.ExecuteScalar().ToString() (gdzie cmd2 to OleDbCommand cmd2 = new OleDbCommand(weryfikacja_zawartosci_nazwa_projektu, con1)).
W dalszym ciągu jednak w 7-mym z kolei if'e debugger wyświetla błąd o treści:

System.Data.OleDb.OleDbException
HResult=0x80040E10
Message=Nie podano wartości dla jednego lub kilku wymaganych parametrów.
Source=<Nie można ocenić źródła wyjątku>
Ślad stosu:
<Nie można ocenić danych śledzenia>

"If" ten ma postać:

if (cmd7.ExecuteScalar().ToString() != DropDownList1.SelectedItem.Text)
                {
                    using (cmd7a)
                    {
                        cmd7a.Parameters.AddWithValue("@a", DateTime.Now.ToString("yyyy/MM/dd, dddd, HH:mm:ss"));
                        cmd7a.Parameters.AddWithValue("@b", DropDownList1.SelectedItem.Text);
                        cmd7a.Parameters.AddWithValue("@c", "Projekt_manager");
                        cmd7a.Parameters.AddWithValue("@d", sText1);

                        cmd7a.ExecuteNonQuery();
                    }
                }

gdzie:


OleDbCommand cmd7 = new OleDbCommand(weryfikacja_zawartosci_projekt_manager, con1);
OleDbCommand cmd7a = new OleDbCommand(zapytanie2, con2);

string connection_string1 = @"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=D:\projekty.accdb";
string connection_string2 = @"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=D:\logi.accdb";

OleDbConnection con1 = new OleDbConnection(connection_string1);
OleDbConnection con2 = new OleDbConnection(connection_string2);

string weryfikacja_zawartosci_nazwa_projektu = "SELECT Nazwa_projektu FROM projects WHERE Nazwa_projektu = " + DropDownList4.SelectedItem.Text + "";
string zapytanie2 = "INSERT INTO historia_akcji (Czas_akcji, Nazwa_uzytkownika, Rodzaj_wartosci, Nowa_wartosc) values (@a,@b,@c,@d)";

Wydaje się jednak, że ExecuteScalar().ToString() nie działa tak jak powinien, lub ja używam go niewłaściwie.

0

Gwneralnie w SQL teksty powinny być w apostrofach.
"Where cos Tam = '"+ txtValue +"'";
Ciężko się to czyta.
Błąd mówi raczej o braku wymaganego parametru czyli np po where costam = tu nie ma nic

0

@jacek.placek:
WHERE ma wartość:


WHERE Nazwa_projektu = " + DropDownList4.SelectedItem.Text + "

0

@jacek.placek:Dodałem apostrof i... działa :) Jednak nie wiem dlaczego z każdym ifem dodaje się także i if 7-dmy mimo, że nie zmieniany, a tylko zmiana określonego pola miałaby go wywoływać.

Zmiana natomiast wartości DropDownList odpowiadającego za if 7 "wyrzuca" środowisko VS

0

Moze wcześniejsze nie maja np spacji i jakoś przechodza.
Jak już Ci zadziała to co chcesz to poczytaj trochę i napisz lepiej.

2

Będziesz bluźnił na takie nazewnictwo szybciej niż myślisz :P
sText1 DropDownList1 sText2 DropDownList2 sText3 DropDownList3 sText4 DropDownList4 cmd1 cmd2 cmd2a cmd3 cmd3a cmd4 cmd4a

Czemu nie nazwiesz DropDownList1 np. ddlUserName? Czytając np. ddlUserName.SelectedValue od razu waidomo o co chodzi, za to czytając DropDownList1.SelectedValue lecimy od razu szukać czym jest ten DropDownList1. Nawet jak jesteś na bieżąco i pamiętasz wszystkie zmienne teraz, za miesiąc sam będziesz szukał tracąc 3x więcej czas niż na nazwanie sugerujące 'zawartość'.

0

@dlaFrajdy: Odpowiednie nazewnictwo mam zaplanowane na następny projekt ;)

0

Akurat nazewnictwo to jest mały problem w tym kodzie no ale każdy kiedyś zaczynał.
Zmiana nazw jest prosta. Klikasz na zmiennej, potem F2 i wpisujesz normalną nazwę.

Jeśli już musisz używać SQL-a to zawsze używaj parametrów. Nie wklejaj wartości do SQL bezpośrednio jak tu: "Nazwa_projektu = " + DropDownList4.SelectedItem.Text + "". Ktoś będzie złośliwy i będą problemy. Jak już się naklepiesz tego SQL w wystarczającej ilości to zobacz co daje EntityFramework.

Jeśli nie masz naprawdę, ale to naprawdę dobrego powodu to nie używaj operacji bazodanowych w UI. Przenieś do do osobnych klas (być może w osobnych dll). W UI tylko odczytuj dane z kontrolek, ewentualnie walidacja danych czy nie ma jakichś pustych stringów, czy wybrane jest cokolwiek z listy itp, a potem jakaś metoda AddProject(string name,...) w osobnej klasie np. ProjectService.

0

@jacek.placek: A no właśnie. Zwróciłeś uwagę na (prawdopodobnie) SQL Injection.... a co jeśli uniemożliwię wpisywanie innych znaków niż a-zA-Z0-9? Czy nie będzie to przypadkiem wystarczającą ochroną przed tym problemem?

Według mojej koncepcji każdy zalogowany użytkownik ma swoją własną kopię bazy danych (nie jest ona duża) na której operuje więc nawet w najgorszym przypadku nie może zrobić nic co by zaszkodziło komukolwiek innemu ;)

0

Troche pomoze ale być może w nazwach potrzebne będą mysliniki, apostrofy, cudzysłów itp. Trzeba by escapowac takie stringiprzed sklejania sql-a. Jak za starych czasów w php.
ORMy raczej załatwiają takie problemy.
Inna sprawa to utrzymanie takiego kodu, testy itp, ale to jeszcze chyba przed Tobą :).
Ja się staram nie cisnac ludzi za brzydki kod bo każdy dochodzi do jakosci we własnym tempie.
Jak wspomniałeś. Następny projekt będzie lepszy :)

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