Delphi ADO->Access record verwijderen lukt niet

Pagina: 1
Acties:
  • 317 views sinds 30-01-2008
  • Reageer

  • Rodyman
  • Registratie: November 2001
  • Laatst online: 08-06-2024
Ik heb een Delphi applicatie die gekoppeld is via een ADO-connectie met een Access Database.

Nu heb ik overzichtje in een TDBGrid staan en als daar een row geselecteerd is, kan er met een knop het betreffende record verwijderd worden, dit werkt allemaal met de volgende regel code onder de onlick van de verwijderknop:

ADODS_dataset.Delete;

Dus ik delete de row uit de dataset. In de DBGrid gaat hij nu ook netjes weg. Maar hij verwijderd hem niet uit de Access database. De volgende keer als ik de applicatie opstart zit de betreffende row er gewoon weer bij.

Hoe kan dit nou, omdat ik hem toch echt uit de dataset haal. Maar hij weigert het om hem uit die access database te halen. Moet ik nog iets van een 'update' uitvoeren zodat hij de veranderingen doorvoerd ofzoiets? Of heeft het iets met rechten te maken?

  • whoami
  • Registratie: December 2000
  • Laatst online: 09:19
Ik vermoed dat het een 'clientside' dataset is; je verwijderd de row dus wel uit de daatset, maar je zal die wijzigingen dan ook nog moeten doorgeven naar de database.

https://fgheysels.github.io/


  • Rodyman
  • Registratie: November 2001
  • Laatst online: 08-06-2024
en hoe geef je zoiets door aan de database dan? (ben redelijke delphi noob nog) ;)

Verwijderd

Ik ben 100% noob wat betreft Access, maar voor zover ik weet vindt ADO 't wel fijn wanneer je na een wijziging (insert/update/delete) ook nog een Post stuurt.

Tenminste bij TADOTables en TADOQueries met RequestLive aan. Heb ik me laten vertellen, ik gebruik ze beide nooit... :+

  • LordLarry
  • Registratie: Juli 2001
  • Niet online

LordLarry

Aut disce aut discede

Nee, Post wordt alleen gebruikt als je dataset in Edit mode staat. Een Delete zou meteen doorgevoerd moeten worden aan de database, tenzij ie op caching staat. Als je zo'n TADOConnection en TADOQuery/TADOTable voor het eerst op een form gooit staat ie niet op chache en zou het direct moeten werken. Werkt het nog niet goed als je er nieuwe componenten op zet en geen property veranderd (behalve de broodnodige)? Zit je misschien in een transactie?

We adore chaos because we like to restore order - M.C. Escher


Verwijderd

Indulge me, en laat Rodyman 't 's proberen?
Toen ik nog met filebased databases werkte (Clipper, FoxPro, Paradox) ben ik dit probleem meermaals tegengekomen. En wat je zegt is helemaal waar, maar klopt 't in de praktijk ook? Ik weet niet meer hoeveel Post en Flush commando's ik indertijd heb moeten tussenvoegen...

  • LordLarry
  • Registratie: Juli 2001
  • Niet online

LordLarry

Aut disce aut discede

Kijk maar in je DB.pas unit bij procedure TDataSet.Post; Er wordt alleen gepost als State dsInsert of dsEdit is en TDataSet.Delete zet geen van de States. Ook de help is duidelijk over TDataSet.Post:
TDataSet implements a virtual method to write a modified record to the database or change log.
Als je Post roept op een database die niet in insert of edit mode staat krijg je zelfs een exceptie. Bij een TClientDataSet moet je ApplyUpdates roepen, misschien ben je daar mee in de war?

We adore chaos because we like to restore order - M.C. Escher


  • FendtVario
  • Registratie: Januari 2002
  • Laatst online: 12-05-2025

FendtVario

The leader drives Vario!

Een exception bij het aanroepen van .Post? Kan ik me toch niet herinneren dat ik dat ooit meegemaakt hebt. Ligt misschien aan het type implementatie? Zal het morgen eens proberen, nu geen Delphi. Kan me wel herinneren dat BDE een exception gaf als je een veld probeerde te wijzigen en de dataset stond in edit mode. Zeos doet dit niet wat al eens voor vervelende situaties heeft gezorgd.

www.fendt.com | Nikon D7100 | PS5


  • Delphi32
  • Registratie: Juli 2001
  • Laatst online: 10-05 21:36

Delphi32

Heading for the gates of Eden

Ik heb in D5 en D2005 geen exception kunnen vinden in TDataSet.Post. Maar LL heeft verder wel gelijk: Post doet alleen wat als de dataset.state in dsEdit of dsInsert is.

Verwijderd

Hier maken we de TS niet blij mee, maar...
LordLarry schreef op maandag 07 maart 2005 @ 22:39:
Kijk maar in je DB.pas unit bij procedure TDataSet.Post; Er wordt alleen gepost als State dsInsert of dsEdit is en TDataSet.Delete zet geen van de States.
TDataSet.Delete roept de virtual method InternalDelete aan, en die moet worden geimplementeerd door de inherited classes. In het geval van ADO komt 'ie dan terecht in DoRecordsetDelete, en in mijn Delphi 6 source staat daar een klein commentje bij:
{ When CacheSize > 1, Recordset allows fetching of deleted records.
Calling MovePrevious seems to work around it }
Oftewel, vertrouw nooit blind op de VCL. De mensen bij Borland hebben soms ook workarounds nodig, net als gewone programmeurs. :)

  • FendtVario
  • Registratie: Januari 2002
  • Laatst online: 12-05-2025

FendtVario

The leader drives Vario!

Hum, in D7 staat dat commentaar er ook bij. De work-around is trouwens direct onder het commentaar geimplementeerd. Het zou dus wel moeten werken.

www.fendt.com | Nikon D7100 | PS5


  • Rodyman
  • Registratie: November 2001
  • Laatst online: 08-06-2024
Ok, ik zit nu op mijn werk, heb hier geen Delphi 2005, maar .Post na de delete heb ik al geprobeerd, en dat maakt niets uit.
Ik heb een TAdoDataset op het form staan waar de gegevens in staan. Geen TADOQuery of TADOTable, ik kan vanavond nog even proberen een nieuwe TADOTable er op te zetten en het daarmee te proberen.

  • Rodyman
  • Registratie: November 2001
  • Laatst online: 08-06-2024
Verwijderd schreef op dinsdag 08 maart 2005 @ 01:02:
Hier maken we de TS niet blij mee, maar...

[...]

TDataSet.Delete roept de virtual method InternalDelete aan, en die moet worden geimplementeerd door de inherited classes. In het geval van ADO komt 'ie dan terecht in DoRecordsetDelete, en in mijn Delphi 6 source staat daar een klein commentje bij:

[...]

Oftewel, vertrouw nooit blind op de VCL. De mensen bij Borland hebben soms ook workarounds nodig, net als gewone programmeurs. :)
Ok, dus met een moveprevious erna moet het werken, dit zal ik vanavond ook even proberen

Verwijderd

Die workaround werkt ook, maar het ging me meer om
Een Delete zou meteen doorgevoerd moeten worden aan de database
en dit was bedoeld als voorbeeldje dat "zou moeten" in de praktijk niet altijd het geval is.

Of bij het probleem van TS die Post helpt weet ik niet, maar ik weet wel dat oudere (Delphi 2) versies van bv. de Halcion en Advantage database drivers bij een Delete de recordset wel degelijk in editmode zetten, en er een daadwerkelijke Post (of Flush) nodig was.

Edit: Niet dus. Jammer, maar 't was het proberen waard... :)

[ Voor 9% gewijzigd door Verwijderd op 08-03-2005 09:59 ]


  • FendtVario
  • Registratie: Januari 2002
  • Laatst online: 12-05-2025

FendtVario

The leader drives Vario!

Ik las zit in de help-file van Delphi over TADODataSet
TADODataSet is not capable of issuing Data Manipulation Language (DML) SQL statements that do not return result sets (like DELETE, INSERT, and UPDATE). For this use a component like TADOCommand or TADOQuery.
Je kan dus geen records verwijderen met een TADODataSet.

www.fendt.com | Nikon D7100 | PS5


  • Rodyman
  • Registratie: November 2001
  • Laatst online: 08-06-2024
FendtVario schreef op dinsdag 08 maart 2005 @ 10:05:
Ik las zit in de help-file van Delphi over TADODataSet

[...]


Je kan dus geen records verwijderen met een TADODataSet.
AHA! Kijk daar zal het probleem zitten, ik ga het vanavond omzetten naar een TADOQuery! Ik laat weten of het gelukt is.
Alvast bedankt!

  • Rodyman
  • Registratie: November 2001
  • Laatst online: 08-06-2024
Ok, vraagje 2, ik heb nu zo'n TADOCommand erin zitten, maar hoe koppel ik die aan een TDBGrid? Omdat die TDBGrid alleen een datasource kan gebruiken als input, maar een datasource krijg ik weer niet gekoppeld aan die TADOCommand die ik gemaakt heb.

  • LordLarry
  • Registratie: Juli 2001
  • Niet online

LordLarry

Aut disce aut discede

Een TDBGrid koppel je idd aan een TDataSource. Een TDataSource op zijn beurt koppel je weer aan een TDataSet of afgeleide. In jouw geval dus een TADOQuery of een TADOTable. Die kan je weer koppelen aan je TADOCommand. De TADOCommand is alleen voor de connectie of het uitvoeren van een simpele query zonder resultaat.

We adore chaos because we like to restore order - M.C. Escher


  • Rodyman
  • Registratie: November 2001
  • Laatst online: 08-06-2024
LordLarry schreef op dinsdag 08 maart 2005 @ 21:13:
Een TDBGrid koppel je idd aan een TDataSource. Een TDataSource op zijn beurt koppel je weer aan een TDataSet of afgeleide. In jouw geval dus een TADOQuery of een TADOTable. Die kan je weer koppelen aan je TADOCommand. De TADOCommand is alleen voor de connectie of het uitvoeren van een simpele query zonder resultaat.
Ok, dat lukt me alleen niet, de koppeling tussen een TADODataSet en mijn TADOCommand, hoe moet ik die koppeling leggen?

Even de uitleg van mijn programma:

DBGrid haalt gegevens uit datasource die gekoppeld is aan ADODataSet.

ADODataset haalt gegevens rechtstreeks uit database.

Nu heb ik een verwijder knop. als daarop gedrukt is moet de geselecteerde record uit de DBGrid gedelete worden.

ADODataset.delete;
werkt niet, hoe moet ik zo'n ADOCommand dan koppelen aan deze dataset, ik zie nergens een mogelijkheid/property bij de ADODataSet en bij de ADOCommand.

  • LordLarry
  • Registratie: Juli 2001
  • Niet online

LordLarry

Aut disce aut discede

We waren er toch al over uit dat je geen TADODataSet moet gebruiken, maar een TADOQuery of TADOTable? Je kan een grid niet direct aan een TDataSet koppelen, dus ik neem aan dat je daar een TDataSource tussen hebt? Je moet geen TADOConnection koppelen aan een TADODataSet/Table/Query, je kan ook gewoon de ConnectionString property gebruiken. Het is alleen zonde om dat bij elk component weer opnieuw te doen, dus je kan het ook eenmalig in een TADOConnection doen en deze dan via de Connection (duh?) property aan een TADODataSet/Table/Query koppelen.

We adore chaos because we like to restore order - M.C. Escher


  • FendtVario
  • Registratie: Januari 2002
  • Laatst online: 12-05-2025

FendtVario

The leader drives Vario!

het koppelen van de data-componenten van connectie tot grid is erg basic werk, zoek eens een leuk tutorial of koop een boek. Een TADOCommand kun je niet rechtstreeks koppelen aan een TADODataSet. De ADOCommand kun je gebruiken voor queries die geen resultaten terugeven (bijv delete, insert of update). De SQL hiervoor kun je in de CommandText property zetten.

Is het in jouw geval niet makkelijker om een TADOTable of query te nemen? Dan kun je TADOTable.Delete gebruiken.

www.fendt.com | Nikon D7100 | PS5


  • Rodyman
  • Registratie: November 2001
  • Laatst online: 08-06-2024
Klopt, ik had helemaal niet gezien dat je een TADOTable of Query kon koppelen aan een datasource. stomstom, sorry voor deze wat noobische vraag! :)

Heel erg bedankt allemaal dus!

FendtVario, over boeken gesproken, heb jij nog bepaalde aanraders?

  • LordLarry
  • Registratie: Juli 2001
  • Niet online

LordLarry

Aut disce aut discede

We adore chaos because we like to restore order - M.C. Escher

Pagina: 1