Autor Beitrag
olliterski
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 105
Erhaltene Danke: 2

Win7 64-Bit
D7 Ent.
BeitragVerfasst: Do 20.02.03 16:37 
Hi,

ich habe auf einem Datenbankserver eine Dateenbank zu laufen! -> was sonst! 8)

In dieser Datenbank sind alle Primarykeys autoincrement. Wenn ich jetzt über eine TTable-Komponente einen Datensatz hinzufüge, meckert mich delphi an das der Wert nicht null sein darf. Das kann ich sogar verstehen, weil in der Datenbank steht das das feld nich NULL sein darf. Die Default_value für dieses Feld ist allerdings autoincrement. Das heißt die Datenbank trägt bei einem Insert automatisch eine Value ein!!!

Warum pubt mich Delphi also immernoch an, obwohl dieses Feld (Primary Key) von der Datenbank selber gefüllt wird???

Viele Grüße Oliver :evil:

_________________
Viele Grüße
Oliver
LCS
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1305
Erhaltene Danke: 1

WIN 7, WIN 8
Delphi XE5, Delphi XE, Delphi 2007
BeitragVerfasst: Fr 21.02.03 08:20 
Hi
das Feld wird zwar von der Datenbank gefüllt, aber Delphi weiss davon eben nix. Für Delphi ist das ein Primärschlüssel der gefüllt sein muss, bevor der neue Satz gepostet wird.
Wenn du in deiner Datenmenge mit persistenten Feldern arbeitest, setzt du einfach bei allen Keyfeldern mit AutoInc die Eigenschaft Required auf False. Ansonsten hilft:
ausblenden Quelltext
1:
Table1.FieldByName('DeinFeldName').Required := False;					


Gruss Lothar

_________________
Der BH ist für die Brust, der Plan ist für'n Ar...
kiwicht
ontopic starontopic starontopic starontopic starontopic starofftopic starofftopic starofftopic star
Beiträge: 1021

Win 7, MacOS
Delphi x, VBA, PHP, ...
BeitragVerfasst: Fr 21.02.03 09:37 
hi..

über das Problem hab ich mich auch schon geärgert, aber am Ende hab ich doch nachgegeben, und das AutoInc-Feld einfach selber gefüllt mit:

ausblenden Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
Query1.Last;

// SQL, so oder so ähnlich:
INSERT dbank SET nr = ' + (Query1.FieldByName('nr').AsInterger + 1)
// oder halt so, auf nummer sicher:
INSERT dbank SET nr = ' + (Query1.RecordCount + 1)

Query1.Open

(not tested yet, quasi aus´m stehgreif... ;) also nur als schema zu verstehen!)

mfg
kiwicht
olliterski Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 105
Erhaltene Danke: 2

Win7 64-Bit
D7 Ent.
BeitragVerfasst: Fr 21.02.03 17:24 
@LCS

...geht nicht!!! Hab ich zwar schon gestern probiert, wollte mich aber heute nochmal versichern das ich nix falsch gemacht habe.

Es geht wirklich nicht!! :(

@kiwicht

Bei ner Standalone DB wo nur ein User drauf zu greift mag das gehen. Aber die Folgen in einem Client-/Serversystem wären bei dieser Vorgehensweise verheerend!!! :shock:

Bsp: User1 greift auf eine Tabelle zu und will einen Datensatz zurückschreiben, genau wie User2.
User1 holt sich als MaxWert 14 aus der ID-Column und addiert 1 hinzu. Sein Datensatz hätte somit die ID 15. User2 holt sich ebenfalls den MaxWert für die ID, ebenfalls 14 und addiert 1 hinzu. User1 schreibt seinen Datensatz in die Datenbank mit der ID 15. User2 kommt 0,05 Sekunden später an und will seinen Datensatz in die Datenbank schreiben, ebenfalls ID 15. :wink:

Ich garantiere Dir, das die Datenbank User2 mit dem nackten Hintern ins Gesicht springt wenn er das versucht! Primary Keys sind Unique!!! :twisted:

Ganz unter uns, ich weiß ich schweife jetzt vom Thema ab, aber ich find´s blöd das sich 3Mio. Leute die Threads durchlesen, aber selten antworten.

Trotzdem erstmal danke, das ihr euch die Zeit dafür genommen habt!

Wenn euch nochwas einfallen sollte - ich bin ganz Ohr...! 8)

Viele Grüße

Oliver

_________________
Viele Grüße
Oliver
DaDoc
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 27

Win 2000, Linux
D2005 Prof
BeitragVerfasst: Mo 24.02.03 12:45 
Am sichersten wäre es, den Datensatz durch folgenden SQL-Befehl einzufügen:
ausblenden Quelltext
1:
insert into dba.TableName(FieldName2, FieldName3,...) values(FieldValue2, FieldName3, ...);					

wobei Du bei der Feldaufzählung und bei den Wertezuweisungen einfach das ID-Feld (AutoIncrement) wegläßt. Der Server wirds danach für Dich ausfüllen. Einfach mal mit dem DBExplorer checken. Und mit:select @@identity bekommst Du den den Zuletzt erzeugten Incrementalwert heraus. Aber Vorsicht: Wenn viele schnelle "Inserts" von verschiedenen Usern durchgeführt werden, kannst Du es schon mal haben, daß Du den ID-Wert eines "fremden" Inserts bekommst (s.o.).

Sven
kiwicht
ontopic starontopic starontopic starontopic starontopic starofftopic starofftopic starofftopic star
Beiträge: 1021

Win 7, MacOS
Delphi x, VBA, PHP, ...
BeitragVerfasst: Di 25.02.03 16:21 
olliterski hat folgendes geschrieben:
@LCS
Bei ner Standalone DB wo nur ein User drauf zu greift mag das gehen. Aber die Folgen in einem Client-/Serversystem wären bei dieser Vorgehensweise verheerend!!! :shock:
[...]


naja, in solch einem Fall geb ich dir natürlich recht. Deswegen läuft das bei mir (in meinem DB-Prog) ja auch so ab, um genau diesen Fall zu verhindern:

1. User sagt: Ich will neuen Datensatz
2. Programm öffnet Table nochmal NEU (!), liest RecordCount, addiert 1
und speichert SOFORT leeren Datensatz mit neuem RecordCount
3. User gibt neue Daten ein, Programm kann diese anhand der vorher
festgelegten ID richtig speichern ...... ODER:
4. User will doch nicht mehr: GIBT ES NICHT! Denn: Ente oder Trente!

Zugegeben, die Methode ist MEHR als stümperhaft und notdürftig, aber hier bei uns, wo nur etwa 20 Rechner stehen, dürfte dein Fall in einer Millionen Jahre nicht vorkommen.
Und durch diese Methode spar ich mir irgendwelche Huddelein mit einem extra DB-Server, der die Sache zwar übernehmen könnte, aber bei dem ich die alten DBaseIII+-Dateien nicht mehr nutzen könnte.. von daher...

Aber ich denke, man sollte einfach zwischen den gebotenen Möglichkeiten wählen. In einer RiesenFirma würd ich natürlich nicht so handeln wie jetzt... aber viele andere Möglichkeiten gibts glaub ich auch garnicht... except DaDoc´s Solution... ;)

idS mfG
kiwicht
olliterski Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 105
Erhaltene Danke: 2

Win7 64-Bit
D7 Ent.
BeitragVerfasst: Di 25.02.03 19:45 
Hi,

tja, es scheint wirklich nur mit nem Insert zu funzen! Schade auch!

Man könnte es aber auch anders lösen:

Eine Tabelle (TableName char50, ColName char50, Value Integer) und keine einzige Tabelle mit einem Autoincrement. Dafür wird für jede ID eine StoredProc aufgerufen der TableName und ColName übergeben werden. Der Returnwert wäre dann eine Value für das Feld ID.
Die StoredProc würde zu TableName und ColName die höchste Value auslesen und mit einem Update um eins erhöhen und diesen erhöhten Wert wieder zurückgeben.

Da eine StoredProc auf einem Server die Tabelle erst wieder für andere Zugriffe freigibt, wenn sie abgearbeitet ist, dürfte das sogar in großen Unternehmen eine passable Vorgehensweise sein. Womit ich nicht sagen möchte das deine Vorgehensweise stümperhaft ist, aber sie ist dennoch unsicher! Wenn denn dann mal der Fall, der alle zig-Millionen Jahre auftreten kann, auftritt, was übrigens auch schon morgen sein kann, hast du denke ich mal ein Problem!

Ich würde nur gerne wissen wie die das bei Powerbuilder geschafft haben. Die arbeiten ja auch mit den von Gates gegebenen Komponenten - wie Delphi!

Wenn ich da aber ein Datawindow erstelle, weiß er automatisch, das ich die ID nicht angeben muss weil sie persistent ist!!

Da stellt sich allerdings die Frage nach der Daseinsberechtigung einer TTable-Komponente!!!!

Wozu überhaupt noch das Teil verwenden???

Ich meine jeder Programmierer ist darum bemüht (sollte eigentlich!!!) seinen Code sauber zu halten und überflüssigen Balast zu entfernen!
Gibt es da bei Borland vielleicht Faulpelze?

Viele Grüße

Oliver

_________________
Viele Grüße
Oliver
kiwicht
ontopic starontopic starontopic starontopic starontopic starofftopic starofftopic starofftopic star
Beiträge: 1021

Win 7, MacOS
Delphi x, VBA, PHP, ...
BeitragVerfasst: Mi 26.02.03 00:02 
Zitat:

Da eine StoredProc auf einem Server die Tabelle erst wieder für andere Zugriffe freigibt, wenn sie abgearbeitet ist, dürfte das sogar in großen Unternehmen eine passable Vorgehensweise sein. Womit ich nicht sagen möchte das deine Vorgehensweise stümperhaft ist, aber sie ist dennoch unsicher! Wenn denn dann mal der Fall, der alle zig-Millionen Jahre auftreten kann, auftritt, was übrigens auch schon morgen sein kann, hast du denke ich mal ein Problem!


naja, zugegeben! mir ist durchaus bewusst, das die ganze Geschichte etwas auf wackligen Beinen steht, bzw. stehen könnte. Aber in Abwägung mit der Anschaffung eines Extra SQL-Servers, war das einfach die "besser" Wahl.

Zitat:

Wozu überhaupt noch das Teil verwenden???


|mfG.

kiwicht