[ mr.zhile @ 18.11.2008. 13:49 ] @
Koristim firebird bazu i zbog raznih manipulacija sa poljima potrebno mi je da se ona dinamicki kreiraju u RunTime modu!KAKO?
[ Rapaic Rajko @ 18.11.2008. 15:04 ] @
Ako mislis na polja u tabeli u firebird bazi, u runtime-u bogami NIKAKO (bar ne iz iste aplikacije).

Moguce je kreirati nove field-ove pomocu skripta. Ali je neophodan preduslov da budes JEDINI nakacen na bazu u trenutku izvrsenja skripta. Mislim da je nemoguce iz jedne iste aplikacije izvrsiti skript i odmah (bez restarta) citati/pisati po tim novokreiranim poljima. Mozda gresim.

A sam skript dobijes recimo iz IBExpert-a: dodajes nove field-ove ili sta vec hoces rucno, pa zatim pogledas u DDL tab FieldsEditor-a sta je IBExpert slozio/napisao. To ti je upravo SQL materijal za script. U svakom slucaju, jako pipava materija i tesko je naterati da 100% pouzdano radi.

Rajko
[ savkic @ 18.11.2008. 16:31 ] @
> Koristim firebird bazu i zbog raznih manipulacija sa poljima potrebno mi je da se ona dinamicki kreiraju u RunTime modu!KAKO?

Da li želiš da dodaš polja u bazu ili u svoje dataset komponente? Ako je u bazu možeš koristiti CREATE/ALTER TABLE, preporučljivo je da budeš jedini povezan u tom trenutku na bazu i da se pre dodavanja podataka u izmenjenu tabelu rekonektuješ na bazu. Ako polja ili podaci koji ti trebaju nisu stalni onda možeš koristiti i privremene tabele.
[ mr.zhile @ 18.11.2008. 20:31 ] @
@rajko
@savkic
Hvala na nesebicnoj pomoci!

Da pojasnim polja treba da se kreiraju na ClientDataSet-u !
Nesto slicno sam nasao,ali je za BDE

Code:

var
  Field: TField;
  i: Integer;
begin
  Table1.Active:=False;
  for i:=0 to Table1.FieldDefs.Count-1 do
    Field:=Table1.FieldDefs[i].CreateField(Table1);

  Field:=TStringField.Create(Table1);
  with Field do
  begin
    FieldName:='New Field';
    Calculated:=True;
    DataSet:=Table1;
  end;
  Table1.Active:=True;
end;

E sad nije mi tu najjasnije,u pr se kreira jedno polje,ali ja treba da kreiram sva definisana polja za dati dataset....kako da im dodelim imena da budu ista kao imena FieldDef?
[ savkic @ 19.11.2008. 09:51 ] @
> E sad nije mi tu najjasnije,u pr se kreira jedno polje,

U primeru se kreiraju sva polja definisana u FieldsDef i jedno dodatno string polje.

> ali ja treba da kreiram sva definisana polja za dati dataset....kako da im dodelim imena da budu ista kao imena FieldDef?

DataSet bi trebalo sam da napravi polja na osnovu definicije u FieldsDef, a ako hoćeš sam onda koristi kod iz primera koji si poslao.
[ mr.zhile @ 19.11.2008. 10:48 ] @
Nije mi jasan sledeci deo koda
Code:

  for i:=0 to Table1.FieldDefs.Count-1 do
    Field:=Table1.FieldDefs[i].CreateField(Table1);

Koliko ja kapiram,ovim se prave sve polja koja su definisana....
Kako ta,novo napravljena polja da vezem za svojstvo DataSet.Filds, jer mi javlja gresku da ja svojtvo tipa read only?
[ savkic @ 19.11.2008. 11:20 ] @
> Koliko ja kapiram,ovim se prave sve polja koja su definisana....
> Kako ta,novo napravljena polja da vezem za svojstvo DataSet.Filds, jer mi javlja gresku da ja svojtvo tipa read only?

Nisam siguran da te pratim, CreateField će napraviti novo polje i povezati ga sa datasetom, tvoja dalja akcija tu nije potrebna.
[ mr.zhile @ 19.11.2008. 17:42 ] @
Ovim kodom bi trebalo da se dodaju polja u simplledaataset,ali nece!!!
Nezmam gde gresim nemma sintaksnih,ali tu neizbezne semanticke grreske?
POMOC!
HELP!!!!!!!!!!
Code:

procedure TfrmPrikazDrzava.frmObjekat1acPregledExecute(Sender: TObject);
var
  sql:String;BR:Integer;
begin
        sql := 'select * from T_Drzave';
  TD.TransactionID := 2;
  td.IsolationLevel := xilREADCOMMITTED;
  with frmObjekat1.SimpleDataSet1 do
      begin 
           DataSet.CommandText := sql;
      end;
  dmMain.SQLConn.StartTransaction(TD);
  frmObjekat1.SimpleDataSet1.Open;
  PraviPolja;
  dmMain.SQLConn.Commit(TD);
end;

procedure TfrmPrikazDrzava.PraviPolja;
var
   Fld:TFieldDefs;
begin
   with frmObjekat1.SimpleDataSet1 do
   begin
      Close;
      Fld := frmObjekat1.SimpleDataSet1.FieldDefs;
   with Fld do
      begin
         Clear;
         Add('ime',ftString,25,false);
         with AddFieldDef do
            begin
               Name := 'MOJE POLJE';
               DataType := ftString;
               Required := True;
               Visible := True;
               DisplayName := Name
            end;
            with AddFieldDef do
            begin
               Name:='phNo';
               DataType:=ftInteger;
               Required:=True;
            end;

            with AddFieldDef do
            begin
               Name:='Email';
               DataType:=ftString;
               Size:=255;
            end;
      end;
   Open;
   end;

[ savkic @ 19.11.2008. 23:43 ] @
Prvo, u ovom kodu samo dodaješ definicije u FieldDefs, ali ne pozivaš CreteField koja bi napravila TField polja. Drugo, šta uopšte želiš da postigneš dodavanjem u FieldDefs pa onda pravljenjem regularnih polja, napravi odmah regularna polja. Treće, mislim da bi pomoglo da kažeš šta je zapravo ono što ti pokušavaš da uradiš, vrlo je moguće da se to može postići na druge, bolje načine.
[ mr.zhile @ 20.11.2008. 00:45 ] @
>>Treće, mislim da bi pomoglo da kažeš šta je zapravo ono što ti pokušavaš da uradiš, vrlo je moguće da se to može postići na druge, bolje načine.

Ovako imam jedan Frame na kom se nalaze dbgrid,datasource,simpledataset...frejm se koristi za primenu na vise formi...postoje polja koja treba da se sakriju od korisnika,kao npr id...isl
Kada u dizajntejmu prebacim frejm na formu,nije moguce dodati polja na simpledataset,pukne greku da se nemogu vrsiti dodavanja nad instancoom...ali polja moraju da budu napravljena,pa sam ja mislio ovim kodom da ih napravim,jer sve sto sam na netu nasao radi po principu AddFieldDef,a kapiram da negde ih treba kreirati...cak me buni sto mi kod
Code:
FieldDefs.Clear;

ne brise listu definisanih polja...
NAdam se da sam malo pojasnio zbrkanu situaciju
NISAM PAMETAN!!!
[ savkic @ 20.11.2008. 10:10 ] @
> Kada u dizajntejmu prebacim frejm na formu,nije moguce dodati polja na simpledataset,pukne greku da se nemogu vrsiti dodavanja nad instancoom...

Polja u ClientDatasetu se mogu dodavati i za vreme dizajniranja forme, ako tebi ne uspeva onda ne poštuješ proceduru, prođi kroz help.

> ali polja moraju da budu napravljena,pa sam ja mislio ovim kodom da ih napravim,

Da li su ta polja na neki način vezana sa bazom podataka odnosno da li uopšte koristiš neku bazu podataka?

> jer sve sto sam na netu nasao radi po principu AddFieldDef,a kapiram da negde ih treba kreirati...cak me buni sto mi kod
> FieldDefs.Clear;

FieldsDef <> Fields, ako hoćeš da isprazniš polja onda ti treba Fields.Clear;

> NAdam se da sam malo pojasnio zbrkanu situaciju

Sam si poslao kod (i to dva načina) koji radi u prvoj poruci da li si ga uopšte probao? Evo još jednom:

Code:

  Field:=TStringField.Create(Table1);
  with Field do
  begin
    FieldName:='New Field';
    Calculated:=True;
    DataSet:=Table1;
  end;


Ako već praviš polja onda to možeš raditi direktno u datasetu, ne moraš ići preko posrednika FieldDefs. Ali ako ipak hoćeš može i to, opet napraviš polja u FieldDefs i pozoveš CreateField ili (primer iz helpa):

Code:

  with ClientDataSet1 do
  begin
    with FieldDefs.AddFieldDef do 
    begin
      DataType := ftInteger;
      Name := 'Field1';
    end;
    with FieldDefs.AddFieldDef do
    begin
      DataType := ftString;
      Size := 10;
      Name := 'Field2';
    end;
    with IndexDefs.AddIndexDef do
    begin
      Fields := 'Field1';
      Name := 'IntIndex';

    end;
    CreateDataSet;
  end;
[ mr.zhile @ 20.11.2008. 11:04 ] @
Ok je resio sam problem!!!!!!!
HVALA!!!!
Evo koda koji mi je trebao
Code:

rocedure TfrmObjUpit.CreateFieldObject (FieldDef: TFieldDef);
var
 Dummy : TComponent;

 IntField : TIntegerField;
 StringField : TStringField;
// DateTimeField : TDateTimeField;
 DateTimeField : TSQLTimeStampField;
 FloatField : TFloatField;
 MemoField : TMemoField;


begin
   Dummy := cdsObjUpit.FindComponent('field' + FieldDef.Name) ;
   if Dummy <> nil then
      Dummy.Free;

   case FieldDef.DataType of
     ftInteger, ftSmallint, ftWord, ftAutoInc,
     ftLargeint : begin
                     IntField := TIntegerField.Create(cdsObjUpit);
                     IntField.Name := 'field' + FieldDef.Name;
                     IntField.DisplayLabel := FieldDef.DisplayName;
                     IntField.FieldName := FieldDef.Name;
                     IntField.DataSet := cdsObjUpit;
                  end;
     ftString, ftWideString, ftFixedChar :
                  begin
                     StringField := TStringField.Create(cdsObjUpit);
                     StringField.Name := 'field' + FieldDef.Name;
                     StringField.DisplayLabel := FieldDef.DisplayName;
                     StringField.FieldName := FieldDef.Name;
                     StringField.Size := FieldDef.Size;
                     StringField.DataSet := cdsObjUpit;
                  end;
     ftDate, ftTime, ftDateTime, ftTimeStamp :
                  begin
                     DateTimeField := TSQLTimeStampField.Create(cdsObjUpit);
                     DateTimeField.Name := 'field' + FieldDef.Name;
                     DateTimeField.DisplayLabel := FieldDef.DisplayName;
                     DateTimeField.DisplayWidth := 15;
                     DateTimeField.DisplayFormat := dmObjectDef.DisplayFormat(FNazivKlase, FieldDef.Name);
                     DateTimeField.FieldName := FieldDef.Name;
                     DateTimeField.DataSet := cdsObjUpit;
                  end;
     ftFloat, ftCurrency, ftBCD, ftFMTBcd :
                  begin
                     FloatField := TFloatField.Create(cdsObjUpit);
                     FloatField.Name := 'field' + FieldDef.Name;
                     FloatField.DisplayLabel := FieldDef.DisplayName;
                     FloatField.FieldName := FieldDef.Name;
                     FloatField.DataSet := cdsObjUpit;
                  end;
     else
         begin
            MemoField := TMemoField.Create(cdsObjUpit);
            MemoField.Name := 'field' + FieldDef.Name;
            MemoField.FieldName := FieldDef.Name;
            MemoField.DataSet := cdsObjUpit;
            MemoField.Visible := false;

            Dummy := cdsObjUpit.FindComponent('_field' + FieldDef.Name) ;
            if Dummy <> nil then
            Dummy.Free;


            StringField := TStringField.Create(cdsObjUpit);
            StringField.Name := '_field' + FieldDef.Name;
            StringField.DisplayLabel := FieldDef.DisplayName;
            StringField.FieldName := '_' + FieldDef.Name;
            StringField.FieldKind := fkCalculated;
            StringField.Size := 20;
            StringField.DataSet := cdsObjUpit;
         end;
     end;

E da ne otvaram drugu temu mogu ovde da postavim pitanja?
1.Kako biizgledala for petlja za string kojom bi se znak _ menjao sa razmakom, velika slova posle 1.slova malim,i ako naidje na reci tip sifra da zameni recju šifra drzava država?
2.Kakva je razlika medju application.terminate i halt?
[ savkic @ 20.11.2008. 12:34 ] @
> .Kako biizgledala for petlja za string kojom bi se znak _ menjao sa razmakom, i ako naidje na
> reci tip sifra da zameni recju šifra drzava država?

Koristi StringReplace.

> velika slova posle 1.slova malim,

Pretvori sve u mala slova pa prvo slovo pretvori u veliko.

> 2.Kakva je razlika medju application.terminate i halt?

Piše u helpu, Halt nasilno prekida program dok Application.Terminate to radi regularnim putem (šalje odgovarajuće poruke).
[ mr.zhile @ 20.11.2008. 12:46 ] @
a kako da pretvorim sve u mala slova?
[ Deep|Blue @ 20.11.2008. 12:52 ] @
LowerCase()
[ mr.zhile @ 20.11.2008. 14:32 ] @
E da jos mallko iskoristim ovu temu
KAko moze da se u sql upitu tipa 'select * from tabela' ogranisi broj rekorda koji ce biti pozvani?
Npr.Da prvo idu prvih N rekorda,zatim drugih N rekorda...N je neki bzvz broj 100,500,2000
ako je n 10
da 1.put prikaze 1-10
2.put 11-20
Postoje dugmad koja ce da ucecavaju sa 10 na 11,sa 20 na 21...
[ savkic @ 20.11.2008. 17:49 ] @
> KAko moze da se u sql upitu tipa 'select * from tabela' ogranisi broj rekorda koji ce biti pozvani?

Sintaksa zavisi od baze, recimo za FB je SELECT FIRST ...

> Npr.Da prvo idu prvih N rekorda,zatim drugih N rekorda...N je neki bzvz broj 100,500,2000 ako je n 10 da 1.put prikaze 1-10
> 2.put 11-20
> Postoje dugmad koja ce da ucecavaju sa 10 na 11,sa 20 na 21...

Ako se oslanjaš na bazu da vrati samo određeni broj slogova, onda se za svaki novi poziv posebno izvršava, što za velike podatke može stvoriti usporenje. Druga varijanta ti je da to sam radiš pomoću dva dataseta, prvi je vezan za bazu a drugi za kontrole, iz prvog prebaciš u drugi koliko ti treba podataka i tako redom kako se klikće.
[ mr.zhile @ 21.11.2008. 14:20 ] @
Mislim da se nismo razumeli nasao sam na netu
nesto otprilike
'select *from '+ tabela+' rows'+ od+' to'+ do

Nesto me jos interesuje
Napracio sam jedno stirngpolje kome treba vrednost da bude kao vrednost broja rekorda...nije generator ni id vec polje koje samo odredjuje broj rekorda ( REKORDA 1 rekorda )
Treba mi neka fukcija kojom bi se uvecavala vrednost tog broja
probao sam ovako
Code:

      for i :=0 to RecordCount-1 do
         FieldByName('RDB').AsString := IntToStr(I);


ali mi ignorise petlju!!!
Treba da kad se unese rekord vrednost polja se poveca za 1,a kad se izbrise smanji za 1,a kad se otvara dataset sa postojecim rekordima da im se vrednost dodoeli automatski...
POMOC!!!
[ mr.zhile @ 22.11.2008. 11:47 ] @
Opet ja sa mojim ptanjima...nadam se da ko pita treba da dobije odgovor
Pitanje:
Kako treba da izgleda sql upit koji bi kao rezultat imao spisak svih tabbela odredjene baze?
[ savkic @ 22.11.2008. 12:09 ] @
> Napracio sam jedno stirngpolje kome treba vrednost da bude kao vrednost broja rekorda...nije generator ni id vec polje koje samo
> odredjuje broj rekorda ( REKORDA 1 rekorda )

Želiš da jedno polje čuva redni broj sloga?

> for i :=0 to RecordCount-1 do
> FieldByName('RDB').AsString := IntToStr(I);

Koliko vidim dati kod menja vrednost RDB polja na jednom istom slogu. Ako želiš da svaki slog dobije svoju vrednost onda je najboljed da koristiš
Code:

DataSet.First;
while not DataSet.Eof do
begin
  DataSet.FieldByName('RDB').AsInteger := DataSet.RecNo;
  DataSet.Next;
end;


> Kako treba da izgleda sql upit koji bi kao rezultat imao spisak svih tabbela odredjene baze?

Zavisi od RDBMSa, to što ti tražiš se naziva metadata pa možeš potražiti na netu kako se to radi za konkretnu bazu.
[ mr.zhile @ 22.11.2008. 12:16 ] @
>Želiš da jedno polje čuva redni broj sloga?

Bas to?

>Zavisi od RDBMSa

FireBird baza je u pitanju?
[ savkic @ 23.11.2008. 14:16 ] @
> FireBird baza je u pitanju?

Code:

Create view s_tables_list (
  table_name
) as
Select 
  rdb$relation_name
From 
  rdb$relations
Where 
  rdb$view_blr is null and 
  rdb$relation_name not starting with 'rdb$' and
  rdb$relation_name not starting with 'tmp$'
Group by
  rdb$relation_name;
[ mr.zhile @ 23.11.2008. 15:24 ] @
@savkic
HVALA kralju

E sad me muci kako da odredim da li je naziiv jedinstven?
svaka tabela ima 3 polja koja moraju biti jedinstvena:ID,Sifafa,Naziv...prva 2 ssam uspeo da odresim bez greske,a 3. me zeza ...probao sam na sledece nacuine,ali mi puca grsku da ne postoji vrednost za sifru,jer kako ja kapiram on ne uzima da sifra ima vrednost
Code:
1.nacin
var
  SQl,Naziv : String;
begin
  Naziv := DBEdit2.Text;
  sql := 'select * from t_drzave where naziv_drzave = ' + QuotedStr(Naziv);
  sdsUnosIzmena.Close;
  sdsUnosIzmena.DataSet.CommandText := Sql;
  dmMain.SQLConn.StartTransaction(TD);
  sdsUnosIzmena.Open;
  dmMain.SQLConn.Commit(Td);
    if sdsUnosIzmena.RecordCount = 0 then
      begin
        sdsUnosIzmena.Append;
        sdsUnosIzmena.FieldByName('id').AsInteger := sp_Drzava_Gen_Id.Params[0].AsInteger;
        sdsUnosIzmena.FieldByName('sifra_drzave').AsString := DBEdit1.Text;
        sdsUnosIzmena.FieldByName('Naziv_Drzave').AsString := Naziv;
      end;
end;

2.nacin
function KorektanUnos(sds:TSimpleDataSet;Tabela,Polje,Vrednost:String):Boolean;
var
  TD:TTransactionDesc;
  sqlText:String;
begin
      sqlText := 'select * from ' + Tabela + ' where ' + Polje + ' = ' + QuotedStr( Vrednost );

      TD.TransactionID := 3;
      TD.IsolationLevel :=xilREADCOMMITTED;

      sds.Close;
      sds.DataSet.CommandText := sqlText;
      SQLConn.StartTransaction(TD);
      sds.Open;
      SQLConn.Commit(TD);

      if sds.RecordCount = 0 then
        Result := True
      else
        begin
          Result := False;
          ShowMessage('Polje ' + Polje + ' mora imati jedinstvenu vrednost ');
        end;
end;
//pozovem je sa

KorektanUnos(sdsUnosIzmena,'T_DRZAVE','NAZIV_DRZAVE',DBEdit2.Text)


Opet nece ne znam gde gresim?
Funkciju pozovem u dogadjaju Balidation
[ savkic @ 23.11.2008. 17:35 ] @
> E sad me muci kako da odredim da li je naziiv jedinstven?

Napravi unique indekse nad tim poljima.

> svaka tabela ima 3 polja koja moraju biti jedinstvena:ID,Sifafa,Naziv...prva 2 ssam uspeo da odresim bez greske,a 3. me zeza ...probao sam
> na sledece nacuine,ali mi puca grsku da ne postoji vrednost za sifru,jer kako ja kapiram on ne uzima da sifra ima vrednost

Moraš naučiti da debaguješ. Ako ti kaže da ne postoji šifra, pogledaj kako izgleda tekst SQLa koji si izvšio, ako tu nema vrednosti, onda pogledaj odakle si uzeo tu vrednost. Koliko vidim ti koristiš DBEdit.Text i tu može biti problem, pre svega gotovo nikada nema razloga da se radi direktno sa DBEdit kontrolom, već sa poljem dataseta sa kojim je taj DBEdit povezan.
[ mr.zhile @ 23.11.2008. 18:03 ] @
>Napravi unique indekse nad tim poljima.

To sam uradio na serverskoj strani

Ma ok je sqltext , ali kad uzmem vrednost iz dbedi2 vrednost iz dbedit1 se brise,to mi nije jasno?
Probao sam i sa DataSet kontrolom,ali nece
Umesto DBEDit koristio sam sdsUnosIzmena.FieldByName('Naziv_Drzave').AsString i opet nece?