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?
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-2008 by www.elitesecurity.org. All rights reserved.