Avatar billede zerohero Nybegynder
11. oktober 2000 - 15:55 Der er 15 kommentarer og
2 løsninger

Nybegynder i databaser

Hej allesammen. Jeg har lige lært at oprette en database (JUBIIII), hvor jeg benytter Ttable. Men hvordan faen jeg få lov til at bruge den? Jeg mener når jeg har koblet min db fil, Ttable og Tdatasource sammen og bruger følgende kode for at indsætte/rette i databasen:

table1.open;
table1.insert; (eller table1.edit)
table1custom.fieldbyname(\'et eller andet\')asstring := \'et eller andet\'; (eller
table1custom.fields[x]asstring := \'et eller andet\';)
table1.post;

så kommer følgende fejlmedelse:
\"Table1: Type mismatch for field \'Directory\', expecting: Memo actual: string.\"

Er det en helt forkert den måde jeg gør?
Trods mine fattige forklaringer håber jeg på et godt svar med masser af eksempler da jeg er LIDT tungnem *G* og hvis en eller anden GUD viser et søge eksempel så er ville det være GUDDOMMELIGT.

ZeroHero

Forresten min database består af følgende fields:
1 Drive
2 Directory
3 Filename
4 Extension
5 Filesize
6 Filedate
7 Type
8 Katalog

Hvis det kan være til nogen hjælp...
Avatar billede davsclaus Nybegynder
11. oktober 2000 - 16:02 #1
Hvordan har du defineret din tabel?

Det lyder som om at AsString på feltet Directory ikke er tilladt - Memo.
Avatar billede zerohero Nybegynder
11. oktober 2000 - 16:05 #2
lige et øjeblik så skal jeg tjekke....
Avatar billede flashit Nybegynder
11. oktober 2000 - 16:05 #3
Jeg tror at du indtaster tal i et tekstfelt,
og det må du ikke.
Avatar billede zerohero Nybegynder
11. oktober 2000 - 16:10 #4
Nej, det er ikke tal jeg indsætter det er kun en string. Men hvordan kan jeg bestemme om en field skal modtage integer eller string?
Avatar billede tknudsen Nybegynder
11. oktober 2000 - 16:11 #5
til søgning vil jeg anbefale dig at bruge en TQuery komponent frem for en TTable. En query tillader langt større kontrol over din søgning.

du anvender den næsten på samme måde som en ttable - eneste STORE forskel er at du selv skal skrive dit søgekriterie. Det kan du gøre på design tidspunktet eller runtime. På design tidspunktet skal du have en TQuery komponent på formen (du finder den  på samme faneblad som TTable).

Du kan nu sætte din TDataSource til at pege på din TQuery i DataSet property\'en. I SQL property\'en skriver du så feks:

SELECT * FROM TableName

- hvor TableName er navnet på din tabel (!!)

Dette vælger ALLE felter fra tabellen hvorimod:

SELECT Filename FROM TableName WHERE Filesize > 1024

finder alle filenavne hvor filstørrelsen er større end 1K


Hvis du vil lave forskellige søgninger kan du gøre det runtime - dvs du kan ændre SQL sætningen imens dit program afvikles. Dette gøres (et-eller-andet-sted i koden) via din TQuery således (jeg antager at TQuery\'en hedder Q1):

Q1.Close;
Q1.SQL.Clear;
Q1.SQL.Add(\'SELECT * FROM TableName\');
Q1.Open;

eller

Q1.Close;
Q1.SQL.Clear;
Q1.SQL.Add(\'SELECT FileName\');
Q1.SQL.Add(\'FROM TableName\');
Q1.SQL.Add(\'WHERE FileSize > :pSize\');
Q1.ParamByName(\'pSize\').AsIinteger := 1024;
Q1.Open;

viel spaß... (Danmark - Bulgarien 4-1 :-)

Avatar billede pellelil Nybegynder
11. oktober 2000 - 16:20 #6
Som \"DavsClause\" siger, det lyder som om at du har defineret \"Directory\" som et Memo felt hvorved du skal tildele værdien som:

table1custom.fieldbyname(\'et eller andet\').Value := \'et eller andet\';


Avatar billede pellelil Nybegynder
11. oktober 2000 - 16:23 #7
Her er et eksempel som jeg lavede i sidste uge da jeg skulle test en SQL over en ISDN Lines. Eksemplet læser en tekstfil indeholdende \"nogle oplysninger\" som hældes i en SQL database (vha. en TTable)

<SNIP>
procedure TForm1.Button1Click(Sender: TObject);
var
  szFileName : String;
  InputFile  : TextFile;
  szLine    : String;
  iIdx      : Integer;
  chRand    : Char;
  iTimer    : Integer;
begin
  szFileName := FilenameEdit1.FileName;
  AssignFile(InputFile, szFileName);
  Reset(InputFile);
  iTimer := GetTickCount;
  try
    repeat
      ReadLn(InputFile, szLine);
      if (Length(szLine) > 40) and (szLine[1] <> \';\') and (szLine[1] <> \' \') then begin
        TableTest.Append;
        TableTest.FieldByName(\'Id\').AsString      := Copy(szLine,1,4);
        TableTest.FieldByName(\'Name\').AsString    := Copy(szLine,5,23);
        TableTest.FieldByName(\'Lat\').AsFloat      := Str2Float(Copy(szLine,29,10));
        TableTest.FieldByName(\'Lon\').AsFloat      := Str2Float(Copy(szLine,39,10));
        szLine := \'\';
        for iIdx := 1 to 200 do begin
          chRand := Char(65 + Random(26));
          szLine := szLine + chRand;
        end;
        TableTest.FieldByName(\'RandStr\').AsString := szLine;
        TableTest.Post;
      end;
    until EOF(InputFile);
  finally
    CloseFile(InputFile);
  end;
  LabelTime2.Caption := FloatToStr((GetTickCount-iTimer) / 1000.0);
end;
</SNIP>
Avatar billede tknudsen Nybegynder
11. oktober 2000 - 16:27 #8
mht til editering af poster kan du også bruge en TQuery:

indsæt:

Q1.Close;
Q1.SQL.Clear;
Q1.SQL.Add(\'INSERT INTO TableName VALUES(:pDrive,:pDir,:pFileName,:pExt,:pFileSize,:pFileDate,:pType,:pKatalog)\');
Q1.ParamByName(\'pDrive\').AsString := \'c:\';
Q1.ParamByName(\'pDir\').AsString := \'\\dims\\\';
Q1.ParamByName(\'pFileName\').AsString := \'dimser\';
Q1.ParamByName(\'pExt\').AsString := \'dms\';
Q1.ParamByName(\'pFileSize\').Asinteger := 430281;
Q1.ParamByName(\'pFileDate\').AsDate := \'01-01-2000\'; //(format?)
Q1.ParamByName(\'pType\').AsString := \'dims\';
Q1.ParamByName(\'pKatalog\').AsString := \'udkommer medio 2000 :-)\';
Q1.ExecSQL;

indsætter en HEL record i tabellen. Hvis du ikke vil indsætte data i alle felter skal SQL sætningen se således ud:

INSERT INTO TableName (FileName,FileSize) VALUES(:pFileName,:pFileSize)
og så skal parametrene tilføjes som ovenfor

opdater:

Q1.Close;
Q1.SQL.Clear
Q1.SQL.Add(\'UPDATE TableName SET FileDate = :pFileName, FileSize = :pFileSize WHERE FileName = :pFileName\');
Q1.ParamByName(\'pFileName\').AsString := \'dimser\';
Q1.ParamByName(\'pFileSize\').Asinteger := 4302810121;
Q1.ParamByName(\'pFileDate\').AsDate := \'01-01-1998\'; //(format?)
Q1.ExecSQL;

sletning:

Q1.Close;
Q1.SQL.Clear;
Q1.SQL.Add(\'DELETE FROM TabelName WHERE FileName = :pFileName\');
Q1.ParamByName(\'pFileName\').AsString := \'dimser\';
Q1.ExecSQL;


(pfeeew)

Avatar billede zerohero Nybegynder
11. oktober 2000 - 16:27 #9
Hej Pellelil...
Hvordan kan jeg bestemme om en field skal modtage integers eller strings?
Og hvad er forskellen mellem .Value .Asstring da de begge modtager string. Og hvad betyder float?
Avatar billede zerohero Nybegynder
11. oktober 2000 - 16:32 #10
Hej Tknudsen...
OK... det lyder faktisk på det hele at det er bedre at bruge Tquery. Men hvad er den præcise forskel mellem Ttable og Tquery bortset fra det med en bedre søgnings mulighed i Tquery?
Avatar billede pellelil Nybegynder
11. oktober 2000 - 16:34 #11
Vi starter bagfra. Mit eksempel indeholder en variable type (Float) som jeg selv har defineret
<SNIP>
Type
  Float = Double;
</SNIP>

Så du kan bare erstatte den med single, double, extended eller lign.

Ligeledes så er Str2Float også mine egne funktioner, men du kan bruge StrToFloat - den eneste forskel er at jeg fjerne \"ulovlige tegn\" inden jeg konvertere således at jeg ikke får en exception hvis strengen indeholder alfanumeriske tegn.

Du skal ALTID tage udgangspunkt i hvordan feltet er defineret i Databasen (eller hvis vi skal bruge de rigtige navne - i tabellen). Hvis feltet er et tal felt så SKAL du bruger \".AsInteger\" eller \".AsFloat\" og det er ikke ligegyldigt hvilken du bruger. Hvis det er et heltals felt så SKAL du bruger \"AsInteger\" og hvis det er flydende komma så SKAL du bruge \"AsFloat\".

Prøv at kigge på Delphi\'s hjælpe til TMemoField.AsString og TMemoField.AsValue.
Avatar billede pellelil Nybegynder
11. oktober 2000 - 16:44 #12
For at (muligvis) komme Tknudsen i forkøbet så er brugen af TTable og TQuery ofte en \"relgions krig\".

Når vi snakker søgning så vil jeg til en hver tid foreslå en TQuery da den er meget stærkere. F.eks. så kan du vælge sorteringer uafhængig af evt. Index i tabellen og når vi taler klient/server så kan du lave selecteringer der bliver behandlet af serveren i stedet for klienten hvilket igen vil sige at mindre skal transmiteres over netværker (vigtigt i den \"test\" jeg netop har lavet hvor jeg kørte fra en kient op på en server via ISDN). Havde jeg lavet det samme med en TTable var jeg nødt til at bruge filtre hvilket betyder at ALLE poster \"sendes\" over (ISDN) linien og så er det kilenten der \"fra selektere\" de der ikke skal bruges.

Med hensyn til at oprette poster så jeg egentlig mest glad for TTable. Denne skal bare sættes i Append/Insert mode. Felterne udfyldes med værdier via \"FieldBy\" and ændringen gemmes med en POST. Uden om del hele \"pakker man\" noget transaktionsstyring (hvis det skal gøre rigtigt).
Avatar billede tknudsen Nybegynder
12. oktober 2000 - 08:12 #13
Tja - jeg er faktisk ikke klar over det - årsgen til at jeg bruger TQuery (og dermed SQL) er at jeg koder i forskellige sprog - som alle understøtter en-eller-anden metode til at afvikle SQL.

Men som pellelil nævner vil en TTable altid indeholde alle records (efter post) og dermed \'virke\' hurtigere - alt efter serverens placering - end en TQuery.
Avatar billede zerohero Nybegynder
12. oktober 2000 - 08:32 #14
Hej allesammen 1000 tak for alle jeres svar.I går aftes sad jeg og nørklede med det, og nu har jeg endelig fundet ud af det. Men den sidste lille ting jeg gerne vil vide er, hvordan søger jeg i en Ttable. Jeg har set følgende kode i Delphi\'s hjælpefil:

table1.setkey;
table1.fields[0].asstring := \'sm\';
table1.Gotonearest;

Er det den kode jeg skal bruge når jeg søger efter et eller andet i et bestemt field?
Hvis jeg nu vil vise resultatet i en Tlistbox
hvordan gør jeg så?

PS: Hej Tknudsen... ja jeg ved godt hvad du tænker lige nu: \"Så brug da en Tquery!!!\", men jeg kunne godt tænke mig at håndtere en Ttable før jeg går i kast med en Tquery.

Forresten... Til Pellelil, når jeg søger efter Tmomofield.asstring og Tmemofield.asvalue som du anbefalede mig at gøre kommer der ingen søge resultater frem.
Avatar billede tknudsen Nybegynder
12. oktober 2000 - 08:48 #15
Det fede ved at programere er når tingene lykkes. OG da vi ikke er ens er der heller ikke kun een vej til målet...(dybt :-)

good luck...

/thomas
Avatar billede pellelil Nybegynder
12. oktober 2000 - 09:01 #16
zerohero> Det er nu ikke kun TKnudsen der tænker \"Så brug da en TQuery\". Jeg ville gå så langt som at tænke \"Så brug dog for h....... en TQuery\"  :-)

Med hensyn til hjælp så søg efter TMemoField og gå ind i hjælpen for denne. Der kan du vælge properties og så igen vælge den property der hedder Value. Gør dig selv den tjeneste at sætte dig ind i hvordan hjælpen (generelt) virker og hvordan Borland har bygget den op. Mange gange er manualer og hjælpefiler lige så nyttige som en litter fyrings olie er når din bil render tør, men i mine øjne så har Borland gjort det godt.

Skulle ovenstående være \"for meget\" så undskylder jeg da jeg kan se at jeg har ledt dig lidt på vildspor, da property\'en bare hedder \"Value\" og ikke \"AsValue\" som jeg skrev først.

tknudsen> jeg mindes ikke at have sagt at en TTable \"virker\" hurtigere. JEG synes blot at den er nemmere at bruge når jeg skal oprette poster (smag og behage), men som jeg har nævnt (efterhånden et par gange <G>) så er en TQuery at foretrække i en søgning. Men du har helt ret i at \"ikke er ens...\".

Med hensyn dit SetKey eksempel har jeg flg. kommentare:

For det første så \"byrder jeg mig ikke om\" brugen af \"Fields[0]\", da dette virker lige indtil den dan hvor du beslutter at en anden felt skal ligge tidligere end det der er der nu. Ligeledes er programmet nemmere at læse hvis du bruger FieldByName da man kan se feltets navn (hvilket gerne skulle give et finger prej om hvad det var for et felt).

En anden ting er at SetKey/GotoNearest formegentlig kun virker når/hvis du har valgt det index der netop betyder en sortering i samme rækkefølge som de(t) felter du udvælger på. Jeg skal gerne indrømme at jeg her \"gætter\" da en Query er at fortrække i min bog.
Avatar billede zerohero Nybegynder
12. oktober 2000 - 09:10 #17
OK OK OK OK...Jeg bruger en Tquery (men jeg var bare så glad da jeg fik mine Ttable koder til at virke)... Jeg ved ikke hvem jeg skal give point til for både Tknudsen og Pellelil har været de sejeste til at hjælpe...
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester