[Delphi, MySQL] Dodawanie rekordów do tabeli

0

To chyba bardziej dotyczy baz danych ale program jest w Delphi więc piszę tutaj.

Mam taką sytuację że w pewnym momencie dodaję nowy rekord do tabeli i w następnym kroku muszę dodać kilka rekordów zależnych od tego pierwszego do drugiej tabeli.
W pierwszej tabeli ID rekordów jest dodawane przez auto-inkrementację, by dodać rekordy do drugiej tabeli potrzebuję id rekordu właśnie dodanego do pierwszej.

Pytanie, w jaki sposób pobrać id tego dodanego wpisu z tabeli pierwszej?

Ja już to zrobiłem po swojemu, trochę "na około" problemu. Chciałbym się od Was dowiedzieć jak to się robi profesjonalnie.

Potrzebuję tylko krótki opis postępowania w takiej sytuacji.

0

Może Ci sie przydać taka instrukcja ktora zwraca ostatni zapisany ID

last_insert_id()

Mozesz to wstawic jako parametr zapytania na miejscu ID.

0

Ok, ale program jest wieloużytkownikowy i działa na kilku stanowiskach. Jaką mam pewność że last_insert_id() da mi ID rekordu dodanego przeze mnie a nie rekordu dodanego przez panią Jadzię z siódmego piętra. Jej rekord może wskoczyć gdzieś pomiędzy moje zapytania i zrobi się bałagan.

0

A może spróbuj pobrać ID z tej pierwszej tabeli na podstawie tego co dodajesz do niej, np.

SELECT id FROM tabela1 where wartosc_pola1=to_co_przed_chwila_dodales_do_pola_pierwszego

, albo jak masz użytkowników w bazie to jak pisał maciejmt: last_insert_id()

 tylko dodaj do tego jeszcze użytkownika, który to dodał (tego nie testowałem, więc nie wiem czy działa?). 
Mam nadzieję, że zrozumiałeś  moją koncepcję? ;-)
0

Ale ze mnie tępak :)

Jasne że mam użytkowników w bazie. Sprawa załatwiona. Dziękuje wam obu.

0
AngelEyes napisał(a)

Ok, ale program jest wieloużytkownikowy i działa na kilku stanowiskach. Jaką mam pewność że last_insert_id() da mi ID rekordu dodanego przeze mnie a nie rekordu dodanego przez panią Jadzię z siódmego piętra. Jej rekord może wskoczyć gdzieś pomiędzy moje zapytania i zrobi się bałagan.

Pewnie - lepiej pytać zamiast wziąć i wpisać (ba, przekleić, a jak masz operę to kliknąć dwa razy i wybrać szukaj) w google i przeczytać

MySQL Manual napisał(a)

For LAST_INSERT_ID(), the most recently generated ID is maintained in the server on a per-connection basis. It is not changed by another client. It is not even changed if you update another AUTO_INCREMENT column with a nonmagic value (that is, a value that is not NULL and not 0). Using LAST_INSERT_ID() and AUTO_INCREMENT columns simultaneously from multiple clients is perfectly valid. Each client will receive the last inserted ID for the last statement that client executed.

maciejmt napisał(a)

Ja kiedys probowalem sterowac last_insert_id(), (np z tabeli X), ale to nie skutkowało poprawnie.
A skąd pewność, że to wina bazy a nie Twoja?

Wiec raczej jedynym wyjsciem bedzie wyselektowanie tego, co zainsertowales :-)
i to jest najgorsze rozwiązanie

jawor1104 napisał(a)

A może spróbuj pobrać ID z tej pierwszej tabeli na podstawie tego co dodajesz do niej, np.

SELECT id FROM tabela1 where wartosc_pola1=to_co_przed_chwila_dodales_do_pola_pierwszego

Pewnie, szczególnie jak tych wstawianych wartości jest ze 30. Z drugiej strony po co optymalizować programy - za wolno działa, zmieńmy sprzęt!!

albo jak masz użytkowników w bazie to jak pisał maciejmt:

last_insert_id()

użytkownicy nie mają tu nic do rzeczy. Możesz mieć jednego usera a to i tak będzie działać - dlaczego, masz napisane powyżej

tylko dodaj do tego jeszcze użytkownika, który to dodał (tego nie testowałem, więc nie wiem czy działa?).
tylko jestem ciekaw gdzie i jak tego usera miałby dodać :>

0
Misiekd napisał(a)
AngelEyes napisał(a)

Ok, ale program jest wieloużytkownikowy i działa na kilku stanowiskach. Jaką mam pewność że last_insert_id() da mi ID rekordu dodanego przeze mnie a nie rekordu dodanego przez panią Jadzię z siódmego piętra. Jej rekord może wskoczyć gdzieś pomiędzy moje zapytania i zrobi się bałagan.

Pewnie - lepiej pytać zamiast wziąć i wpisać (ba, przekleić, a jak masz operę to kliknąć dwa razy i wybrać szukaj) w google i przeczytać

MySQL Manual napisał(a)

For LAST_INSERT_ID(), the most recently generated ID is maintained in the server on a per-connection basis. It is not changed by another client. It is not even changed if you update another AUTO_INCREMENT column with a nonmagic value (that is, a value that is not NULL and not 0). Using LAST_INSERT_ID() and AUTO_INCREMENT columns simultaneously from multiple clients is perfectly valid. Each client will receive the last inserted ID for the last statement that client executed.

maciejmt napisał(a)

Ja kiedys probowalem sterowac last_insert_id(), (np z tabeli X), ale to nie skutkowało poprawnie.
A skąd pewność, że to wina bazy a nie Twoja?

Wiec raczej jedynym wyjsciem bedzie wyselektowanie tego, co zainsertowales :-)
i to jest najgorsze rozwiązanie

jawor1104 napisał(a)

A może spróbuj pobrać ID z tej pierwszej tabeli na podstawie tego co dodajesz do niej, np.

SELECT id FROM tabela1 where wartosc_pola1=to_co_przed_chwila_dodales_do_pola_pierwszego

Pewnie, szczególnie jak tych wstawianych wartości jest ze 30. Z drugiej strony po co optymalizować programy - za wolno działa, zmieńmy sprzęt!!

albo jak masz użytkowników w bazie to jak pisał maciejmt:

last_insert_id()

użytkownicy nie mają tu nic do rzeczy. Możesz mieć jednego usera a to i tak będzie działać - dlaczego, masz napisane powyżej

tylko dodaj do tego jeszcze użytkownika, który to dodał (tego nie testowałem, więc nie wiem czy działa?).
tylko jestem ciekaw gdzie i jak tego usera miałby dodać :>

chociażby tak:

SELECT (id) FROM tabela1 where (id=last_insert_id() and (kto_modyfikowal= 'użytkownik_który_dodał_rekord'));

o ile oczywiście zapisuje do bazy, kto dodał dany rekord (czyli kto jest zalogowany w programie)?

0
jawor1104 napisał(a)

chociażby tak:

SELECT (id) FROM tabela1 where (id=last_insert_id() and (kto_modyfikowal= 'użytkownik_który_dodał_rekord'));

o ile oczywiście zapisuje do bazy, kto dodał dany rekord (czyli kto jest zalogowany w programie)?

i przemyślałeś to co tu pisze :>

bo nie wiem czy wiesz, ale last_insert_id zwraca JEDNE numer i jakikolwiek byś warunek nie dopisał (oczywiście mowa o warunku AND) to NIGDY nie dostaniesz innego id niż to zwrócone przez last_insert_id (pomijam fakt, że najwyżej nie dostaniesz żadnego)

0
Misiekd napisał(a)
jawor1104 napisał(a)

chociażby tak:

SELECT (id) FROM tabela1 where (id=last_insert_id() and (kto_modyfikowal= 'użytkownik_który_dodał_rekord'));

o ile oczywiście zapisuje do bazy, kto dodał dany rekord (czyli kto jest zalogowany w programie)?

i przemyślałeś to co tu pisze :>

bo nie wiem czy wiesz, ale last_insert_id zwraca JEDNE numer i jakikolwiek byś warunek nie dopisał (oczywiście mowa o warunku AND) to NIGDY nie dostaniesz innego id niż to zwrócone przez last_insert_id (pomijam fakt, że najwyżej nie dostaniesz żadnego)

Faktycznie z tym

las_insert_id()

to lipa, a co powiesz na to:

SELECT id FROM tabela where ( kto_modyfikowal= 'użytkownik_który_dodał_rekord') order by id desc limit 1
0

ano tyle, że przeważnie w aplikacjach desktop (a w serwisach www prawie zawsze) user, na którego aplikacja łączy się do bazy jest jeden. Natomiast kwestię uprawnień do programu i użytkowników samej aplikacji rozwiązuje się "we własnym zakresie". Inna sprawa, że nikt mi nie zabroni uruchomić dwóch kopii programu i na obu się zalogować. Jak myślisz czy w takim wypadku dostanę to ID które powinienem, czy po prostu ostatnio dodane.

Nie ma co wymyślać niestworzonych historii - każda baza ma rozwiązany problem pobierania wartości wstawianej do pola autoinc i z tego należy korzystać a nie z jakichś dziwolągów

0
Misiekd napisał(a)

ano tyle, że przeważnie w aplikacjach desktop (a w serwisach www prawie zawsze) user, na którego aplikacja łączy się do bazy jest jeden. Natomiast kwestię uprawnień do programu i użytkowników samej aplikacji rozwiązuje się "we własnym zakresie". Inna sprawa, że nikt mi nie zabroni uruchomić dwóch kopii programu i na obu się zalogować. Jak myślisz czy w takim wypadku dostanę to ID które powinienem, czy po prostu ostatnio dodane.

Nie ma co wymyślać niestworzonych historii - każda baza ma rozwiązany problem pobierania wartości wstawianej do pola autoinc i z tego należy korzystać a nie z jakichś dziwolągów

To też w zależności jak ma rozwiązany problem kilku użytkowników, czy każdy ma swoje konto w bazie, czy wszyscy logują się na jedno i to samo. Mam wrażenie, że niedokładnie się zrozumieliśmy - mi nie chodziło o to, żeby tworzyć każdemu użytkownikowi konta na serwerze, tylko np. ja też w programie łączę się z bazą danych jako root, ale dodatkowo mam tabelę użytkownicy, gdzie sobie definiuję użytkowników (ich uprawnienia itp.) i np. jak dodaję coś do bazy, to mam też pole "kto_dodał" i tam zapisuję sobie użytkownika aktualnie zalogowanego (w programie) - który zapisał coś do bazy.

0

ale ja Cię doskonale rozumiem

Misiekd napisał(a)

Inna sprawa, że nikt mi nie zabroni uruchomić dwóch kopii programu i na obu się zalogować. Jak myślisz czy w takim wypadku dostanę to ID które powinienem, czy po prostu ostatnio dodane
i nie powiesz mi chyba, że w Twoim programie tak nie można

0
Misiekd napisał(a)

ale ja Cię doskonale rozumiem

Misiekd napisał(a)

Inna sprawa, że nikt mi nie zabroni uruchomić dwóch kopii programu i na obu się zalogować. Jak myślisz czy w takim wypadku dostanę to ID które powinienem, czy po prostu ostatnio dodane
i nie powiesz mi chyba, że w Twoim programie tak nie można

Jasne, że można. Tylko w moim przypadku ja mam sprawę rozwiązaną jak pisałem wcześniej:
podaję "kto_modyfikowal" i po problemie - dostaję to ID które chce ;-)
A czy to akurat najprostrzy sposób - to już inna bajka - ważne że działa :-)

Ps. To żeśmy sobie porozmawiali :-)

0

dalej nie rozumiesz - odpalam Twój program dwa razy (na dwóch kompach jak chcesz), na obu loguję się tym samym userem (rozumiem, że "kto_modyfikowal" jest ten sam) i dodaję w tym samym czasie na tych dwóch wersjach taki sam dokument - które ID odczyta każda z wersji?

0
Misiekd napisał(a)

dalej nie rozumiesz - odpalam Twój program dwa razy (na dwóch kompach jak chcesz), na obu loguję się tym samym userem (rozumiem, że "kto_modyfikowal" jest ten sam)

tak, kto modyfikowal jest oczywiście ten sam, ale nie rozumiem czemu ma się logować 2 różnych użytkownków w tym samym czasie na to samo konto (tym samym userem)? moim zdaniem to bez sensu - nie po to tworzyłem tabele z userami i tam im zakładałem konta, żeby teraz wszyscy logowali się na to samo.

i dodaję w tym samym czasie na tych dwóch wersjach taki sam dokument - które ID odczyta każda z wersji?

w tym samym czasie? trochę mało prawdopodobne, ale możliwe - odczyta ostatnio dodane.

0

i pewnie nie widzisz tutaj żadnego problemu :>

BTW to to jest normalnie perełka i WTF roku

jawor1104 napisał(a)

nie po to tworzyłem tabele z userami i tam im zakładałem konta, żeby teraz wszyscy logowali się na to samo.

biedny programista tak się napocił, potworzył tabele, konta a ten wredny user wszędzie loguje się na konto testowe... Chyba za mało jeszcze widziałeś, że masz takie podejście

0
Misiekd napisał(a)

i pewnie nie widzisz tutaj żadnego problemu :>

BTW to to jest normalnie perełka i WTF roku

jawor1104 napisał(a)

nie po to tworzyłem tabele z userami i tam im zakładałem konta, żeby teraz wszyscy logowali się na to samo.

biedny programista tak się napocił, potworzył tabele, konta a ten wredny user wszędzie loguje się na konto testowe... Chyba za mało jeszcze widziałeś, że masz takie podejście

A co za problem wyłączyć konto testowe (jak je nazwałeś), administrację kontami masz z poziomu serwera jak i programu - więc w czym problem? O ile oczwiście je tworzyłeś?

0

zgadzam sie z miskiemD <ort>poco </ort>wywazac otwarte drzwi. skoro baza cos oferuje to na <ort>holere </ort>pisac jakies dziwaczne fukncje skoro to działa dobrze. nie rozumiem <ort>poco </ort>komplikowac sobie zycie

0
http://dev.mysql.com/doc/refman/5.0/en/getting-unique-id.html napisał(a)

For LAST_INSERT_ID(), the most recently generated ID is maintained in the server on a per-connection basis. It is not changed by another client. It is not even changed if you update another AUTO_INCREMENT column with a nonmagic value (that is, a value that is not NULL and not 0). Using LAST_INSERT_ID() and AUTO_INCREMENT columns simultaneously from multiple clients is perfectly valid. Each client will receive the last inserted ID for the last statement that client executed.
wyważacie szeroko otwarte drzwi

@AngelEyes - masz problem z google, czy z angielskim?

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