[ mr.zhile @ 06.08.2008. 10:48 ] @
Znam da ima sllicnih tema,ali...
Imam bazu podataka radjenu u firebird_u.Kako da pozovem stored procedure u delphiju da bi mi se generator uvecao?Imam i triger koji se aktivira before insert ali se generator ne uvecava?
Kod procedure je
Code:
 
SET TERM ^ ;
CREATE PROCEDURE KUPCI_ID
RETURNS (
    VAL Integer )
AS
BEGIN
  val=gen_id( GEN_KUPCI_ID,1 );
END^
SET TERM ; ^

a trigera
Code:

SET TERM ^ ;
CREATE TRIGGER KUPCI_BI0 FOR KUPCI ACTIVE
BEFORE INSERT POSITION 0
AS 
BEGIN 
    if ( new.ID is null ) then
    new.ID=gen_id(GEN_KUPCI_ID,1);
END^
SET TERM ; ^

Ovim kodom se vrsi unos u tabelu kupci
Code:

var
  sql:string;
begin
  sql := 'insert into banka values ( ' + QuotedStr(EditId.Text) + ' , ' + QuotedStr(EditPrefiks.Text) + ' , ' + QuotedStr(EditNAziv.Text) + ' ) ';
  DMMain.SQLQuery1.SQL.Clear;
  DMMain.SQLQuery1.SQL.Text := sql;
  DMMain.SQLQuery1.ExecSQL;
end;

Kako bi mogao da iskombinujem da napravim autoincrement polje nad tabelom?
HVALA!!!
[ savkic @ 06.08.2008. 12:25 ] @
> Imam bazu podataka radjenu u firebird_u.Kako da pozovem stored procedure u delphiju da bi mi se generator uvecao?

SELECT * FROM KUPCI_ID;

Generator možeš i direktno pozvati: SELECT GEN_ID(GEN_KUPCI_ID, 1) from RDB$DATABASE;

> Imam i triger koji se aktivira before insert ali se generator ne uvecava?

Verovatno ti ID polje nije null, dodelio si mu vrednost u tvom programu.
[ chachka @ 06.08.2008. 13:08 ] @
Delphi kod koji je postovan vrši unos u tabelu 'banka' a triger je dat za tabelu 'kupci'! Pošalji kod kojim vršiš unos u spomenutu tabelu 'kupci'.

Inače loše je raditi unos tako kako ti radiš komandom:
Code:
INSERT INTO banka
VALUES (......)

uvek navedi sve kolone u koje vršiš insert, nešto poput:
Code:
INSERT INTO banka
       (ime_prve_kolone, ime_druge_kolone, ime_trece_kolone)
VALUES (......)


Sledeće - jednom za imenovanje tabele koristiš jedninu (banka), dok drugi put koristiš množinu (kupci). Ima zagovornika i jedne i druge notacije, ali ti savetujem da se prihvatiš jedne i da je se držiš koliko je god to moguće, znači 'banka' i 'kupac', ili u drugoj notaciji 'banke' i 'kupci'.
[ mr.zhile @ 06.08.2008. 15:19 ] @
Verovatno ti ID polje nije null, dodelio si mu vrednost u tvom programu.

Nije nul unosio sam podatke u tabelu..
Kako da ga postavim na null?
@chachka
Hvala na savetima uvazicu ih
Evo koda za unos u tabelu kupci
Code:

var
  sql:String;
begin
  sql := ' insert into kupci values ( ' + QuotedStr(EditID.Text) + ' , ' + QuotedStr(EditSifra.Text) + ' , ' + QuotedStr(EditNaziv.Text) + ' , ' + QuotedStr(MemoOpis.Lines.Text) + ' ) ';
  DMMain.SQLQuery1.SQL.Clear;
  DMMain.SQLQuery1.SQL.Text := sql;
  DMMain.SQLQuery1.ExecSQL;

Gde bi sad trebalo umetnuti ovaj kod
Code:

SELECT GEN_ID(GEN_KUPCI_ID, 1) from RDB$DATABASE

Jel mora rdb$database ili se tu pise samo ime baze?
Ako bi neko bio ljubazan da mi napise kompletnu proceduru kojom bi se vrsio i unos i autoincrement povecavao za 1 bio bi mu punooo zahvalan,jer nigde nisam nasao nista slicno,a ne znam gde gresim?
[ savkic @ 06.08.2008. 16:28 ] @
> Nije nul unosio sam podatke u tabelu..
> Kako da ga postavim na null?

Navedeš NULL kao vrednost polja ili izostaviš to polje iz INSERTa:

Code:

INSERT INTO
  TABELA (ID, POLJE)
VALUES(GEN_ID(GEN_KUPCI_ID, 1), NULL);

ili 

INSERT INTO
  TABELA (ID)
VALUES(GEN_ID(GEN_KUPCI_ID, 1));



> Jel mora rdb$database ili se tu pise samo ime baze?

Mora, RDB$DATABASE je specijalna FB tabela koja ima garantovano 1 slog. Vise detalja kako se koristi i uopšte o insertu i drugim operacijama možeš pronaći na www.ibphoenix.com ili još bolje u Firebird Book od Helen Borrie.
[ mr.zhile @ 07.08.2008. 09:42 ] @
Hvala vam na komentarima,ali meni i dalje stoji jedna velika dilema.Kako mogu u jednoj proceduri da upisem podatke i da ih pozovem sa select upitom?
Code:
   sql := ' insert into kupci(id,sifra,naziv,opis) values ( null' + QuotedStr(EditID.Text) + ' , ' + QuotedStr(EditSifra.Text) + ' , ' + QuotedStr(EditNaziv.Text) + ' , ' + QuotedStr(MemoOpis.Lines.Text) + ' ) ';
  DMMain.SQLQuery1.SQL.Clear;
  DMMain.SQLQuery1.SQL.Text := sql;
  DMMain.SQLQuery1.ExecSQL;
  sql:='select * from kupci_id';
  DMMain.SQLQuery1.SQL.Clear;
  DMMain.SQLQuery1.SQL.Text := sql;
  DMMain.SQLQuery1.Open;

ovas procedura npr ne funkcionise?
Ne kapiram gde gresim,ali znam da su autoinc polja veoma bitna
[ chachka @ 07.08.2008. 10:29 ] @
Da li si procitao poruku o gresci koju ti je vratio server? Da li se u njoj spominje sintaksna greska?
[ mr.zhile @ 07.08.2008. 15:06 ] @
Greska je da ne moze null da bude ulaz jer je id primary key i not null!!
Kako da pozovem uz pomoc komponente SqlStoreProc proceduru za pravljenje autoincrementa?
Da li uopste onaj kod koji sam postavio u 1. poruci moze da pravi autoincrement?
Kada bi mi mogli dati konkretan kod kojim bi se pokrenula kompoenta?bio bi punooo zahvalan..
Nasao sam neke kodove ali mi nije jasno jer ja ovde nemam ulaz imam samo izlaz.ALi da li sam dobro napisao proceduru?
Code:

 
SET TERM ^ ;
CREATE PROCEDURE KUPCI_ID
RETURNS (
    VAL Integer )
AS
BEGIN
  val=gen_id( GEN_KUPCI_ID,1 );
END^
SET TERM ; ^

[ savkic @ 07.08.2008. 15:36 ] @
> Greska je da ne moze null da bude ulaz jer je id primary key i not null!!

Gde je to greška u komponenti koju koristiš ili u bazi? Ako hoćeš da trigger dodeli ID onda izostavi čitavo polje iz inserta.

> Da li uopste onaj kod koji sam postavio u 1. poruci moze da pravi autoincrement?

Može.

> Kada bi mi mogli dati konkretan kod kojim bi se pokrenula kompoenta?bio bi punooo zahvalan..

Odgovor si dobio u prvom odgovoru.

Mislim da bi za početak bilo dobro da nam kažeš šta je to što ti zapravo želiš uraditi (ne prost insert već ono što je iznad toga).
[ mr.zhile @ 07.08.2008. 16:16 ] @
Hocu da napravim autoincrement polje za tabelu kupci koje ce da se formira pozivanjem stored procedure uz pomoc dbExpress komponentu SqlStoreProc !
Ali posto moj "mentor"nezeli da mi kaze kako ali je rekao da moram pomocu stored proc to da uradim ne znam kako da pokrenem dbExpress komponentu SqlStoreProc za moj slucaj...
Pa prost insert funkcionise ali NEMOGU da napravim autoincrement...
Ljudi od toga mi buducnost zavisi od autoincrement...:)
[ chachka @ 07.08.2008. 16:48 ] @
Citat:
mr.zhile: Greska je da ne moze null da bude ulaz jer je id primary key i not null!!

To nije prava greška koju ti je prosledio server. Greška ti je sintaksne prirode jer ti se u naredbi posle null ne pojavljuje zarez već apostrof ' . Naredba koja stiže do servera započinje:
Code:
insert into kupci(id,sifra,naziv,opis) values ( null'
jer tvoj kod obavezno dodaje apostrof iza null, a ta naredba bi trebala da počinje:
Code:
insert into kupci(id,sifra,naziv,opis) values ( null,


Drugo: Na toj tabeli imaš postavljen BEFORE INSERT triger koji postavlja vrednost kolone 'id' na neku NOT NULL vrednost, tako da ti do te kolone u momentu inserta nikada nemože doći NULL.

Mislim da u pravilima ovog foruma stoji da treba da se postavi što više podataka o nastaloj grešci, a to podrazumeva da se napiše i kompletna poruka o grešci koja je dobijena!

Prosto izostavi tu famoznu 'id' kolonu iz onog inserta i dobićeš taj dragoceni autoincrement.
[ mr.zhile @ 07.08.2008. 17:01 ] @
Evo ovaj kod pravi autoincrement za imenovane konekcije
Code:

  sql := ' insert into kupci(id,sifra,naziv,opis) values ( '+QuotedStr(EditID.Text)+', ' + QuotedStr(EditSifra.Text) + ' , ' + QuotedStr(EditNaziv.Text) + ' , ' + QuotedStr(MemoOpis.Lines.Text) + ' ) ';
  DMMain.SQLQuery1.SQL.Clear;
  DMMain.SQLQuery1.SQL.Text := sql;
  DMMain.SQLQuery1.ExecSQL;
  DMMain.SQLStorProc.StoredProcName:='kupci_id';
  DMMain.SQLStorProc.ExecProc;

A sta bi trebalo da se promeni u njemu da bi mogao da se izvrsi i za neimenovane konekcije jer favorizuje se ini konekcija?
[ mr.zhile @ 07.08.2008. 17:16 ] @
Opet mi pokazuje gresku ' Incorrect values within SQLDA structure'? i posle f8 dva puta unese kupca!
Ne razumem sta se to desava?
Posto aplikacija omogucava i brisanje kada izvrsim brisanje generator ostaje na prethodnoj vrednosti kako ovaj problem da resim?
Treba mi neka procedura za smanjenje generatora?
[ savkic @ 07.08.2008. 18:48 ] @
> Hocu da napravim autoincrement polje za tabelu kupci koje ce da se formira pozivanjem stored procedure uz
> pomoc dbExpress komponentu SqlStoreProc !
> Ali posto moj "mentor"nezeli da mi kaze kako ali je rekao da moram pomocu stored proc to da uradim ne
> znam kako da pokrenem dbExpress komponentu SqlStoreProc za moj slucaj...

Ako mora iz DBExpress komponente da se sazna ID onda ti trebaju dva kverija, prvi da dobiješ naredni ID, i drugi da insertuješ novi slog sa datim IDom.
Nisam koristio DBExpress pa ćeš za ta dva kverija morati sam da se snađeš (jedan već imaš, samo ti treba i selektovanje vrednosti iz procedure).

Ako DBExpress nije obavezan a tražiš nešto slično autoincrement polju onda ti je rešenje sa triggerom najbolje, u insert kveriju izostaviš ID polje i onda se trigger pobrine da dobije vrednost.

Code:


U odnosu na tvoju proceduru dodato je SUSPEND jer je to neophodno ako procedura vraca neke vrednosti.

CREATE PROCEDURE ID_GENERATE
RETURNS (
    RES INTEGER)
AS
BEGIN
  RES = GEN_ID(PERA, 1);

  SUSPEND;
END

U triggeru:

  if (NEW.ID is NULL) then
    EXECUTE PROCEDURE ID_GENERATE RETURNING_VALUES NEW.ID;


Ako upotreba stored procedure nije obavezna onda sve to možeš zameniti sa direktnim pozivom GEN_ID kako je pokazano u prethodnim porukama.

> Evo ovaj kod pravi autoincrement za imenovane konekcije
> sql := ' insert into kupci(id,sifra,naziv,opis) values ( '+QuotedStr(EditID.Text)+', ' + QuotedStr(EditSifra.Text) ....

Ne znam zašto si uporan sa ovakvim načinom rada, dobio si primer kako treba da se radi. Moraš odlučiti da li korisnik unosi ID (preko EditID kontrole) ili se to radi automatski kako i treba da bude.

> A sta bi trebalo da se promeni u njemu da bi mogao da se izvrsi i za neimenovane konekcije jer favorizuje se ini.

Nejasno pitanje, razjasni.

> Opet mi pokazuje gresku ' Incorrect values within SQLDA structure'? i posle f8 dva puta unese kupca!
> Ne razumem sta se to desava?

Tu si naveo dva kverija, jedan za insert drugi za izvršavanje procedure, ovako ne može da ti se pomogne moraš shvatiti da ovako nepreciznim pisanjem nigde ne dospevamo, mi ne možemo da ti pomognemo a ti ne možeš da rešiš problem. Zamolio bih te da pročitaš linkove koje se mogu naći u mom potpisu (kako postavljati pitanja).

> Posto aplikacija omogucava i brisanje kada izvrsim brisanje generator ostaje na prethodnoj vrednosti kako ovaj problem da resim?
> Treba mi neka procedura za smanjenje generatora?

Pozoveš generator sa -1, Npr: GEN_ID(NAZIV, -1);
Inače nikako ti ne bih preporučio da to radiš, ID brojevi ne smeju da imaju nikakvo značenje za korisnika (ako ti treba broj za korisnika uvedi novo polje) pa samim tim vođenje računa o neprekinutom nizu nema smisla. Dakle, sasvim je normalno da IDevi u tabeli budu 1, 2, 5, 100.

[ mr.zhile @ 08.08.2008. 08:03 ] @
Korisnik mora da unosi id.Pa zar nje polje koje je autoincrement generator,njega korisnik nema potrebe da vidi i zna a on obavlja svoj posao.
Problem je sto se dva puta izvrsavam kveri.
Mozda bi bolje resenje bila store proc za unos u kojoj bi se pozivvano i generator?
Koje je bolje resenje od gen_id(naziv,-1)za brisanje?
[ savkic @ 08.08.2008. 09:56 ] @
> Korisnik mora da unosi id.

Onda to nije autoincrement field, vec user defined.

> Mozda bi bolje resenje bila store proc za unos u kojoj bi se pozivvano i generator?

Možeš i tako vežbe radi, ali to nije previše fleksibilno rešenje.

> Koje je bolje resenje od gen_id(naziv,-1)za brisanje?

DELETE FROM... generator ne treba dirati.
[ mr.zhile @ 08.08.2008. 16:14 ] @
Code:

sql:='insert into racuni values ( '+ QuotedStr(EditId.Text)+','+QuotedStr(cbKupac.Text)+','+QuotedStr(cbBanka.Text)+','+QuotedStr(cbPrefiks.Text)+','+QuotedStr(EditBrRacuna.Text)+','+QuotedStr(EditKonBr.Text)+','+QuotedStr(EditPunBrRacuna.TExt)+')';
  DMMain.SQLQuery1.SQL.Clear;
  DMMain.SQLQuery1.SQL.Text := sql;
  DMMain.SQLQuery1.ExecSQL;

Ovako napisano radi,ali kada se pozove
Code:

  DMMain.SQLStorProc.StoredProcName:='Nracun_id';
  DMMain.SQLStorProc.ExecProc;

Onda tu pukne gresku
'incorect values within sqlda structure'
i pokaze na liniju
DMMain.SQLQuery1.ExecSQL;
NERAZUMEM GDEE GRESIM?
[ mr.zhile @ 09.08.2008. 18:41 ] @
Opet sam dao sebi za pravo da postavim pitanja.
Code:

  sql := 'insert into banka values ( ' + QuotedStr(EditId.Text) + ' , ' + QuotedStr(EditPrefiks.Text) + ' , ' + QuotedStr(EditNAziv.Text) + ' ) ';
  DMMain.sdsBanke.Close;
  DMMain.sdsBanke.Append;
  DMMain.sdsBanke.DataSet.Close;
  DMMain.sdsBanke.dataset.CommandType:=ctStoredProc;
  DMMain.sdsBanke.DataSet.CommandText:='nbanka_id';
  DMMain.sdsBanke.DataSet.Open;
  DMMain.sdsBanke.DataSet.Close;
  DMMain.sdsBanke.DataSet.CommandType:=ctQuery;
  DMMain.sdsBanke.DataSet.CommandText:=sql;
  DMMain.sdsBanke.DataSet.Open;
  DMMain.sdsBanke.Post;
  DMMain.sdsBanke.Open;

Posle konsultacija sa mentorom dosao sam na ideju da bi ovako mogao da pozovem i proceduru i query,ali nece da radi.
Pa gde sam pogresio?
Pukne gresku da je sdsBanke zatvoren i ne moze da odradi?
[ schild @ 11.08.2008. 06:43 ] @
Ajde @Zile objasni sta se radi sa ovim delom koda:
Code:
  DMMain.sdsBanke.Close;
  DMMain.sdsBanke.Append;
  DMMain.sdsBanke.DataSet.Close;

??? Logicno da je tu greska!

Potom se odluci da li ces ID polje setovati u triggeru ili kroz program... Ako ces koristiti trigger, onda nemoj petljati sa procedurama, ne vidim poentu.
Objasni prostom recenicom koju si opciju izabrao, pa da vec resimo ovo jednom :(
[ mr.zhile @ 11.08.2008. 12:39 ] @
Korisnik unosi id
Aj majke ti puce mi glava
[ mr.zhile @ 11.08.2008. 12:42 ] @
Znam da ne treba Append treba Insert,ali me onda buni sto pokaze gresku da ne moze insert da se radi sa zatvoreniom datasetom
Neka mi neko malo podobnije objasni ove situacije i cake?
Ploease
[ mr.zhile @ 11.08.2008. 13:00 ] @
hocu da u jednoj proceduri pozovem i query i storeproc jer se tako trazi od strane gurua?
[ schild @ 11.08.2008. 14:10 ] @
Citat:
mr.zhile: Znam da ne treba Append treba Insert,ali me onda buni sto pokaze gresku da ne moze insert da se radi sa zatvoreniom datasetom
Neka mi neko malo podobnije objasni ove situacije i cake?

Code:
  DMMain.sdsBanke.Close;
  DMMain.sdsBanke.Append;
  DMMain.sdsBanke.DataSet.Close;

Ja te ovo upito da sam skontas sta si uradio. U prvom redu si zatvorio dataset (close), i onda u drugom hoces da dodas novi slog (append). Zatim ponovo zatvaras dataset,... Fali ti izmedju jedno DMMain.sdsBanke.Open, ali i tako ti ne bi radilo, ali sada nemam vremena da objasnim, malo je komplikovanije.

Ukratko: Nemoj koristiti SimpleDataSet da bi izvrsavao sql komande.
Bolje koristi TSQLQuery, i onda ide:
Code:
  q: TSQLQuery.ExecSQL;
  ...
  q..SQL.Add('insert ... into...');
  q.ExecSQL;
i sa tim si odradio insert.
Ako hoces posle da zoves proceduru, onda ide:
Code:
  
  q.sql.Clear;
  q.SQL.Add('execute procedure...');
  q.ExecSQL;

[ mr.zhile @ 11.08.2008. 16:01 ] @
Jeste to sve ok
Ali treba dataset da se prebaci u rezim insret pa da se onda izvrsava kod?
[ schild @ 12.08.2008. 06:32 ] @
Kada koristis dataset onda insert ide ovako:
Code:

DMMain.sdsBanke.Open;     
DMMain.sdsBanke.Append;  
DMMain.sdsBanke.FieldByName('Polje1').AsInteger:=111;
DMMain.sdsBanke.FieldByName('Polje2').AsString:='Tito';
DMMain.sdsBanke.FieldByName('Polje3').AsDateTime:=now;
...
DMMain.sdsBanke.Post;

Ukoliko pricamo o TSimpleDataSet-u onda treba i:
Code:
DMMain.sdsBanke.ApplyUpdates;

jer su ti tek onda vrednosti upisane u bazu, a do tada su u lokalnom keshu.

To je ukratko, ali najbolje prouci help, ima sve objasnjeno. Mozda neka dobra knjiga za Delphi?? Pogledaj od Marco Cantu-a, ima serial "Majstor za Delphi", vrlo korisne knjige.
[ mr.zhile @ 12.08.2008. 11:36 ] @
@schild
Hvala puno uspeoo mi je append
kada bi mogao malo da mi pomognes oko insert-a
jer kada stavim sdsBanka.open jevi mi gresku jer (koliko ja znam) za insert treba commandtype da bude ctQuery...a greska je u slobodnom prevodu da skup podataka ne vraca skup podataka...
znam da kaad se u sql unese insert,update,delete treba da se radi execsql,a simpledataset to ne podrzava...
AKo moze jos malena pomoc oko toga i aplikacija je gotova?