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