[ Miloš Baić @ 07.11.2007. 13:01 ] @
Pozdrav, da li u novijoj veriziji Firebird-a (2.0 ako se ne varam) postoji analitička funkcija slična ROW_NUMBER kao u DB2 ili MS SQL Serveru? |
[ Miloš Baić @ 07.11.2007. 13:01 ] @
[ darko_sudarov @ 08.11.2007. 07:54 ] @
Kako mislis analiticka funkcija?
Ako mozes malo to da objasnis,mislis li na brojace redova u tabeli ili indekse rekorda? [ Miloš Baić @ 08.11.2007. 08:56 ] @
Mislim na brojače redova u tabeli, da se u jednoj koloni ispisuje broj reda. Radio sam sa Firebird -om 1.5, gde takva funkcija nije postojala, ili nisam naišao na istu. Naime, u tim situacijama sam pravio ručni brojač, uglavnom u uskladištenim procedurama.
[ darko_sudarov @ 08.11.2007. 10:17 ] @
Za to se koriste trigeri koji pokrecu generatore.
Polje proglasis za primary key(PK) ako zelis-(ne moras) i napravis trigger tipa Code: new.id = gen_id(NAZIV_GENERATORA,1); ili pak Code: IF (NEW.ID IS NULL) THEN NEW.ID = GEN_ID(NAZIV_GENERATORA,1); stim da je ova druga varijanta losija od prve ako imas aplikaciju koja salje podatak u id. znaci napravis generator pa trigger na before insert za tu tabelu. To postoji i u 1.5* Pokusaj sa IBExpertom on ima skoro pa automatizovano kreiranje autoinkrementa. [Ovu poruku je menjao darko_sudarov dana 08.11.2007. u 11:27 GMT+1] [ Miloš Baić @ 08.11.2007. 11:26 ] @
@darko_sudarov
Očigledno me nisi razumeo. Ne treba meni autoincrement, nego brojač redova u upitu. Npr., želimo po nekom kriterijumu izlistati spisak radnika iz tabele gde su memorisani radnici: Code: select * from radnici where ime_roditelj is not null; Firebird će izbaciti, npr., 3 reda sa podacima iz tabele. Moje pitanje se odnosilo na to da li postoji neka funkcija u Firebiru koja će automatski, njenim pozivanjem, proširiti ovaj upit tako što će biti dodata još jedna izlazna kolona sa rednim brojevima. U SQL Serveru to izgleda ovako: Code: select ime, ime_roditelj, prezime, row_number() over (order by ime) redni_broj from radnici where ime_roditelj is not null Izlazni podaci: [att_img] Nadam se da je dovoljno ilustrativno. [ schild @ 08.11.2007. 12:32 ] @
Evo jednog resenja:
1. kreiras sledecu proceduru Code: CREATE PROCEDURE SP_ROW_NUMBER ( query_name varchar(20)) returns ( rb integer) as begin /* povecavam vrednost za 1 i prikazujem */ rb = coalesce(rdb$get_context('USER_TRANSACTION', QUERY_NAME), 0); rb = rb + 1; rdb$set_context('USER_TRANSACTION', QUERY_NAME, RB); suspend; end i onda bi tvoj upit izgledao ovako: Code: select ime, ime_roditelj, prezime, (select rb from SP_ROW_NUMBER('upit_o_radnicima')) as redni_broj from radnici where ime_roditelj is not null order by ime Znaci brojac je ok ako ga koristis jednom u transakciji... Svaki upit unutar transakcije treba da ima drugo ime. Nije bas nesto, ali radi! [ savkic @ 08.11.2007. 14:46 ] @
> Mislim na brojače redova u tabeli, da se u jednoj koloni ispisuje broj reda. Radio sam sa Firebird -om 1.5, gde takva funkcija nije postojala, ili
> : nisam naišao na istu. Naime, u tim situacijama sam pravio ručni brojač, uglavnom u uskladištenim procedurama. To je u principu posao za klijenta, dodaš posebno calculated polje, moguće je da i same grid kontrole imaju takvu mogućnost, QuantumGrid mi pada na pamet. [ darko_sudarov @ 08.11.2007. 15:02 ] @
Izgleda da to ne postoji u Firebirdu-barem ja ne znam za to tako da se i ja dovijam sa dve procedure i jednim generatorom za to i svuda ga posle koristim.
Code: CREATE GENERATOR BROJAC; SET GENERATOR BROJAC TO 0; kada ovo napravim onda ide procedura koja koristi taj generator tj uzima redne brojeve Code: SET TERM ^ ; CREATE OR ALTER PROCEDURE REDOSLED1 returns ( rb integer) as begin rb=GEN_ID (BROJAC,1); suspend; end^ SET TERM ; ^ GRANT EXECUTE ON PROCEDURE REDOSLED1 TO SYSDBA; posle toga ide jos jedna procedura koja nulira generator da bi brojevi krenuli od 1 ponovo. Code: SET TERM ^ ; CREATE OR ALTER PROCEDURE REDOSLED as declare variable br integer; begin br=0; br = GEN_ID (BROJAC, br - GEN_ID (BROJAC,0) ); END^ SET TERM ; ^ GRANT EXECUTE ON PROCEDURE REDOSLED TO SYSDBA; i to je to tako da bi kod koji tebi treba bio Code: select ime, ime_roditelj, prezime, (select rb from redosled1 ) as rb from radnici where ime_roditelj is not null order by ime Posle toga bi isla procedura REDOSLED da vrati brojace na nulu. Nije previse srecna varijanta.... [ Mr. Rejn @ 08.11.2007. 18:43 ] @
Ne znam zašto su svi zaobišli ROW_COUNT kontekstualnu promenljivu,valjda je
to ono sto se traži ako sam razumeo pitanje: Code: SET TERM ^ ; CREATE PROCEDURE NEW_PROCEDURE returns ( red_br integer, ime varchar(30)) as begin for select row_count,IME from tab1 into :red_br ,:ime do suspend; end^ SET TERM ; ^ select * from new_procedure daje ![]() [ Miloš Baić @ 08.11.2007. 22:10 ] @
Nešto slično sam i sam pravio, kroz proceduru.
Dakle, ne postoji funkcija slična ROW_NUMBER, jer koliko sam primetio ROW_COUNT u običnom select iskazu ne prolazi!?! [ Mr. Rejn @ 08.11.2007. 23:16 ] @
Citat: Miloš Baić: ROW_COUNT u običnom select iskazu ne prolazi!?! Nažalost ne. [ Miloš Baić @ 09.11.2007. 08:37 ] @
U redu, zadovoljan sam odgovorima, te se svima zahvaljujem.
Ne bi bilo loše da tim koji radi na razvoju Firebirda ima to u vidu i implementira u nekoj novoj verziji servera. Pozdrav. Copyright (C) 2001-2025 by www.elitesecurity.org. All rights reserved.
|