29. marts 2004 - 10:31Der er
3 kommentarer og 1 løsning
Slet post i database.
Da jeg laver en adressebog i Delphi, vil jeg have at der skal være en funktion, som skal slette personer, hvis man ikke vil have dem i adressebogen mere. Adressebogen ligger som en database, så jeg skal altså kunne slette personerne i databasen via mit program. Problemet er bare, at posterne i databasen jo ikke er unikke, så jeg bliver nødt til at identifisere personerne via en autonøgle. Dette nummer kan jo også skifte, så man kan ikke regne med at post nummer 1 i min tabel (som viser adressebogen i programmet) har nøglenummer 1 i databasen. Hvordan løser jeg dette problem? Jeg har prøvet følgende:
private { Private declarations } public { Public declarations } adrid: array of integer; end;
var Form1: TForm1; celle: integer;
procedure TForm1.FormCreate(Sender: TObject); var t: integer; begin ADOConnection1.Open; try ADOQuery1.SQL.Clear; ADOQuery1.SQL.Add('SELECT * FROM adressebog'); ADOQuery1.Open; t:=0; while not ADOQuery1.EOF do begin adrid[t]:= ADOQuery1.Fieldbyname('adressebogid').AsInteger; ADOQuery1.Next; inc(t); end; finally ADOQuery1.Close; end; end;
procedure TForm1.StringGrid1SelectCell(Sender: TObject; ACol, ARow: Integer; var CanSelect: Boolean); begin celle:=ARow; end;
procedure TForm1.ButtonsletClick(Sender: TObject); begin ADOQuery1.SQL.Clear; ADOQuery1.SQL.Add('DELETE * FROM adressebog WHERE '+inttostr(adrid[celle])); end;
procedure TForm1.FormDestroy(Sender: TObject); begin ADOConnection1.Close; end;
end.
Det giver dog en "Access Violation at address 00498A7C in module 'Project1.exe' og den markerer sætningen adrid[t]:= ADOQuery1.Fieldbyname('adressebogid').AsInteger; Det bliver jeg jo ikke meget klogere af! Nogen ideer?
Hvorfor lægger du ikke basen ind i en DBGrid og lægger en DBNavigator ind på siden. Så skal du ikke spekulere på at slette og indsætte. Det går nærmest af sig selv.
Du smækker bare en TDataSource på, forbinder den med tabellen. Dernæst en TDBNavigator som du forbinder med DataSourcen. Endelig smækker du en TDBGrud på og forbinder den til samme DataSource og så kører det - simpelt og let.
Ulempen er (dog ikke hvis du bare bruger Paradox eller Access), at det ikke altid dur mod databasen. Professionelle relationsdatabaser kræver alt i SQL (Af samme grund bruger jeg aldrig de "direkte" og lette funktioner som TDBNavigator tilbyder, men kører udelukkende med SQL. Jeg siger ikke at det er smartest for det er en afvejning af behov og fleksibilite, så brug du bare komponenterne).
Er blevet klar over at "FieldByName().AsString er et fortidslevn. Mener at nedenstående også virker
procedure TForm1.FormCreate(Sender: TObject); var t: integer; begin ADOConnection1.Open; try ADOQuery1.SQL.Clear; ADOQuery1.SQL.Add('SELECT adressebogid FROM adressebog'); // Optimering ADOQuery1.Open;
t:=0; while not ADOQuery1.EOF do begin adrid[t]:= ADOQuery1['adressebogid']; // Prøv dette ADOQuery1.Next; inc(t); end; finally ADOQuery1.Close; end; end;
Endelig - og det er et optimeringsspørgsmål. Du laver "select * from ...", men hvis den indeholder andre felter end adressebogid så bør du ændre det til "select adressebogid from ...". Der er ingen grund til at hente mere data end du har brug for.
Den navigator er jo helt genial:) Siden det kun var hrc, der gav et svar får han pointene. Tak for svarene.
Synes godt om
Ny brugerNybegynder
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.