[Delphi] Procedura tworząca zapytanie SQL

0

Witam chciałem zrealizować dodawanie pustych rekordów do wyświetlanej tabeli poprzez kliknięcie przycisku

Udało mi się to zrealizować tak

begin
if Form1.SQLDataSet1.Active then Form1.SQLDataSet1.close;   // jesli SQLDataSet1 wlaczony to wylacz         // uaktualnianie DBGrida
if Form1.ClientDataSet1.Active then Form1.ClientDataSet1.Close; // jesli ClientDataSet1 wlaczony to wylacz

Form1.SQLQuery1.Close;                       // otwurz SQLQuwery1
Form1.SQLQuery1.SQL.Clear;                   // wyczyść zaytanie SQL

zd:='insert into '+Form1.sComboBox1.Text+' (';
zd:=zd+sCombobox1.Items[0];
for q:=1 to SCombobox1.Items.Count-1 do
begin
zd:=zd+','+sCombobox1.Items[q];
end;
zd:=zd+') values (';
zd:=zd+#39+''+#39;
for q:=1 to sCombobox1.Items.Count-1 do begin
zd:=zd+','+#39+''+#39;
end;
zd:=zd+');';

Form1.SQLQuery1.SQL.Add(zd);
Form1.SQLQuery1.ExecSQL;                     // wyknaj polecenie // zmodyfikuj bazę

Form1.SQLDataSet1.Active := true;       // wlacz SQLDataSet1    // uaktualnianie DBGrida
Form1.ClientDataSet1.Active := true;   // wlacz ClientDataSet1

dopasuj_komurki2;    // dopasuj komórki do długości danych

sButton3.Enabled := false; // zabij sButton3 "dodaj"
sButton4.Enabled := true;  // uaktywnij sbutton4 "usuń"
end;

W tabeli zawierającej Imię , Nazwisko, Telefon wszystko jest w porządku procedura dodaje puste rekordy

Ale kiedy mam tabelę złożoną z kolumn Imię, Nazwisko, Pensja, Staz w kolumnach

Pensja i Staz otrzymuję po zerze

Nie wiem co może być tego przyczyną :-/

0

z twojego kodu nie wynika jakie dokladnie zapytanie leci do serwera
wklej raczej to co jest w zmiennej zd
jaki system bazodanowy uzywasz?
moze w kolumnach Pansja i Staz masz default value?

0

LOL a co to jest wg ciebie "pusty rekord"? Z pewnością '' to nie jest pusty rekord ale pusty string...

0

Zapytanie do Tabeli ADRESY wygląd następująco

insert into ADRESY
(Nazwisko, Adres, Telefon)
values
('','','')

A do drugiej tabeli tak samo tylko że z odpowiednio zmienionymi nazwami kolumn i ilością pustych komórek.

Baza której używam jest MySQL-owa.

"Pusty rekord" - chciałbym aby to był rekord który podczas przeglądania NIE MA żadnej zawartości czyli we wszystkich kolumnach są puste komórki.

0

wklej shcematy tabel, najlepiej create table ... dla obu

@AdamPL to ze faktycznie taki rekord jest co najmniej dziwny nie podlega dyskusji, ale moze jakas wysublimowana logika rozwiazania tego wymaga :D

0

Nie wiem co kolega ma na myśli mówiąc schematy tabeli ?

Jeśli chodzi o tabelę adresy to sam ją tworzyłem

create table ADRESY
(
Nazwisko varchar(40),
Adres varchar(50),
Telefon varchar(20)
);
Commit;

A jeśli chodzi o drugą to już nie jest moim tworem :)

Takie rozwiązanie zastosowałem bo chcę abym mógł dodawać pusty rekord do dowolnej tabeli poprzez naciśniecie przycisku.

Z tego co poczytałem prawdopodobnie pewne kolumny mają ustawione właściwość NOT NULL więc może dlatego zera się tam pojawiają ?

Jeśli tak będzie po prostu będę wypełnił komórki zerami

0

Żeby pola rekordu miały puste wartości (NULL) to trzeba użyć przy wstawianiu parametru związanego z danym polem i wywołać metodę tego parametru o nazwie "clear" a następnie ustawić właściwość parametru "bound" na true.

0

Dziękuję za pomoc ale nie wiem jakiego typu są pola a i tak nie jest istotna wartość tych <ort>pul </ort>bo poddawane są i tak edycji więc będę wypełnił rekordy zerami

Pozdrawiam i dziękuje

0

Mając dostęp do bazy danych dostaje się choćby najprostsze programy narzędziowe, które pokazują typy danych pól tabel. Wstawianie zer nie jest tym co NULL, szczególnie jeśli pola mogą i tak mogą przyjąć wartość zero w innych wypadkach. Mamy osobne zapytania w języku SQL dotyczące NULL (where nazwa_pola is null) i tak jest chyba szybciej wykonywane zapytanie. Podobnie wstawienie pustego ciągu znaków nie jest tym samym co wstawienie NULL.

0

Rzecz w tym, że ja tworzę ten program do obsługi bazy :)

0

Mariuszowi chodzilo czy tekze towrzysz baze lub czy masz do niej dostep za pomoca np. jakiegos managera gui, w ktorym mozesz poogladac sobie tabeli i typy kolumn

a wstawianie zer nie jest najlepszym pomyslem, bo jesli beda one zle interpretowane w programie? bo jak napisal Mariusz brak wartosci (NULL) to nie to samo co wartosc zero (0)

idea raczej jest taka, aby najpierw wprowazic pola dla danego rekordu, poddac walidacji i zapisac w bazie,
a nie wpisac "pusty" rekord, a pozniej go edytowac

0

Rzecz w tym, że to ja piszę interfejs GUI :), a moje kombinacje wynikają z tego bo musi się dać dodawać rekord do każdej wybranej tabeli gdybym miał jedną konkretną to nie miał bym problemu ale niestety mam kilka i to o różnych typach pól.

0

dobrze, rozumiem ze piszesz aplikacje, wnioskuje ze nie ty jestes autorem bazy i nie mozesz jej modyfikowac
rozumiem tez ze chcesz miec mechanizm ktory do dowolnej tabeli wstawia rekord
wiec jesli dobrze zrozumialem, to
zapoznaj sie z http://dev.mysql.com/doc/refman/5.1/en/columns-table.html
i generalnie z http://dev.mysql.com/doc/refman/5.1/en/information-schema.html
nie za duzo bawilem sie z MySQL wiec nie wiem jakies sa obostrzenia w uzyciu tych tabel systemowych, moze ktos inny cos o tym napisze
powinienes pobrac sobie schemat tabeli, rozpoznac jakie typy maja poza, czy mozna tam wstawic null, czy sa zdefiniowane wartosci domyslne dla kolumn (jesli w mySQL jest cos takiego)
i dopiero skonstruowac sensowne zapytanie insert, a nie na przypal wstawiac 3 kolumny i liczyc ze resza jakos tam sie wypelni

jesli potrzebujesz jakiegos innego rozwiazania napisz jasniej o co chodzi

0

Dziękuję za wyczerpującą odpowiedź

Wychodzi na to że muszę sprawdzać pojedynczo typy kolumn lub pół a następnie skonstruować zapytanie

Czyli moja procedura się rozrośnie.

Dzięki na pewno przeję materiały z linków

Widzę że odpowiadają mi fachowcy z zakresu baz danych i MySQL-a to chciałbym zapytać jak pobrać konkretną daną z komórki jaką postać miało by zapytanie SQL-owe ?

0

nie wiem czy o to ci chodzi, bo to podstawowa skladnia select
select KolumnaX from Tabela where Id = ilesTam

czy masz pole "wielowartosciowe" i chcesz czesc jego wartosci pobrac?

0

Chciałbym na przykład pobrać z tabeli adresy z kolumny telefon pierwszy wiersz tej że kolumny. czyli pierwszą komórkę z kolumny.

P.S Czy pole ID musi być wyświetlane czy jest to niewidoczna kolumna dla klienta.

Pozdrawiam

0

Zapewne chodzi o sytuację, gdy osoba przegląda rekordy w tabelce i klika na pole w wybranym rekordzie. Zarówno w zwykłej aplikacji jak w aplikacji internetowej następuje programowe połączenie umożliwiające rozpoznanie jakie ID ma kliknięty rekord i na tej podstawie można na przykład wyświetlić osobne okno z tym jednym rekordem pobranym przez zapytanie SQL którego bazą jest jedynie to ID (klucz główny). ID nie musi być wyświetlane dla użytkownika bo najczęściej jest mu niepotrzebne, gdyż identyfikuje on rekord na podstawie innych pól. Ono tylko ułatwia wynajdywanie danych programowi.

0

Zmierzam do tego w swojej aplikacji i nie mogę rozwiązać tego problemu aby to było takie proste i przyjemne dla użytkownika.

Pytałem o nr ID bo kiedy sformułował zapytanie aby usunął ostatni rekord z bazy to komunikat był że nie znaleziono ID bo faktycznie tam go nie było :)

0
blue_17 napisał(a)

Zmierzam do tego w swojej aplikacji i nie mogę rozwiązać tego problemu aby to było takie proste i przyjemne dla użytkownika.

Pytałem o nr ID bo kiedy sformułował zapytanie aby usunął ostatni rekord z bazy to komunikat był że nie znaleziono ID bo faktycznie tam go nie było :)

Może nastąpić taka sytuacja i to jest tylko wtedy, gdy użytkownik na innej końcówce w tym samym czasie zrobi operację która na przykład skasuje rekord z tym ID. Czyli to musiałoby nastąpić po wyświetleniu tabelki rekordów przez pierwszego użytkownika a przed wybraniem przez pierwszego użytkownika z tabelki rekordu który już został skasowany przez drugiego użytkownika. Oczywiście procedura wyszukująca rekord o wybranym ID powinna to uwzględniać i w razie nie znalezienia rekordu wyświetlać zamiast niego komunikat, że rekord został skasowany.
Należy pamiętać o tym że te sytuacje będą normalnie występować przy wielu użytkownikach łączących się jednocześnie, bo wyświetlenie tabelki to jest jedna transakcja, a wybranie z niej rekordu do jego osobnej edycji to jest druga osobna transakcja i użytkownik na innej końcówce ma pełne możliwości zrobienia swojej transakcji między nimi. Może nawet być tak, że chcemy zapisać zmieniony rekord (trzecia już transakcja) i wtedy dopiero okazuje się że on już został skasowany na innej końcówce. Taką sytuację też należy przewidzieć, bo rekordów nie blokuje się, poprzez transakcję, na czas edycji (która może trwać wiele minut) tylko na czas zapisu zmian (ułamek sekundy).

0

uzupelnie tylko powyzsza wypowiedz o haslo timestamp
poczytaj na ten temat, jesli nie chce aby jeden uzytkownik nadpisywal zmiany innego

0
massther napisał(a)

uzupelnie tylko powyzsza wypowiedz o haslo timestamp
poczytaj na ten temat, jesli nie chce aby jeden uzytkownik nadpisywal zmiany innego

Ja po prostu dodaję dodatkową kolumnę zawierającą licznik wersji. Przy każdym update zwiększam go o jeden. Przy wyświetlaniu wybranego rekordu (do edycji) odczytuję licznik wersji dla tego rekordu a przed zapisem sprawdzam, czy się nie zmienił (poprzez działania innego użytkownika na innej końcówce). Zmiana jego wartości wskazuje na to, że rekord nie jest aktualny. Jeśli licznik wersji nie jest taki sam, nie wykonuję zapisu, informuję użytkownika że rekord został zmieniony przez innego użytkownika i wyświetlam wszystkie pola zmienionego rekordu (odświeżam).

O ile pamiętam, jeżeli używa się ClientDataSet z TDataSetProvider to on automatycznie sprawdza wersję jeśli się w TDataSetProvider ustawi UpdateMode:=UpdateWhereAll.

0

no i wlasnie napisales jak dziala timestamp :)
np. w ms sql jest to realizowane z automatu

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