Pouziti autoincrementu
Honza Pazdziora
adelton na informatics.muni.cz
Pátek Červen 20 13:59:52 CEST 2003
On Thu, Jun 19, 2003 at 04:13:36PM +0200, Petr Vileta wrote:
> > > create table test(cislo int(10) autoincrement, neco varchar(20));
> > > insert into test set neco='ABC';
> > > insert into test set neco='DEF';
> >
> > Ufff, piste prosim ty priklady tak, aby si to lidi mohli vzit mysi
> > a vyzkouset ...
> Co je spatne? Ja to takhle vzal z DOS okna a Ctrl-V :-)
mysql> create table test(cislo int(10) autoincrement, neco varchar(20));
ERROR 1064: You have an error in your SQL syntax near 'autoincrement, neco varchar(20))' at line 1
Verze MySQL 3.23.42.
> > No, evidentne jste chtel, aby kdyz smazete cislo z prostredka, aby Vam
> > databazovy stroj precisloval vsechna cisla nad tim? To snad ne.
> Ne, chtel jsem smazat posledni zaznam, to se v ucetnictvi dost casto
> pouziva, ze se maze naposledy zapsany zaznam a jeho misto se znovu pouzije,
> vcetne ocislovani. Zkuste libovolny ucetni program (Ucto, Kalkul) a
> zjistite, ze kdyz chcete smazat predposledni fakturu, musite napred smazat
> posledni a pak teprve tu predposledni. Nelze mazat kdekoliv ale prave a jen
A ta operace "smazani dokladu" je ucetne co?
> posledni zaznam. No a cele se to musi pak chovat tak, jako kdyby tam ten
> smazany zaznam nikdy nebyl. To je pozadavek na chovani programu a
> programator to musi nejak zaridit, aby se to tak chovalo.
Pokud na to, abyste smazal predposledni doklad, smazete jeste navic
ten posledni, ktery s tim predposladnim nema nic do cineni, tak to pak
muzete ty doklady precislovavat dvakrat denne. Vzdyt ten posledni byl
vydany, vytisteny, zaplaceny ...
> No to jsem zjistil zrovna ted, kdyz to zkousim. Takze jak se v nove verzi
> vlastne zjisti posledni pridelena hodnota typu autoincrement? Kdyz dam
> SELECT LAST_INSERT_ID() tak mi to k memu zdeseni prideli dalsi cislo, misto
> abych se dozvedel, jake to pridelilo naposledy. Takze mi vysvetlete jak
> resit nasledujici pripad, rad se naucim neco noveho.
mysql> create table xx (id integer not null auto_increment primary
key) ;
Query OK, 0 rows affected (0.00 sec)
mysql> select * from xx ;
Empty set (0.03 sec)
mysql> insert into xx values (null) ;
Query OK, 1 row affected (0.00 sec)
mysql> select * from xx ;
+----+
| id |
+----+
| 1 |
+----+
1 row in set (0.01 sec)
mysql> select last_insert_id();
+------------------+
| last_insert_id() |
+------------------+
| 1 |
+------------------+
1 row in set (0.00 sec)
Verze MySQL 3.23.42. Pokud se Vam to chova jinak, je to chyba. Pokud
mate nejnovejsi doporucovane verze MySQL, pouzijte mysqlbug a chybu
nahlaste.
> Mam 2 tabulky, ktere jsou svazany nejakym ID. V jedne tabulce to ID je
> primarni klic, v dalsi muze byt duplicitni (napriklad cislo kancelare je
> unikatni v tabulce kancelari, ale duplicitni v tabulce inventare)
> Takze potrebuji zapsat novou kancelar (pridelit unikatni ID) a toto ID
> potrebuji znat, abych jej pouzil pro seznam inventare v druhe tabulce.
V MySQL na auto_increment sloupec select last_insert_id().
> > a cislo dokladu pak nove vytvorenemu zaznamu v tabulce zaznamu
> > pridelite jedinym nezamykacim updatem.
> Tomu nejak nerozumim. Jak updatem dostanu to cislo do aplikace? Malokdy
Selectem?
> clovek vystaci s tim, ze ma jednu tabulku, kde je nutne unikatni cislo.
> Mnohem casteji je jedna tabulka s unikatnim klicem, ale totez pole je v jine
> tabulce jako neunikatni klic, aby se ty tabulky daly provazat. Priklad:
Ano, rika se tomu cizi klic (foreign klic).
> 1) seznam faktur - unikatni ID je cislo faktury
> 2) seznam pohledavek - ma vlastni cislovani (ID), ale protoze krome faktur
> vystavuji i uctenky, tak u kazde pohledavky musi byt pole "typ_dokladu"
Proc je typ_dokladu u pohledavky a ne u dokladu?
> 3) seznam polozek faktury - zde je cislo faktury duplicitni v kazdem
> pripade, dokonce je duplicitni i objednaci cislo zbozi, dokonce i kdyz
> spojim do klice cislo_faktury+cislo_zbozi muze to byt duplicitni, protoze
> proste nektere zbozi je na fakture zapsano 2x. Jednou 2 kusy, a pak si
> zakaznik vzpomel, ze chce vlastne 3, ale je rychlejsi proste dopsat jeste
> jednou tutez polozku x 1kus, nez opravovat jiz zapsanou na 3 kusy (rychlejsi
> pro obsluhujiciho).
> Neni mi jasne, jak pomoci UPDATE dostanu do aplikace unikatni cislo faktury
> ;-)
insert into faktury values (null, 'nejaka', 'zakladni', 'data');
select last_insert_id();
> zakone, ale rozhodne to je v internich smernicich FU. Neco pisete, udelate
> preklep a ulozite to. Jenze v dalsi sekunde zjistite svou chybu, tak se
OK. Zrusite fakturu a jeji vazbu na cislo faktury (tam provedete update
na null, takze to cislo bude znovu k dispozici), a pri dalsim zalozeni
nove faktury (s novym (vyssim) internim id) to cislo faktury znovu
pridelite.
Dokazu si dokonce predstavit, ze ten zaznam v tabulce faktury se
nebude rusit (delete), ale zustane tam s priznakem smazano, aby bylo
k cemu poznamenat, kdo a kdy to smazal.
--
------------------------------------------------------------------------
Honza Pazdziora | adelton na fi.muni.cz | http://www.fi.muni.cz/~adelton/
.project: Perl, mod_perl, DBI, Oracle, auth. WWW servers, XML/XSL, ...
Only self-confident people can be simple.
Další informace o konferenci Databases