[Delphi] Dodawanie danych do bazy Interbase

0

Cześć!

Od razu mówię, że jestem żółtodziób w tych klockach, zatem prosze o wyrozumiałość.
Przeczytałem artykuły Artura o bazie Interbase i Delphi 7.

Nie potrafię jednak napisać procedury pod buttona aby mi dodawał rekord, usuwał lub edytował :( Tamten artykuł był dla mnie za trudny, pomimo że stworzyłem swoją bazę w Interbase. Odczytałem ją w Delphi, działam na tych samych komponentach, co Artur czyli na IB...

Nie ma jakiejś prostszego zapytania SQL do dodania - usuwania - edycji rekordów?
Po prostu nie mogłem się tam połapać, dla mnie to jeszcze za trudne :(

1.Jak dodać rekord zapytaniem SQL?
2. Jak usunąć rekord zapytaniem SQL?
3. Jak edytować rekord zapytaniem SQL?

Oczywiście uwzględniając aktualizację bazy. Z góry WIELKIE DZIĘKI za pokazanie i wyjaśnienie mi tego!!! [browar]

0

Bo wypadało by dowiedzieś się cokolwiek o tym co che się robić. Poczytaj może co to jest relacyjna baza danych, co to są postacie normalne, normalizacja, przerób najprostszy kurs SQLa. Oczywiście teoria nie będzie Ci ppotrzebna jeśli ta baza to jedna tabelka z trzema polami i docelowo z 50 rekordami ale jeśli masz zamiar zagłębić się w tematykę baz danych to bez podstaw się nie obejdzie.

Dodać rekord
INSERT INTO nazwa_tabeli(lista_pol) VALUES(lista_wartosci)

Usunąć rekord
DELETE FROM nazwa_tabeli WHERE pole_kluczowe = wartosc_kluczowa_usuwanego_rekordu

Edytować rekord
UPDATE nazwa_tabeli SET pole_1 = nowa_wartosc_1, pole_2 = nowa_wartosc_2, ...

No i po każdej operacji trzeba zatwierdzić transakcję

To jest trudne tylko na pierwszy rzut oka, a jak zapoznasz się z podstawami i poćwiczysz trochę to zobaczysz, że to wcale nie jest takie trudne.

0

Podstawy myslę, że opanowałem.
W Interbase przerobiłem:

  • Wyświetlanie rekordów
  • Dodawanie/usuwanie rekordów
  • Sortowanie rekordów
  • Wyświetlanie zakresów (between...and)
  • Tworzenie indexów
  • Wyszukiwanie rekordów i filtrowanie
    i wiele, wiele innych zapytań, także mogę stwierdzić że SQL to jest to czego potrzebowałem cały czas!

Teraz przyszła kolej na przelanie wiedzy do Delphi, co ku zaskoczeniu poszło mi to gładko do pewnego momentu, gdy zaczaąłem Tworzyć zapytanie dodawania rekordu i napisałem takie coś:

Moje baza nazywa się BOOK. Tworzę bazę z książką telefoniczną (standardzik :))

procedure TForm1.Button3Click(Sender: TObject);
begin
IBQuery1.Close;
IBQuery1.SQL.Clear;
 if not IBTransaction1.InTransaction then
           IBTransaction1.StartTransaction;
IBQuery1.SQL.Add('Insert into Book (nr_id,imie,nazwisko,data_ur,adres,telefon) Values("'+Edit1.Text+'", "'+Edit2.Text+'", "'+Edit3.Text+'", "'+Edit4.Text+'", "'+Edit5.Text+'", "'+Edit6.text+'");');
     IBQuery1.ExecSQL;
        IBTransaction1.Commit;
IBQuery1.Post;
end;

I gdy próbuję dodać dane do tabeli to wyskakuje mi błąd: "Unknown Column: 4"
Liczbę 4 wpisuję do Edit1, który odpowiada za pole Nr_ID. Dziwne, nie wiem o co chodzi. Traktuje tą "4" jak nazwę kolumny. Spróbowałem też zamiast "4" wpisać "Nr_ID" i to samo wyskoczyło :(

Nie wiem czy dobrze napisałem instrukcję dodawania rekordu. Poprawcie mnie gdzie napisałem ją źle [browar] Z góry dzięki!!!

0
with IBQuery1, SQL do
begin
  Clear;
  Add('INSERT INTO book(nr_id, imie, nazwisko, data_ur, adres, telefon) VALUES (:nr_id, :imie, :nazwisko, :data_ur, :adres, :telefon)');
  ParamByName('nr_id').AsInteger := StrToInt(Edit1.Text);
  ParamByName('imie').AsString := Edit2.Text;
  ParamByName('nazwisko').AsString := Edit3.Text;
  ParamByName('data_ur').AsString := Edit4.Text;
  ParamByName('adres').AsString := Edit5.Text;
  ParamByName('telefon').AsString := Edit6.Text;
  ExecSQL;
end;

i bez IBQuery1.Post;

0

Dzięki piękne!! Działa, aż się kurzy :)
Właśnie chodziło o napisanie jeszcze tych parametrów przeze mnie.

Mam jeszcze pytanie: otóż nr_ID to numeracja rekordu u mnie itd.
Jak mogę potem zaktualizować numery rekordów jeśli mam 4 rekordy a usunę trzeci i zostanie 1, 2, 4? A ma być 1, 2, 3.

Czy to będzie coś podobnego jak pokazał to Artur w swoim artykule tam gdzie jest MAX ID itd.?

0

Z założenia ID to unikalny identyfikator rekordu i

  1. powinno się ustalac jego wartość przez generator i wyzwalacz (auto increment)
  2. jeśli koniecznie chcesz zmienić te numery to możesz tak

UPDATE book SET nr_id = nr_id - 1 WHERE nr_id > :nr_id
i jako parametr nr_id wstawiasz id usuniętego rekordu

Jeśli jednak masz inną tabele powiązaną z tabelą book przez pole nr_id to musisz to uaktualnić we WSZYSTKICH tabelach

0

Jednak będę używał wyzwalaczy i generatorów do autoincrementacji. Poczytałem trochę o tym i jest dosyć ciekawe, ale nie wiedziałem, że te numerowanie będzie takie skomplikowane, bo jeśli usunę rekordy z jakiegoś zakresu?
Np: rekordy od 3 do 17 na 20 rekordów w bazie to już tak kolorowo nie jest.
Zostaną mi:
1
2
18
19
20
Wtedy zaczyna się zabawa z ponumerowaniem odpowiednio tych nr_id ;)
Spróbuję wykonać autonumeracje PRZED (BEFORE INSERT) dodaniem rekordu i PO usunięciu rekordu(ów) (AFTER DELETE). :)

0

ale po co chcesz to zmieniać???? Jeśli chcesz mieć numerację pozycji to to się robi na polach kalkulowanych. POLE ID JEST DO IDENTYFIKACJI REKORDU A NIE JEGO NUMERACJI!

0

Czyli już rozumiem.
NR_ID, ogólnie tam gdzie stawiamy klucz główny do konkretnego pola, to pole te jest naszym identyfikatorem. Każdy rekord posiada swój unikalny identyfikator i nie należy go zmieniać.

Jeśli chciałbym koniecznie numerację rekordów, która zmieniałaby się, to muszę dorobić dodatkowe pole w tabeli np.: LP INTEGER NOT NULL, (nie chcę aby zostawało puste, dlatego NOT NULL) i tam wtedy sobie robię autonumerację i te inne pierdoły. Pole NR_ID ewentualnie mogę ukryć.

Usuwanie rekordu będzie się odbywało wtedy też po NR_ID, bo raczej nie usunę rekordu po zwykłym polu NR, racja?
Jeśli źle to wszystko zrozumiałem to mnie popraw.

0
Domek napisał(a)

Czyli już rozumiem.
NR_ID, ogólnie tam gdzie stawiamy klucz główny do konkretnego pola, to pole te jest naszym identyfikatorem. Każdy rekord posiada swój unikalny identyfikator i nie należy go zmieniać.

Dokładnie

Jeśli chciałbym koniecznie numerację rekordów, która zmieniałaby się, to muszę dorobić dodatkowe pole w tabeli np.: LP INTEGER NOT NULL, (nie chcę aby zostawało puste, dlatego NOT NULL) i tam wtedy sobie robię autonumerację i te inne pierdoły. Pole NR_ID ewentualnie mogę ukryć.

no nie do końca. Jeśli bedziesz potrzebował wybrać tylko te rekordy, które spełniają jakiś warunek to Twoja numeracja weźmie w łeb. Jeśli ta numeracja ma być tylko dla informacji usera i nie ma spełniać żadnej innej roli to robi się to tak, że w Query (Table) klikasz dwa razy lewym, potem prawy na tym okienku i Add All Fields... a następnie New Field i dla tego nowego wybierasz FieldType Calculated, name np. LP, Type Integer a w zdarzeniu OnCalcField wpisujesz
DataSet.FieldByName('Lp').AsInteger:= DataSet.RecNo;

W FB działa na 100%

Usuwanie rekordu będzie się odbywało wtedy też po NR_ID, bo raczej nie usunę rekordu po zwykłym polu NR, racja?

Racja

0
  1. Kurde te usuwanie nie działa mi jak powinno :/
 IBQuery1.Close;
IBquery1.SQL.Clear;
IBQuery1.SQL.Add('Delete from Book where nr_id = :nr_id');
IBQuery1.ParamByName('nr_id').AsInteger :=StrToInt(Edit7.text);
        IBquery1.ExecSQL;
   IBTransaction1.Commit;

Usunę jakiś rekord to jest dobrze, ale jak chcę usunąć jakiś inny rekord to wyskakuje mi błąd: violation of PRIMARY or UNIQUE KEY constraint INTEG_7 on table BOOK.

  1. Utworzyłem dodatkowe pole 'LP' tak jak Misiekd pokazał, ale niestety przy sortowaniu (poprzez kliknięcie na tytuł kolumny), autoincrementacji te pole w ogóle nie istnieje! Pisze że "Unknown Column LP". Widoczne jest tylko przy dodawaniu lub usuwaniu rekordu, widoczne czyli że działa w tym polu opcja Calculated.

Nie wiem jak to zrobić aby te pole było tak samo traktowane jak pozostałe, które stworzyłem w Interbase (LP stworzyłem już w Delphi).

  1. Wspomniane było cos o zatwierdzeniu transakcji lub też cofnięciu jej.
    Jak to wykonywać przy operacjach w bazie? Jak to ma wyglądać kodowo i czy to ma być uwzględnione w SELECT, DELETE, UPDATE, INSERT i innych?

  2. Mam problem z napisaniem zapytanie zakresu np. dat i robię takie coś:

procedure TForm1.Button2Click(Sender: TObject);
begin
with IbQuery1, SQL do begin
 Close;
  Clear;
   Add('SELECT Data_ur FROM Book where Data_ur BETWEEN '+DateToStr(Od1.Date)+ 'and' +DateToStr(Do1.Date)'+';');
ParamByName('Data_ur').AsDate:=+DateToStr(Od1.Date);
ParamByName('Data_ur').AsDate:=+DateToStr(Do1.Date);
   Open;
   end; end;

Nie kompiluje się program. Nie wiem jak to napisać. Czy może ktoś to poprawić?

  1. Czy klauzula GROUP BY służy do sumowania dowolnej kolumny z wartościami numerycznymi?

  2. Chciałbym kiedyś napisać prostą stronkę WWW z jakimiś Edit'ami do wpisania danych. Dane wprowadzane by były do bazy, której obecnie piszę w Delphi.
    Czy musze tu stosować PHP? Jak to najlepiej zrobić?

Dzięki za wszystkie odpowiedzi. To bardzo ważne dla mnie, ponieważ się bardzo wkręciłem w SQL i już nie popuszczę tego :) Ostatnimi dniami tylko tym żyję!!! [browar]

0

Dzięki. Ogólnie wiem jak się pisze zapytanie Between and, bo ćwiczyłem w Interbase i mi to wychodziło, ale nie umiem poprawnie zapisać tego w Delphi uwzględniając w to komponenty Edit, DTP lub MaskEdit. Po prostu nie wiem jak to zrobić :(

Co do usuwania rekordu to spróbuję coś innego wymyśleć.

0

OK do zapytania z zakresów doszedłem :):

procedure TForm1.Button2Click(Sender: TObject);
begin
with IbQuery1, SQL do begin
 Close;
  Clear;
   Add('SELECT * FROM Book where Data_ur BETWEEN :Data_Ur and :Data_Ur2'+';');
ParamByName('Data_Ur').AsDate:=StrToDate(Od1.Text);
ParamByName('Data_Ur2').AsDate:=StrToDate(Do1.Text);
   Open;
   end; end;
0
  1. średnik na końcu zapytania nie jest konieczny
  2. usuwanie biorąc Twój kod z postu wyżej
procedure TForm1.Button2Click(Sender: TObject);
begin
  with IbQuery1, SQL do begin
    Close;
    Clear;
    Add('DELETE FROM Book WHERE data_ur BETWEEN :data_Ur and :data_Ur2');
    ParamByName('Data_Ur').AsDate := StrToDate(Od1.Text);
    ParamByName('Data_Ur2').AsDate := StrToDate(Do1.Text);

{  wersja jeśli chcesz usunąć konkretny jeden rekord 
    Add('DELETE FROM Book WHERE pole_kluczowe = :klucz');
    ParamByName('klucz').AsInteger := Jakis_klucz; }

    ExecSQL;
  end; 
end;
0

Misiekd napisał:

procedure TForm1.Button2Click(Sender: TObject);
begin
  with IbQuery1, SQL do begin
    Close;
    Clear;
    Add('DELETE FROM Book WHERE data_ur BETWEEN :data_Ur and :data_Ur2');
    ParamByName('Data_Ur').AsDate := StrToDate(Od1.Text);
    ParamByName('Data_Ur2').AsDate := StrToDate(Do1.Text);

{  wersja jeśli chcesz usunąć konkretny jeden rekord 
    Add('DELETE FROM Book WHERE pole_kluczowe = :klucz');
    ParamByName('klucz').AsInteger := Jakis_klucz; }

    ExecSQL;
  end; 
end;

Zgadza się, ale ten kodzik usunie (DELETE FROM) mi rekordy z danego zakresu :)
A ja mam tylko wyświetlić (SELECT). Czyli tam dobrze miałem: :)
A co do usuwania rekordu to tak usuwam rekord tak jak pisałeś:

{ wersja jeśli chcesz usunąć konkretny jeden rekord
Add('DELETE FROM Book WHERE pole_kluczowe = :klucz');
ParamByName('klucz').AsInteger := Jakis_klucz; }

Męczy mnie jeszcze podanie MAX ID, a raczej napisanie do niego parametru.

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