[ Elmer-Davez @ 04.07.2008. 15:03 ] @
Napisao sam funkciju kojoj treba proslediti connectionstring, sql upit koji zelimo da odradimo i ok(neku boolean promenljivu) koja nam govori da li je sve dobro izvrseno. Kao rezultat funkcija treba da vrati rezultat sql upita. Uostalom ovako izgleda funkcija:
Code:
function sqlupit(veza, sql: String; var ok: boolean): TFields;
var
  adoQuery: TADOQuery;
begin
  ok := true;
  adoQuery := TADOQuery.Create(nil);
  adoQuery.ConnectionString := veza;
  adoQuery.Close;
  try
    adoQuery.SQL.Clear;
    adoQuery.SQL.Add(sql);
    adoQuery.Open;
  except
    ok := false;
  end;
  Result := adoQuery.Fields;
  adoQuery.Close;
  adoQuery.Free;
end;


Javljaju mi se dva problema:
1. U redu "Result := adoQuery.Fields" ja samo Result uperim da pokazuje na Field-ove objekta adoQuery i kad dodje kraj funkcije, tacnije red adoQuery.Free, ja vise nemam nikakav podatak u Result-u. Kako da iskopiram sve vrednosti, a ne samo da uperim pokazivac?
2. Ako bi hteo da koristim sql naredbu SELECT koja ce da vrati vise torki od jedne, tada do sledece torke dolazim sa adoQuery.next, a TFields bi mi cuvao samo jedan niz, tj torku. Koji objekat da koristim umesto TFields-a?

Nadam se da cete shvatiti sta sam hteo da napisem i unapred sam zahvalan svim vasim odgovorima :)
[ savkic @ 04.07.2008. 18:28 ] @
> 1. U redu "Result := adoQuery.Fields" ja samo Result uperim da pokazuje na Field-ove objekta adoQuery i kad dodje kraj funkcije,
> tacnije red adoQuery.Free, ja vise nemam nikakav podatak u Result-u.

Tačnije Result više ne postoji jer je dataset objekat kome je pripadao uništen, samim tim i referenciranje (upotreba) TFields će verovatno podići AV (access violation).

> Kako da iskopiram sve vrednosti, a ne samo da uperim pokazivac?

To zavisi od tvojih daljih potreba, možeš koristiti array of string (ili of variant) gde će svakom elementu odgovarati vrednost jednog polja.

> 2. Ako bi hteo da koristim sql naredbu SELECT koja ce da vrati vise torki od jedne, tada do sledece torke dolazim sa adoQuery.next,
> a TFields bi mi cuvao samo jedan niz, tj torku. Koji objekat da koristim umesto TFields-a?

Šta ti je "torka", slog? Ne vidim razloga da ne koristiš DataSet, dakle AdoQuery koji koristiš, zašto bežiš od toga?
[ Elmer-Davez @ 05.07.2008. 02:42 ] @
Citat:
Ne vidim razloga da ne koristiš DataSet, dakle AdoQuery koji koristiš, zašto bežiš od toga?


Imas pravo, hvala ti. Inace sad je problem resen i to ovako...

Code:
function sqlupit(sql: String; var Query: TADOQuery): boolean; overload;
var
  ok: boolean;
begin
  ok := true;
  Query.Close;
  try
    Query.SQL.Clear;
    Query.SQL.Add(sql);
    Query.Open;
  except
    ok := false;
  end;
  Result := ok;
end;


...pa funkciji prosledim ADOQuery i tamo mi je rezultat sql upita, jedino sto moram da imam dve verzije ove funkcije, jer kad koristim INSERT, UPDATE ili DELETE moram da koristim Query.ExecSQL, a za SELECT je ovo ok.

Bitna mi je ova funkcija zato sto cu x puta koristiti neki sql upit u programu, pa da ne pisem stalno tih par redova koda, uostalom cemu sluze funkcije ako ne tome :).

Jos jednom hvala...
[ Miloš Baić @ 05.07.2008. 08:53 ] @
@Elmer-Davez

Treba razmisliti kako realizovati funkciju sa parametrima u SQL upitu.
[ X Files @ 05.07.2008. 09:04 ] @
Ja bih pod obavezno razmilsio o tekstu poruke o gresci kao jednoj od povratnih vrednosti (u slucaju greske).
[ savkic @ 05.07.2008. 11:26 ] @
> Bitna mi je ova funkcija zato sto cu x puta koristiti neki sql upit u programu, pa da ne pisem stalno tih par redova koda, uostalom cemu
> sluze funkcije ako ne tome :).

Tebi su ovde dva reda potupno višak, Query.Close (promena SQL teksta će to implicitno uraditi) i Query.Sql.Clear, taj red zajedno sa Query.Sql.Add treba zameniti sa Query.Sql.Text := 'SELECT ...';

Inače, mislim da ovakvim rešenjem gubiš dosta fleksibilnosti i smanjuješ preglednost koda, kao što je već pomenuto šta je sa parametrima i error handling.
[ Rapaic Rajko @ 07.07.2008. 16:00 ] @
U ovom redu

Code:
function sqlupit(sql: String; var Query: TADOQuery): boolean; overload;


ono var je suvisno. Objekti se uvek prenose kao pointeri; u ovom slucaju (sa var) Query si preneo kao referencu.

Rajko
[ priki @ 17.07.2008. 13:23 ] @
pa po meni vracanje kolekcije TFields nema smisla
bolje da vratiš ceo dataset, imaš mnogo više mogućnosti za rad

ako si imao u planu da praviš univerzalan upit, može
ali to uradi kroz neku klasicu u kojoj ćeš deklarisati jedan property kao TADOQuery i koji će se
preko svojih polja u klasi kreirati OnCreate forme i koji će se oslobadjati na OnDestroy te klase a
izmedju toga možeš da radiš šta hoćeš jer buildanje polja je dinamičko a možeš i parametre da
prosledjuješ, recimo preko TStringList-e koje ćeš kasnije parisrati a tu možeš da staviš i
kontrolu grešaka i eto

a možeš da izvedeš svoju klasu iz TADOQuery-ja pa da napraviš još bolje