Datenbankserver
Moderator: Moderatoren
-
- Rekursionen-Architekt
- Beiträge: 417
- Registriert: Mo, 17. Sep 2007 18:20
- Wohnort: Senftenberg
- Kontaktdaten:
Datenbankserver
Ich erstelle mit
oSrv1 := dsDbServer():new("DiffGS")
ein Server-Object.
Um Dbpack ausführen zu können, muss ich die Db aber exclusive öffnen und möglichst shared.
Wie macht man so was?
Außerdem hätte ich gern gewusst, wie man den Datentyp eines dssle() festlegt. D. h. bei mir sind alle Values "c". Ich brauche sie aber "n", also den Typ den ich eingebe. Wie kann man das tun?
oSrv1 := dsDbServer():new("DiffGS")
ein Server-Object.
Um Dbpack ausführen zu können, muss ich die Db aber exclusive öffnen und möglichst shared.
Wie macht man so was?
Außerdem hätte ich gern gewusst, wie man den Datentyp eines dssle() festlegt. D. h. bei mir sind alle Values "c". Ich brauche sie aber "n", also den Typ den ich eingebe. Wie kann man das tun?
- brandelh
- Foren-Moderator
- Beiträge: 15710
- Registriert: Mo, 23. Jan 2006 20:54
- Wohnort: Germersheim
- Hat sich bedankt: 73 Mal
- Danksagung erhalten: 38 Mal
- Kontaktdaten:
Hi,
um das Problem mit PACK (braucht zwingend exclusive) zu umgehen nutzen viele (ich auch) ein Satz recycling. Aber nicht mit set deleted on, denn das ist viel zu langsam, sondern über den Index:
Alle Felder eines 'gelöschten' Satzes werden blank gesetzt.
Der Index sortiert den an den Anfang.
Bei DBSEEK wird er immer übersprungen, nur bei Browsern muss man verhindern dass die leeren Sätze angezeigt werden. Z.B. durch Softseek auf chr(33).
Bevor nun ein append blank für neue Sätze gemacht wird, muss man erst mit GO TOP prüfen ob dort ein leerer Satz vorhanden ist ...
PS: zu Clipper Zeiten (oder bei DBFNTX) habe ich auch schon das Indexfeld mit chr(255) gefüllt, dann sind die leeren Sätze ganz hinten.
Die Abfrage do while ! eof() muss man dann ergänzen auf do while ! eof() .and. ! left(Indexfeld,1) = chr(255)
um das Problem mit PACK (braucht zwingend exclusive) zu umgehen nutzen viele (ich auch) ein Satz recycling. Aber nicht mit set deleted on, denn das ist viel zu langsam, sondern über den Index:
Alle Felder eines 'gelöschten' Satzes werden blank gesetzt.
Der Index sortiert den an den Anfang.
Bei DBSEEK wird er immer übersprungen, nur bei Browsern muss man verhindern dass die leeren Sätze angezeigt werden. Z.B. durch Softseek auf chr(33).
Bevor nun ein append blank für neue Sätze gemacht wird, muss man erst mit GO TOP prüfen ob dort ein leerer Satz vorhanden ist ...
PS: zu Clipper Zeiten (oder bei DBFNTX) habe ich auch schon das Indexfeld mit chr(255) gefüllt, dann sind die leeren Sätze ganz hinten.
Die Abfrage do while ! eof() muss man dann ergänzen auf do while ! eof() .and. ! left(Indexfeld,1) = chr(255)
Gruß
Hubert
Hubert
- Tom
- Der Entwickler von "Deep Thought"
- Beiträge: 9394
- Registriert: Do, 22. Sep 2005 23:11
- Wohnort: Berlin
- Hat sich bedankt: 105 Mal
- Danksagung erhalten: 364 Mal
- Kontaktdaten:
@Hubert: Ich mache das über Indexkonditionen:
Das wird beim logischen Löschen automatisch mitaktualisiert. Man muß also keine Felder umbefüllen oder ähnliches.
Code: Alles auswählen
INDEX ON nr to KDNR FOR !Deleted()
Herzlich,
Tom
Tom
-
- Rekursionen-Architekt
- Beiträge: 417
- Registriert: Mo, 17. Sep 2007 18:20
- Wohnort: Senftenberg
- Kontaktdaten:
Genau deswegen will ich ja wissen, wie man die Db nun exclusive öffnet. Auch weil die damit bearbeitete dbf weiterverwendet wird.brandelh hat geschrieben:Hi,
ich lösche die Feldinhalte aus Datenschutzgründen - auch wenn eigentlich kein Anwender an die Serverdatei ran kommt.
Von der Handhabung ist die Indexvariante aber sicher die einfachste Art.
- Tom
- Der Entwickler von "Deep Thought"
- Beiträge: 9394
- Registriert: Do, 22. Sep 2005 23:11
- Wohnort: Berlin
- Hat sich bedankt: 105 Mal
- Danksagung erhalten: 364 Mal
- Kontaktdaten:
Hallo, Stevie.
Du arbeitest mit XClass++. Ich habe mir gerade mal die Doku runtergeladen. Um eine Tabelle exclusiv zu öffnen, müßtest Du das Serverobjekt mit OpenDbServer erzeugen:
Also:
für exclusives Öffnen.
Eigentlich gehört dieser Thread nach "3rd Party".
Du arbeitest mit XClass++. Ich habe mir gerade mal die Doku runtergeladen. Um eine Tabelle exclusiv zu öffnen, müßtest Du das Serverobjekt mit OpenDbServer erzeugen:
Code: Alles auswählen
Syntax: OpenDbServer(uFile, [lAutoIndex], [lShared], [lReadonly], [cDbe], [lMsg], [uSession], [cAlias])
Code: Alles auswählen
oSrv1 := OpenDbServer("DiffGS",,.F.)
Eigentlich gehört dieser Thread nach "3rd Party".
Herzlich,
Tom
Tom
- Rolf Ramacher
- Der Entwickler von "Deep Thought"
- Beiträge: 1931
- Registriert: Do, 09. Nov 2006 10:33
- Wohnort: Bergheim
- Danksagung erhalten: 3 Mal
- Kontaktdaten:
Hi Stevie,
hier ein Auszug aus meinem code, wie ich die Datenbanken packe.
aDb:=Directory("*.dbf")
oDlg := XbpDialog():new( AppDesktop(), , {150,300}, {300,200}, , .F.)
oDlg:taskList := .T.
oDlg:title :="Datenbanken werden gepackt"
oDlg:create()
drawingArea := oDlg:drawingArea
drawingArea:setFontCompoundName( "9.Arial" )
oStatic := XbpStatic():new( oDlg,, {50, 50}, {150, 30} )
oStatic:options := XBPSTATIC_TEXT_CENTER
oStatic:caption := ""
oStatic:Create()
oDlg:show()
SetAppFocus(oDlg)
For i = 1 to Len(aDb)
cAltFile:=""
cFile:=aDb[1]
nPos:=At(".",cFile)
cDb:=substr(cFile,1,nPos-1)
If Val(cDb)>0
cAltFile:=cDb
cDb:="A"+cAltFile
FRename(cAltFile+".dbf",cDb+".dbf")
EndIf
oStatic:setcaption(cDB)
If Netz_Use((cDb),.t.,"Zugiff")
(cDB)->(DbPack())
Close (cDb)
If !empty(cAltFile)
FRename(cDb+".dbf",cAltFile+".dbf")
EndIf
EndIf
Sleep(001)
Next i
oDlg:destroy()
msgbox("Die Datenbanken wurden bereinigt!","Programmhinweis")
Return Nil
p.s. die Abfrage mit Val() habe ich deshalb, um Datenbanken abzufangen,
die einen numerischen Namen haben.
hier ein Auszug aus meinem code, wie ich die Datenbanken packe.
aDb:=Directory("*.dbf")
oDlg := XbpDialog():new( AppDesktop(), , {150,300}, {300,200}, , .F.)
oDlg:taskList := .T.
oDlg:title :="Datenbanken werden gepackt"
oDlg:create()
drawingArea := oDlg:drawingArea
drawingArea:setFontCompoundName( "9.Arial" )
oStatic := XbpStatic():new( oDlg,, {50, 50}, {150, 30} )
oStatic:options := XBPSTATIC_TEXT_CENTER
oStatic:caption := ""
oStatic:Create()
oDlg:show()
SetAppFocus(oDlg)
For i = 1 to Len(aDb)
cAltFile:=""
cFile:=aDb[1]
nPos:=At(".",cFile)
cDb:=substr(cFile,1,nPos-1)
If Val(cDb)>0
cAltFile:=cDb
cDb:="A"+cAltFile
FRename(cAltFile+".dbf",cDb+".dbf")
EndIf
oStatic:setcaption(cDB)
If Netz_Use((cDb),.t.,"Zugiff")
(cDB)->(DbPack())
Close (cDb)
If !empty(cAltFile)
FRename(cDb+".dbf",cAltFile+".dbf")
EndIf
EndIf
Sleep(001)
Next i
oDlg:destroy()
msgbox("Die Datenbanken wurden bereinigt!","Programmhinweis")
Return Nil
p.s. die Abfrage mit Val() habe ich deshalb, um Datenbanken abzufangen,
die einen numerischen Namen haben.
- brandelh
- Foren-Moderator
- Beiträge: 15710
- Registriert: Mo, 23. Jan 2006 20:54
- Wohnort: Germersheim
- Hat sich bedankt: 73 Mal
- Danksagung erhalten: 38 Mal
- Kontaktdaten:
Hallo,
eventuell verstehen wir uns ja auch falsch.
Wenn man verhindern will, dass eine SHARED geöffnete Datei geändert wird während eine Operation abläuft (PACK geht da nicht !), kann man auch die gesamte DBF im Zugriff SPERREN mit FLOCK() geöffnet ist sie immer noch SHARED und andere können sie geöffnet haben aber man kann z.B. Summen berechnen oder mehrere Felder replacen ...
eventuell verstehen wir uns ja auch falsch.
Wenn man verhindern will, dass eine SHARED geöffnete Datei geändert wird während eine Operation abläuft (PACK geht da nicht !), kann man auch die gesamte DBF im Zugriff SPERREN mit FLOCK() geöffnet ist sie immer noch SHARED und andere können sie geöffnet haben aber man kann z.B. Summen berechnen oder mehrere Felder replacen ...
Gruß
Hubert
Hubert