[ Dragan_v @ 08.08.2007. 09:14 ] @
Nisam bio siguran ovde ili u forumu firebird...ali mi se nekako cinilo da je pitanje vise za ovde...
Pitanje je sledece:

Firebird baza,
Delphi,


Potrebno je da izvrsim upisivanje u dve tabele istovremeno i to tako da prva ima polje ID koje je autoINC, ali da se u drugu istovremeno uz novi slog u jedno polje upise i vrednost tog ID polja iz prve.
AutoINC polje se regulise tako sto postoji procedura i trigger, pa storedproc kao paramatar za to polje dobije NULL, trigger okine i dodeli vrednost koja ide umesto null.
E...kako sad da saznam 'u letu' sta je dodelio pa da to upisem u drugu tabelu, ali sve treba da se desi unutar jedne try/except procedure kako bi bio siguran da je upis bio uspesan u OBE tabele...


Pada mi na pamet jedno select MAX(ID) from prva_tabela izmedju...al mi nesto ne izgleda mnogo pametno....

nisam neki strucnjak...pomagajte...
[ schild @ 08.08.2007. 09:43 ] @
Ako koristis FB 2.0, a trebao bi, imas opciju RETURNING za INSERT komandu.
Primer:
Code:

Insert into TAB1 (keyfld, oslala_polja, ...)
values
:f1, :f2, ...
RETURNING keyfld into :novi_keyfld; -- ako je novi


to znaci sledece: ako ti je parametar f1=null (a jeste ako je novi slog), u triggeru after insert ce se dodeliti nova vrednost tom polju, i onda tu novu vrednost mozes ocitati u parametru :novi_keyfld, pa ga dodeliti nekoj drugoj tabeli.
[ Dragan_v @ 08.08.2007. 10:22 ] @
kao 'ladna voda !

HVALA :)
[ Miloš Baić @ 08.08.2007. 10:50 ] @
U Firebird -u postoji mogućnost kreiranja generatora, te da mu postaviš vrednost od koje će početi.
Code:
CREATE GENERATOR G_Neki_Naziv;
SET GENERATOR G_Neki_Naziv TO Neka_Vrednost;

Potom se može napraviti jedna procedura kojom ćeš ga pozivati:
Code:

SET TERM ^ ;

CREATE PROCEDURE GETGEN_Neki_Naziv
RETURNS(
  NOVI_BROJ INTEGER)
AS
BEGIN
    NOVI_BROJ = GEN_ID(G_Neki_Naziv, 1);
END^

SET TERM ; ^

U delphiju samo pozoveš tu proceduru,
Code:
EXECUTE PROCEDURE GETGEN_Neki_Naziv

NOVI_BROJ dodeliš npr. nekoj promenljivoj, istog tipa, potom memorišeš u tabele vrednosti promenljive. Naravno, ukoliko si uspostavio referencijalni integritet, prvo u matičnu tabelu, da je tako nazovem, potom u tabelu koja se vezuje za nju.

Vrednost generatora, ukoliko želiš da je vidiš, možeš prikazati u TEdit kontroli, npr., te promenljiva ti nije potrebna, i iz TEdit kontrole memorišeš direktno u tabele.
Code:
//spGen - komponenta preko koje pozivaš proceduru
Edit1.Text := spGen.ParamByName('NOVI_IDENT').AsString;

Na taj način znaš koji je broj dodeljen.

Možeš da koristiš i SELECT MAX(), te ako je vrednost 0 dodeliš 1, a ako je broj dodeliš broj + 1.
[ Dragan_v @ 08.08.2007. 11:04 ] @
reseno....mislim da ovo izgleda prilicno elegantno :)

storedproc koja mi sluzi za upis novih slogova izgleda ovako:
Code:

BEGIN
  INSERT INTO ARTIKLI (
    ID,
    ID_N0,
    ID_N1,
    ID_N2,
    SIFRA,
    SIFRA_LOK,
    NAZIV,
    JED_MERE,
    KOM,
    OPIS,
    NAPOMENA,
    SLIKA)
  VALUES (
    :ID,
    :ID_N0,
    :ID_N1,
    :ID_N2,
    :SIFRA,
    :SIFRA_LOK,
    :NAZIV,
    :JED_MERE,
    :KOM,
    :OPIS,
    :NAPOMENA,
    :SLIKA)
   RETURNING ID into :novi_id;
END


onda jedan try/except koji pokrene stored proc. za upis u ovu tabelu....pokupi vrenost za novi_id i prosledi ga kao parametar proceduri za drugu tabelu...ovako:
Code:

VAR
noviid:integer;
.............

               dm.stor1.ParamByName('ID').Value := null;
               dm.stor1.ParamByName('ID_N0').AsInteger := strtoint(
                  label39.Caption);
               dm.stor1.ParamByName('ID_N1').AsInteger := strtoint(
                  label40.Caption);
               dm.stor1.ParamByName('ID_N2').AsInteger := strtoint(
                  label41.Caption);
               dm.stor1.ParamByName('SIFRA').AsString := edit18.Text;
               dm.stor1.ParamByName('SIFRA_LOK').AsString := LUCombo2.Text;
               dm.stor1.ParamByName('NAZIV').AsString := edit17.Text;
               dm.stor1.ParamByName('JED_MERE').AsString := LUCombo1.Text;
               dm.stor1.ParamByName('kom').Value := MoneyEdit1.Value;
               dm.stor1.ParamByName('OPIS').AsString := edit19.Text;
               dm.stor1.ParamByName('NAPOMENA').AsString := edit20.Text;
               dm.stor1.Prepare;
               dm.stor1.ExecProc;
               noviid := dm.stor1.ParamByName('NOVI_ID').Value;
               showmessage(inttostr(noviid));
               dm.stor2.close;
               dm.stor2.params.ClearValues;
               dm.stor2.StoredProcName := '';
               dm.stor2.StoredProcName := 'CENE_I';
               dm.stor2.ParamByName('ID').Value := null;
               dm.stor2.ParamByName('ID_ART').Value := noviid;
               dm.stor2.ParamByName('ID_VRSTE').asinteger := strtoint(
                  label55.Caption);
               dm.stor2.ParamByName('CENA').Value := MoneyEdit2.Value;
               dm.stor2.Prepare;
               dm.stor2.ExecProc;
               dm.tr.Commit;



bice od mene nesto...za jedno 20 godina:)
[ Miloš Baić @ 08.08.2007. 11:25 ] @
Mislim da punjenje tabela kroz proceduru i nije baš elegantno rešenje.
[ Dragan_v @ 08.08.2007. 11:34 ] @
Citat:
Mislim da punjenje tabela kroz proceduru i nije baš elegantno rešenje.


nisam siguran da sam ovo shvaio najbolje...
pod 'punjenjem' sam mislio na upis pojedinacnog sloga...ne na presipanje tabele u tabelu...

sta je bolje od storedproc, upisa parametara i izvrsavanja te procedure za upis JEDNOG sloga u tabelu ?

[ Miloš Baić @ 08.08.2007. 11:41 ] @
Da, i ja sam pod punjenjem mislio na upis jednog ili više slogova u tabelu/e, ne presipanje iz tabele u tabelu.
Da li je bolje ili nije, to je stvar iskustva, ali za unos/izmene podataka ne moraš koristiti procedure, možeš "normalnim" SQL upitom to odraditi.
[ Dragan_v @ 08.08.2007. 11:48 ] @
ponekad i napravim 'Insert Into.....' kroz obican query, ali cini mi se i jasnije i lakse ovako....mozda je samo stvar ukusa...proc mi bar umanji muke oko navodnika na stringovima i spajanja vise stringova u jedan upit....

svejedno, bitno je da podaci zavrse tamo gde sam ih poslao :)

hvala na pomoci....odoh da teram dalje ovo ...