🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Thread View: pl.comp.lang.delphi.bazy-danych
5 messages
5 total messages Started by Leszek Thu, 27 Nov 2014 12:39
FIREBIRD - sortowanie pola VARCHAR wg liczb w nim zawartych
#82421
Author: Leszek
Date: Thu, 27 Nov 2014 12:39
40 lines
2298 bytes
Witam,
w bazie firebird jest tabela PRG zawierająca pole NR (VARCHAR), w którym przechowuję łańcuchy zawierające m. in. liczby, np. P-124, P-125a, PL-985, G-214, J-235, G-41cd, PL-7, G-1234 itp. Chciałem posortować tabelę wg LICZB występujących w polu NR. Napisałem procedurę DAJLICZBE:

CREATE PROCEDURE DAJLICZBE(
  WEJSCIE VARCHAR(30) CHARACTER SET WIN1250 DEFAULT NULL)
RETURNS(
  LICZBA INTEGER)
AS
DECLARE VARIABLE I SMALLINT;
DECLARE VARIABLE DLUGOSC SMALLINT;
DECLARE VARIABLE ZNAK VARCHAR(1);
DECLARE VARIABLE LICZBASTR VARCHAR(30);
BEGIN

  DLUGOSC = CHAR_LENGTH(WEJSCIE);

  I = 1;
  LICZBASTR = '';
  WHILE (I <= DLUGOSC) DO
  BEGIN
    ZNAK = SUBSTRING(WEJSCIE FROM I FOR 1);
    IF (ZNAK BETWEEN '0' AND '9') THEN LICZBASTR = LICZBASTR || ZNAK;
    I = I + 1;
  END

  IF (LICZBASTR = '') THEN LICZBASTR = '0';
  LICZBA = LICZBASTR;

  SUSPEND;

END;

i tą procedurę wywołuję następująco:

  select * from PRG
  order by (select * from DAJLICZBE(NR))

Działa dokładnie tak, jak chciałem...
Moje pytanie: CZY DA SIĘ TO ZROBIĆ BARDZIEJ POPRAWNIE, a MOŻE PROŚCIEJ LUB PO PROSTU BARDZIEJ ELEGANCKO... (bez UDF)
Dzięki.
Re: FIREBIRD - sortowanie pola VARCHAR wg liczb w nim zawartych
#82422
Author: wloochacz
Date: Thu, 27 Nov 2014 13:54
16 lines
1578 bytes
W dniu 2014-11-27 13:39, Leszek pisze:
/ciach/

> Działa dokładnie tak, jak chciałem...
> Moje pytanie: CZY DA SIĘ TO ZROBIĆ BARDZIEJ POPRAWNIE, a MOŻE PROŚCIEJ LUB PO PROSTU BARDZIEJ ELEGANCKO... (bez UDF)
> Dzięki.
Dodać nowe pole typu int i zaktualizować je w triggerze, np. za pomocą 
tej procedury i po nim sortować.
A jak założysz indeks na tym polu, to jeszcze lepiej.

To co zrobiłeś, działa - ale ciekawe jak długo będzie szybko ;-)
Chociaż narzut nie jest aż tak duży - musisz potestować...


-- 
wloochacz
Re: FIREBIRD - sortowanie pola VARCHAR wg liczb w nim zawartych
#82423
Author: Leszek
Date: Fri, 28 Nov 2014 07:32
26 lines
2513 bytes
> Dodać nowe pole typu int i zaktualizować je w triggerze, np. za pomocą 
> tej procedury i po nim sortować.
> A jak założysz indeks na tym polu, to jeszcze lepiej.
> 
> To co zrobiłeś, działa - ale ciekawe jak długo będzie szybko ;-)
> Chociaż narzut nie jest aż tak duży - musisz potestować...
> 
> 
> -- 
> wloochacz

Zrobiłem tak, jak napisałeś:
1. Dodałem nowe pole LP(INTEGER).
2. Założyłem indeks na tym polu.
3. Zdefiniowałem trigger dla tabeli PRG:
  CREATE TRIGGER PRG_BI FOR PRG
  ACTIVE BEFORE INSERT OR UPDATE
  POSITION 1
  AS
  BEGIN
    execute procedure DAJLICZBE NEW.NR returning_values NEW.LP;
  END;
4. Zrobiłem zapytanie: select * from PRG order by LP.
Wykonało się około 20 razy (!) szybciej niż zapytanie, które wcześniej wymyśliłem...
DZIĘKUJĘ CI BARDZO ZA TRAFNĄ ODPOWIEDŹ.
Trigger, który korzysta z procedury napisałem po raz pierwszy w życiu, więc jeśli można było go napisać mądrzej, to bardzo proszę jeszcze o sugestie...
Re: FIREBIRD - sortowanie pola VARCHAR wg liczb w nim zawartych
#82424
Author: wloochacz
Date: Fri, 28 Nov 2014 21:45
36 lines
2455 bytes
W dniu 2014-11-28 08:32, Leszek pisze:
/ciach/
> Zrobiłem tak, jak napisałeś:
> 1. Dodałem nowe pole LP(INTEGER).
> 2. Założyłem indeks na tym polu.
> 3. Zdefiniowałem trigger dla tabeli PRG:
>    CREATE TRIGGER PRG_BI FOR PRG
>    ACTIVE BEFORE INSERT OR UPDATE
>    POSITION 1
>    AS
>    BEGIN
>      execute procedure DAJLICZBE NEW.NR returning_values NEW.LP;
>    END;
> 4. Zrobiłem zapytanie: select * from PRG order by LP.
> Wykonało się około 20 razy (!) szybciej niż zapytanie, które wcześniej wymyśliłem...
> DZIĘKUJĘ CI BARDZO ZA TRAFNĄ ODPOWIEDŹ.
Eee... proszę bardzo, ale to raczej oczywiste ;-)

> Trigger, który korzysta z procedury napisałem po raz pierwszy w życiu, więc jeśli można było go napisać mądrzej, to bardzo proszę jeszcze o sugestie...

Aktualizujesz zawsze wiersz, a powinieneś tylko wtedy kiedy dodajesz 
nową wartość lub zmieniasz istniejącą; a więc:
   CREATE TRIGGER PRG_BI FOR PRG
   ACTIVE BEFORE INSERT OR UPDATE
   POSITION 1
   AS
   BEGIN
     if (NEW.NR is not null and OLD.NR is null) or (NEW.NR <> OLD.NR) then
   execute procedure DAJLICZBE NEW.NR returning_values NEW.LP;
   END;

Coś w ten deseń; ja ostatni trigger dla FB pisałem jakieś 10 lat temu, 
więc mogę coś poknocić...

-- 
wloochacz
Re: FIREBIRD - sortowanie pola VARCHAR wg liczb w nim zawartych
#82425
Author: jh
Date: Mon, 01 Dec 2014 00:33
19 lines
1698 bytes
> Aktualizujesz zawsze wiersz, a powinieneś tylko wtedy kiedy dodajesz
> nową wartość lub zmieniasz istniejącą; a więc:
>    CREATE TRIGGER PRG_BI FOR PRG
>    ACTIVE BEFORE INSERT OR UPDATE
>    POSITION 1
>    AS
>    BEGIN
>      if (NEW.NR is not null and OLD.NR is null) or (NEW.NR <> OLD.NR) then
>    execute procedure DAJLICZBE NEW.NR returning_values NEW.LP;
>    END;
>
> Coś w ten deseń; ja ostatni trigger dla FB pisałem jakieś 10 lat temu,
> więc mogę coś poknocić...

Trzeba sprawdzić inserting/updating, bo old.xxx występuje tylko w 
update/delete.

jh
Thread Navigation

This is a paginated view of messages in the thread with full content displayed inline.

Messages are displayed in chronological order, with the original post highlighted in green.

Use pagination controls to navigate through all messages in large threads.

Back to All Threads