Delphi og Databaser

Tags:    delphi
Skrevet af Bruger #123 @ 26.11.2003

Databaser


Vi må nok starte med at skrive lidt om Delphi og databaser. Der er adskillige muligheder inden for database support i Delphi, jeg vil starte med at gennemgå de mest almindelige.

Man skal i øvrigt være opmærksom på at man fra Delphi 5 kun har database support i Professional og opefter. Den sidste "personal" edition af Delphi som har database support er Delphi 4 Standard.

BDE
Siden Delphi 1 har Delphi direkte supporteret databaser i gennem en teknologi som hedder BDE. Det står for Borland Database Engine.

Det er et abstraktionslag som lægges ind imellem databasen og Delphi og fungerer ved at abstrahere fra de forskelle der er på de forskellige databaser. Måden man forbinder til en Interbase database og en Microsoft Access database er meget forskellige f.eks. Typisk bliver det dog brugt sammen med Paradox tabeller som er et filbaseret database system der er indbygget i bl.a. Windows. Paradox er dog et gammel system, og lider derfor under nogle begrænsninger i funktionalitet som man ikke ser i nyere systemer.

Problemet med BDE er at den har et forholdsvis stort footprint, det er en installation på adskillige Mb, ikke noget man ønsker at inkludere i sin installation hvis man regner med sætte sit program til download. Ud over at man også skal sørge for at installere selve database serveren...
Se iøvrigt mere her: http://info.borland.com/devsupport/bde/

Fordele: Når først det er sat op, er det meget let at arbejde med.
Ulemper: Stort footprint, besværligt at sætte op. Kræver ekstern database system.

DBExpress
Fra omkring Delphi 6 barslede Borland med en ny måde at tilgå databaser på. Den metode hedder DBExpress under et, og består reelt at et par ini filer og en dll eller to til hver database engine (en database engine er den mekanik der reelt får databasen til at fungere). Dvs. at metoden udmærker sig ved et relativt lille footprint.

Man skal stadigvæk sørge for at der er en database server tilgængelig på maskinen, men er der det så fungere denne metode udemærket. Problemet med den er at der kun følge support til ganske få databaser med delphi. Professional understøtter Interbase og MySQL. Enterprise understøtter endvidere DB2, Oracle og vist nok MS SQL Server.
Man kan så downloade ekstra drivere, der er adskillige rundt om på nettet, men de fleste koster penge.

Fordele: Lille footprint, let at sætte op.
Ulemper: Eksterne filer der skal inkluderes. Drivere koster ofte penge. Understøtter kun uni-directionelle dataset. Kræver eksternt database system.

MyBase
MyBase er et lille filbaseret database system som følger med Delphi, det findes i følgende versioner: Delphi 5 Enterprise, Delphi 6/7 Professional og Enterprise.

MyBase udmærker sig ved at det har et meget lille footprint. Enten inkluderer man en dll (Midas.dll) som fylder ca. 300 Kb, eller også inkl. man en unit i sit program der hedder MidasLib. Denne dcu før ens program til at fylde ca. 200Kb ekstra.

MyBase har nogle begrænsning i forhold til større database projekter. Man har begrænsede muligheder med hensyn til filtrering og udvælgelse af data, men er iøvrigt velegnet til små projekter. Desuden er det fremragende til briefcase modeller, hvor man har en større database, f.eks. en MS SQL database. Her kan man så hente data over i sit dataset, som ligger i hukommelsen og bearbejde det off-line og så opdatere data tilbage på serveren, her er uni-directionelle datset dog kun understøttet.

Alternativt kan man anvende som et selvstændigt database system. Derved får man adgang til bl.a. bi-directionelle dataset og det fungere i det hele taget ganske fornuftigt.

Fordele: Meget lille footprint. Der er ingen eksterne filer, eller database system.
Ulemper: Understøtter kun uni-directionelle dataset ved eksterne databaser. Begrænset funktionalitet.

ADO
ADO står for Active Data Objects og er en Microsoft opfindelse. Det betyder at man er begrænset til Microsofts egne database produkter. Dog finder der ADO drivere til andre systemer, men ADO drivere til Access f.eks. er faktisk inkluderet i de fleste Windows systemer, ellers kan de downloades ganske gratis fra Microsoft.

ADO kan være lidt besværligt at anvende, men til gengæld kan man rent faktisk anvende dem i Personal editions af Delphi. Det vil jeg ikke berører nærmere i denne artikel, da det vil kræve en artikel for sig selv. I Delphi 6 Professional (og muligvis også Delphi 5) findes der en række komponenter som letter arbejdet ganske betydeligt.

ADO er et godt system, som dog er begrænset til Microsoft systemer, dvs. Access og MS SQL Server. Læs evt. mere her: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/ado270/htm/pg_introduction.asp

Fordele: Findes allerede i de fleste Windows systemer.
Ulemper: Begrænset udvalg af understøttede systemer. Kræver eksternt database system.

Uni-directionelle dataset


Som lovet vil jeg berører emnet uni-directionelle dataset. Dette betyder at et dataset kun kan bevæge sig i een retning når det er åbnet. Skal man skifte retning, skal man lukke datasettet og åbne det igen i den rigtige retning. Det er alletiders til rapportering f.eks., men ikke ret godt til online redigering af data.

og Bi-directionelle dataset


Med et bi-directionel dataset kan man bevæge sig frem og tilbage som man lyster i datasettet uden at skulle lukke og åbne det konstant. Det er mest benyttet til redigerering og visning af online data, men er ikke velegnet til rapportering, da det er noget mere ressource krævende.

Delphi og Databaser


Nu vil vi så i gang med at lave en database applikation i Delphi. Jeg har valgt at anvende MyBase til dette da det er dejligt simpelt at gå til, og så kræver det ikke noget eksternt database system. Denne artikel henvender sig derfor til dem der har Delphi 5 Enterprise, eller Delphi 6 Professional og frem.

Vi vil lave en simpel lille telefon bog hvor vi kan gemme oplysninger om venner og familie med adresser og telefon numre.

Vi starter med at oprette et nyt projekt i Delphi, vi kan f.eks. kalde det "Telefonbog". Så starter vi at placere følgende komponenter på vores form:
1 TMainMenu (Standard), 6 TLabel (Standard), 1 TStatusBar (Win32), 1 TClientDataSet (Data Access), 1 TDataSource (Data Access), 1 TDBNavigator (Data Controls), 5 TDBEdit (Data Controls) og 1 TDBMemo (Data Control). Navnene i paranteser er navnene på de faneblade komponenterne er placeret i komponent paletten.

Vi skal iøvrigt også have sat en TOpenDialog og TSaveDialog på vores form. Dem kalder vi diaOpen og diaSave henholdsvis. De skal lige have sat nogle egenskaber.
Fold kodeboks ind/udKode 

Jeg har valgt den følgende placering af komponenterne:



Opsætningen af menuen ser således ud:



Om du navngiver komponenterne som jeg gør, er fuldstændig op til dig, men det er altid en god ide at give komponenterne sigende navne, så man ikke bliver forvirret. I dette tilfælde er der f.eks. 5 TDBEdit komponenter og man bliver hurtigt forvirret og i tvivl om hvorvidt f.eks. DBEdit3 var telefon, eller mobil.

Det næste vi skal gøre er at definerer vores database. Dobbelt klik på TClientDataSet komponenten. Du får nu et lille vindue frem hvor i man kan definere databasens felter. Det gøres ved at højre-klikke og vælge "New Field". Det frembringer følgende vindue:



Her indtaster man felt navn, navnet på TField komponenten der skal oprettes, felt type og evt. længde på feltet. Vi skal bruge 6 felter:

Navn - Type:String - Size:50
Adresse - Type:Memo
Telefon - Type: String - Size:20
Mobil - Type:String - Size:20
Arbejde - Type:String - Size:20
Email - Type:String - Size:50

Man kan godt navngive komponenterne, men det er ikke nødvendigt, vi skal ikke bruge dem direkte. Felt oversigten ser nu således ud:



Luk dette vindue og højre-klik på din TClientDataSet. Du får nu en context-menu frem. Her skal du finde det punkt der hedder "Create DataSet" og klikke på det.

Nu skal vi så have nogle bindinger.

Start med at sætte DataSource komponentens egenskab DataSet til at pege på ClientDataSet'et. Vælg dernæst hvert DBEdit felt, DBnavigator og DBMemo og sæt DataSource egenskaben til at pege på TDataSource komponenten, jeg har valgt at kalde den dsAdresser.
Endeligt sætter vi DataField egenskaben på hver komponent til et felt i databasen.
edtNavn.DataField = Navn
mmoAdresse.DataField = Adresse
edtTelefon.DataField = Telefon

osv.

Nu skal vi så til at skrive kode.

Menuen Filer

Start med at dobbelt-klikke på menu punktet "Ny adresse bog".
Delphi opretter nu en procedure hvori vi skal have skrevet noget kode.
Fold kodeboks ind/udKode 

Det der sker her, er at vi lukker datasettet, laver et nyt dataset og tildeler det et filnavn. Derefter åbner vi datasettet igen, og vupti. Vores telefon er indlæst og åbnet og klar til brug.

Så skal vi have åbnet for mulighed for at åbne og gemme eksisterende databaser.
Dobbelt-klik på menu punktet "Åben adresse bog". I denne procedure skriver vi følgende:
Fold kodeboks ind/udKode 

Igen lukker vi datasettet. Det medfører i øvrigt at evt. ændringer gemmes i filen så vi skal ikke bekymre os om at huske at gemme filen. Dernæst kalder vi OpenDialog og vælger en fil som tildeles ClientDataSet som derefter åbnes.

Det vi skal bruge Gem Adresse bog til, er faktisk hvis vi vil gemme en database under et nyt navn. Vi dobbelt-klikker på "Gem adresse bog" og udfylder proceduren med det følgende kode.
Fold kodeboks ind/udKode 

Vi sætter simpelthen FileName til det valgte filnavn, og gemmer datasettet. Dermed har vi gemt datasettet under et nyt filnavn.
Menuen Poster
Så kommer vi til håndtering af poster i databasen.

Udfyld "Ny Post" med den følgende kode.
Fold kodeboks ind/udKode 

Vi checker at datasettet er i en "browse" tilstand, og er det tilfældet kalder vi Insert metoden på datasettet. Hvis vi ikke checker for tilstanden først, risikere vi at kalde f.eks. insert mens vi allerede er i insert tilstand og det vil resulterer i en felt.

"Ret Post" skal udfyldes med denne kode.
Fold kodeboks ind/udKode 

Her checker vi først for at dataset er i "browse" tilstand, men vi checker også for at der rent faktisk er data i datasettet. Ved at undersøge om BOF (begining of File) og EOF (End of File) er falske, er vi sikre på at der er data.

Koden for "Slet post" er meget lig "Ret post".
Fold kodeboks ind/udKode 

Vi foretager de sammen check, men sletter i stedet for at redigere.

Når vi har indtastet vores data, skal det gemmes. Udfyld proceduren for "Opdater" med følgende:
Fold kodeboks ind/udKode 

Her checker vi for at vi rent faktisk er i en tilstand af redigering inden vi poster ændringerne.

Det samme gør sig gældende for "Fortryd".
Fold kodeboks ind/udKode 

Her bruger vi så bare Cancel metoden istedet for, for at droppe ændringerne.

Menuen Navigation

Navigation i datasettet er meget meget let, i det datasettet giver os alle metoderne, vi skal bare kalde dem.

"Første post"
Fold kodeboks ind/udKode 

"Frem"
Fold kodeboks ind/udKode 

"Tilbage"
Fold kodeboks ind/udKode 

"Sidste"
Fold kodeboks ind/udKode 

Så mangler vi bare en ting, hvordan vi søger i datasettet.
"Find"
Fold kodeboks ind/udKode 

Den kræver nok lidt mere forklaring end de tidligere. For det første er det bare en simpel søgning hvor man søger på navn. Vi anvender InputQuery som er en funktion i Delphi der forærer os en simpel indtastningsdialog.

Den tager tre argumenter, Caption, Prompt og Value. Slå den op i hjælp for nærmere information.

Hvis den returnerer true har brugeren trykket ok, og vi kan så anvende Value til at søge på. Det gøres med Locate metoden. Denne metode tager tre argumenter:
"KeyFields" som er en semikolon separeret liste over feltnavne der skal søges på.
"KeyValues" som er en liste over feltværdier der skal søges på.
"Options" er et sæt af muligheder man kan sætte. I dette tilfælde har vi sat Options til at inkludere "loCaseInsensitive" og "loPartialKey" hvilket indikere at vi er ligeglade med om det er store eller små bogstaver, og at det indtastede søgedata kan være en del af et ord. Delphi hjælpen har iøvrigt en ganske udemærket gennemgang af hvordan Locate fungere.

Afslutningsvis
Vi mangler bare een ting for at vi er færdige. Vi skal lige have programmet til at vise os hvor mange poster der er i databasen. Dette gøres meget simpelt ved at vælge ClientDataSet på formen. Gå over på Object Inspectoren og vælge "Events". Her skal vi så dobbelt-klikke på "AfterOpen". I den procedure som bliver skabt derved skal vi kode således:
Fold kodeboks ind/udKode 

For at få en nøjagtig status, skal cdsAdresserAfterOpen hændelsen tildeles AfterPost og AfterDelete hændelserne på datasettet.

Det var det


Således anvendes TClientDataSet til en simpel applikation. Man anvende TClientDataSet til mange ting, og det er også muligt at bruge flere dataset samtidigt og derved have mange tabeller. En ting man skal være opmærksom på er at TClientDataSet er et såkaldt "In-memory" dataset. Dvs. at hele tabellen læses ind i hukommelsen, når man åbner datasettet.

Det betyder at har man en tabel med 35 Mb data i, så bruger programmet altså 35Mb eller mere af hukommelsen for at læse datasettet ind. På de fleste nye PC'ere i dag er det ikke det store problem, men det er da noget man skal være opmærksom på.

Kildekoden til adresse bogen som vi bygger i denne artikel kan hentes her:
http://udvikleren.dk/articlefiles/123/Telefonbog.zip

God fornøjelse med TClientDataSet.




Hvad synes du om denne artikel? Giv din mening til kende ved at stemme via pilene til venstre og/eller lægge en kommentar herunder.

Del også gerne artiklen med dine Facebook venner:  

Kommentarer (14)

User
Bruger #4832 @ 04.12.03 07:18
Flot aktikle om databasen til Delphi og
så med praktisk eksempel. FLOT

Med venlig hilsen
Monie Jacobsen
E-mail: energy@sunwind.dk
User
Bruger #4832 @ 16.12.03 17:19
Jeg ved ikke omdet er den rigtig vej at stille et spørgsmål.
Hvordan tilføjer man nye New Field.
Har allerede 4 Field.
Mvh
Monie Jacobsen
User
Bruger #4525 @ 17.12.03 21:22
Hehe nice artikel(får næsten løst til at starte på delphi)
User
Bruger #5252 @ 12.02.04 10:45
Tjek lige op på dit ADO. Det er nemlig ikke kun begrænset til Microsoft Produkter; men indeholder også drivere til både Oracle og andre almindeligt kendte produkter. Sørg for at have den nyeste MDAC installeret. Derudover mangler der lige en kommentar om at DBExpress ganske vist er Borlands nye svar på en Database Engine eller måske rettere Interface; men at det har været så fejlbehæftet i bla. Delphi 6 og Delphi 7, at det var nødvendigt stort set at skrive det om. Vær også opmærksom, at DBExpress returnerer Unidirectional datasets med mindre det foregår via Clientdataset. Og DBExpress understøtter forøvrigt MS SQL.
User
Bruger #123 @ 13.02.04 21:22
Til Bobby: Tak for updaten, jeg var ikke klar over præcis hvilke databaser ADO understøtter. Mht. DBExpress har jeg ingen praktisk erfaring med det, ud over ca. 5 minutters "leg". Jeg nævner som et alternativ til database håndtering. I det hele er der jo kun tale om en generel gennemgang af forskellige måder at anvende databaser på. Hovedformålet er jo MyBase, eller TClientDataSet. Men tak for pointerne.
User
Bruger #1870 @ 21.06.04 12:26
Jeg fåt denn fejl:

[Fatal Error] Required package 'Crystal' not found
User
Bruger #1870 @ 21.06.04 12:56
Jeg fåt denn fejl:

[Fatal Error] Required package 'Crystal' not found
User
Bruger #1870 @ 21.06.04 13:00
ups kom til at opdatere så den kom igen.
User
Bruger #123 @ 29.06.04 10:29
> [Fatal Error] Required package 'Crystal' not found.

Ja det beklager jeg. Du skal ind i Project Options og under Packages fanebladet fjerne hakket i "Build with runtime packages". Så burde det virke.
User
Bruger #1244 @ 14.09.04 10:39
Flot gennemgang, fortsæt venligst, og kom gerne ud i alle kroge af database-progarmmeringen. Det kunne være rart hvis du senere beskriver hvordan man eksporter/importer til CSV fil, samt brug af qrickraport eks.v.
User
Bruger #7877 @ 17.07.05 14:52
Er godt nok lang tid siden artiklen er skrevet,men er først faldet over den nu. Kan stadig ikke kører selvom jeg beder den om ikke at benytte runtime packages'ne...

File not found: 'Variant.dcu'

den besked får jeg når jeg prøver at compile og kører det.

A helping hand would be much appreciated ;-)

På forhånd tak.

/x-ile
User
Bruger #8254 @ 27.01.06 19:13
Hvor kan jeg hente Database component til Delphi 6 PE?
User
Bruger #9888 @ 26.04.06 23:46
Jeg syntes ikke at linket virker ?
User
Bruger #1244 @ 02.03.08 09:15
Det er en flot artikel du har skrevet! den er fyldestgørende for de fleste der er hjemmeprogramør.

Man skylder ligesom at udbrede kenskaben at der også findes mange andre 3. parts databaser på markedet. I den forbindelse skal opmærksomheden henledes på at de som oftes koster penge, men som oftes er virkilig gode og fleksible.

Jeg har i den tid jeg har programmeret Delphi været hæmmet af, at jeg ved brug af paradoks db skulle installere Borland Database Engine til den PC hvorpå programmet skulle afvikles. Hvis sikkerheden bare var strammet en lille smule, kunne dettte af og til give problemer. Jeg taler naturligvis her om NT4, Win 2000, XP og Vista.

En dag jeg søgte på nettet faldt jeg over et funltions-bibliotek fra firmaet "www.componentace.com". I deres produktoversigt har de bla. et VCL funktionsbibliotek med navnet "Absolute Database". Jeg downloadede en prøve og installerede denn, afprøvede den forskellige demoer der fulgte med. Jeg kunne konstatere at det var lige denne type database jeg havde brug for.

Kort beskrivelse.
Type: Enkeltfil database, lige som
f.eks. access.
Bytes per string field: 64.000 bytes
Bytes per BLOB field: 2 GB
Bytes per index: 64.000 bytes
UNIQUE indexes or
constraints per table: 30.000
Database size: 32 TB (dog afhængig af OS)
Identifier length
(in characters): 255
Locks per connection: 2.147.483.647
Columns per table: 65.000
Rows per table: 2.147.483.647
Tables per database: 2.147.483.647
Bytes per page: 65.536
Pages per database file: 2.147.483.647

Connections per database:
- Multiuser: Maksimun angives ved konfigu-
ration af databasen, op til
2.147.483.647

- Singleuser: 1

Records in transaction: 2.147.483.647
In-memory table size: 2.147.483.647 (dog afhængig af
ram)

Dette var lidt omkring databasens "fysiologiske" egenskaber.

Medfølgende er en rigtigt god Database Editor hvor databasen kan kreeres, lige somdet er meget let at oprette den i source.

Generelt må jeg udtrykke min tilfredshed med den lethed databasen er at arbejde med, Tillige fungere den fint med Quick Report samt FastReport.

Den er kompatibel fra Delphi:
Delphi 4 til Delphi 2007
C++ Builder 4 til C++ Builder 2007

jeg købte i sin tid licens til:
Absolute Database - Multi-User, Edition For Single Developer with Source Code.
Dette ef hensyn til at jeg er alene som programør, med udvikler til ferbruger. pris: $349.00

Nogle vil måske syntes at dette er meget at betale, men efterhånden som jeg udvikler mere og mere, Kan jeg indse at prisen er særdeles rimeligt.

Dette er efter min mening et funktionsbibliotek er kan anbefales.

Med venlig hilsen

Lars Christensen
Næstved
Du skal være logget ind for at skrive en kommentar.
t