Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

[newBe] Standardwerte in Datenfeldern

49 views
Skip to first unread message

Jens

unread,
Jun 30, 2004, 10:54:26 AM6/30/04
to
Hallo NG,

ich fange grade erst an mit ADO.NET, also bitte nicht steinigen wenn die Frage zu blöd ist.

Ich habe in einer SQL-Server DB eine GUID als Primary Key. Der Standardwert ist newid().
Auf diese Tabelle greife ich mit einem Dataset via sqlConnection und sqlDataAdapter zu.
Das select-command enthält alle Felder.
Wenn ich nun einen neuen Satz erzeuge kommt die Meldung "Spalte id läßt keine nullen zu".
Offensichtlich wird also null in den Record geschrieben.
Datenbankseitig ist das ja so geregelt:
keine Eingabe und Standardwert -> Feld = Standardwert
Eingabe von null und Standardwert -> Fehler
Ich kann natürlich programmseitig eine GUID erzeugen und in den Record schreiben aber dass
müsste ich ja dann wahrscheinlich für alle not null-Felder machen die einen Standardwert haben.

Wie kriege ich meinen DataAdapter dazu das Feld zu ignorieren oder den Standardwert zu übernehmen?

Danke schon mal
Jens


Peter Fleischer

unread,
Jun 30, 2004, 12:01:12 PM6/30/04
to
Jens wrote:
...

> Wie kriege ich meinen DataAdapter dazu das Feld zu ignorieren oder
> den Standardwert zu übernehmen?

Jens,
wenn du die DefaultValue-Eigenschaft der Spaltendefinition in der DataTable
mit einem Wert belegst, wird dieser bei jedem neuen Datensatz eingetragen.

Peter

Jens

unread,
Jul 1, 2004, 2:56:31 AM7/1/04
to
Peter,

Danke erstmal für den Responds.

Ich will da nochmal nachhaken :-)

Wenn ich einen Standardwert im DataTable setze kann das nachdem was ich bisher gesehen habe nur eine Konstante sein. Z.B. habe ich einen varchar und weise dem als default "" zu. Das Verfahren ist soweit ok, obwohl der default eigentlich auch aus der Datenbank übernommen werden könnte. Wenn ich eine GUID habe oder einen TimeStamp sieht das schon anders aus, vor allem dann wenn die Werte wirlich von der Datenbank gesetzt werden sollen (z.B. verwendet ein TimeStamp oft eine koordinierte Zeitzone wie UTC wenn die Daten aus unterschiedlichen Zeitzonen kommen)
Bei der Erstellung eines DataAdapters mit dem Vizard gibt es unter den erweiterten SQL-Generierungsoptionen eine Checkbox DataSet aktualisieren. Diese hat den Beschreibungstext
"Fügt eine SELECT-Anweisung ... hinzu um Identitätsspalten-,Standard- und andere Werte abzurufen die von der Datenbank berechnet werden."
Das verstehe ich so, dass ich bestimmte Werte eben nicht setze, den Record der Datenbank vorwerfe und mir das bereinigte Ergebnis direkt per SELECT-Statement zurückhole.
Wenn ich sowas in einer Parent-Child Beziehung mit einem Schlüsselfeld mache (z.B. eben aut. Generierung einer GUID) würde das ja vorraussetzen, dass ich den Datensatz sofort wegschreiben muss damit die Struktur stimmt. Was ja wiederum bedeuten würde, dass der Ansatz mit verbindungslosen Daten hier nicht hinhaut. Ich glaube ich habe da was noch nicht verstanden :-/

Kann mir jemand auf die Sprünge helfen?

Gruss Jens

Peter Fleischer

unread,
Jul 1, 2004, 5:49:53 AM7/1/04
to
Jens wrote:
...

> Wenn ich einen Standardwert im DataTable setze kann das nachdem was
> ich bisher gesehen habe nur eine Konstante sein.

Jens,
der DefaultValue-Eigenschaft ist ein Objekt zuzuweisen! Was das Objekt als
Default-Property zurückgibt, ist entscheiden, z.B. bei Now die aktuelle Zeit
(incl. Datum).

> Z.B. habe ich einen
> varchar und weise dem als default "" zu. Das Verfahren ist soweit ok,
> obwohl der default eigentlich auch aus der Datenbank übernommen
> werden könnte.

In der Datenbank stehen aber keine dotNET-Objekte. In manchen Datenbanken
gibt es einen Defaultwert überhaupt nicht (z.B. dBase).

> Wenn ich eine GUID habe oder einen TimeStamp sieht das
> schon anders aus, vor allem dann wenn die Werte wirlich von der
> Datenbank gesetzt werden sollen (z.B. verwendet ein TimeStamp oft
> eine koordinierte Zeitzone wie UTC wenn die Daten aus
> unterschiedlichen Zeitzonen kommen)

Deshalb werden diese Felder ja vom Datenbankserver gesetzt. Du brauchst dich
darum überhaupt nicht zu kümmern. Lediglich in Beziehungen solltest du dir
nach OnRowUpdated den vom Datenabkserver vergebenen Wert holen.

> Bei der Erstellung eines DataAdapters mit dem Vizard gibt es unter
> den erweiterten SQL-Generierungsoptionen eine Checkbox DataSet
> aktualisieren. Diese hat den Beschreibungstext
> "Fügt eine SELECT-Anweisung ... hinzu um Identitätsspalten-,Standard-
> und andere Werte abzurufen die von der Datenbank berechnet werden."

Das wird genau im OnRowUpdated gelesen, nachdem Insert abgesetzt wurde.

> Das verstehe ich so, dass ich bestimmte Werte eben nicht setze, den
> Record der Datenbank vorwerfe und mir das bereinigte Ergebnis direkt
> per SELECT-Statement zurückhole.

Genau so ist es.

> Wenn ich sowas in einer Parent-Child Beziehung mit einem
> Schlüsselfeld mache (z.B. eben aut. Generierung einer GUID) würde das
> ja vorraussetzen, dass ich den Datensatz sofort wegschreiben muss
> damit die Struktur stimmt.

Warum sofort? Du musst lediglich eine Beziehung im Client aufbauen. Sobald
ein Master-Datensatz eingefügt wird, wird im OnRowUpdated der vergebene PK
zurückgelesen und als FK in die in Beziehung stehenden Detail-Datensätze
eingetragen. Und das wird für jeden neu hinzugefügten Master-Datensatz
ausgeführt.

> Was ja wiederum bedeuten würde, dass der
> Ansatz mit verbindungslosen Daten hier nicht hinhaut. Ich glaube ich
> habe da was noch nicht verstanden :-/

Das glaube ich auch:-)

Peter

Jens

unread,
Jul 2, 2004, 5:28:39 AM7/2/04
to
Peter,

soweit alles ok.

Ich kriege das mit den Default-Werten ab ernicht gebacken.

> > Wenn ich eine GUID habe oder einen TimeStamp sieht das
> > schon anders aus, vor allem dann wenn die Werte wirlich von der
> > Datenbank gesetzt werden sollen (z.B. verwendet ein TimeStamp oft
> > eine koordinierte Zeitzone wie UTC wenn die Daten aus
> > unterschiedlichen Zeitzonen kommen)
>
> Deshalb werden diese Felder ja vom Datenbankserver gesetzt. Du brauchst
> dich
> darum überhaupt nicht zu kümmern. Lediglich in Beziehungen solltest du dir
> nach OnRowUpdated den vom Datenabkserver vergebenen Wert holen.

Mal ganz einfach:

SQL-Server DB mit 1 Tabelle sagen wir mal Table
2 Felder
- id GUID NOT NULL DEFAULT new(id) PRIMARY KEY
- name varchar(50) DEFAULT ""

sqlDataAdapter mit SELECT * FROM Table, UPDATE und INSERT Standard

DataSet mit 1 Table gefüllt von sqlDataAdapter

DataGrid mit DataSource DataSet.Table und AllowAddNew

Ich gebe in den neuen Datensatz einen Namen ein. Das Feld id bleibt leer. Wenn ich diesen Satz verlassen will kommt (völlig berechtigt) "Spalte id akzeptiert keine Nullen"

Wie bekomme ich eine von der Datenbank erzeugte GUID in das Feld?

Jens

Peter Fleischer

unread,
Jul 2, 2004, 6:27:35 AM7/2/04
to
Jens wrote:
...

> Ich kriege das mit den Default-Werten ab ernicht gebacken.

Jens,
du kannst die DefaultValue beispielsweise so setzen:

myDataSet.Tables("Tab1").Columns("Feld3").DefaultValue = "leer"
myDataSet.Tables("Tab1").Columns("Datum").DefaultValue = Now

>>> Wenn ich eine GUID habe oder einen TimeStamp sieht das
>>> schon anders aus, vor allem dann wenn die Werte wirlich von der
>>> Datenbank gesetzt werden sollen (z.B. verwendet ein TimeStamp oft
>>> eine koordinierte Zeitzone wie UTC wenn die Daten aus
>>> unterschiedlichen Zeitzonen kommen)
>>
>> Deshalb werden diese Felder ja vom Datenbankserver gesetzt. Du
>> brauchst dich
>> darum überhaupt nicht zu kümmern. Lediglich in Beziehungen solltest
>> du dir nach OnRowUpdated den vom Datenabkserver vergebenen Wert
>> holen.
>
> Mal ganz einfach:
>
> SQL-Server DB mit 1 Tabelle sagen wir mal Table
> 2 Felder
> - id GUID NOT NULL DEFAULT new(id) PRIMARY KEY
> - name varchar(50) DEFAULT ""
>
> sqlDataAdapter mit SELECT * FROM Table, UPDATE und INSERT Standard
>
> DataSet mit 1 Table gefüllt von sqlDataAdapter
>
> DataGrid mit DataSource DataSet.Table und AllowAddNew
>
> Ich gebe in den neuen Datensatz einen Namen ein. Das Feld id bleibt
> leer.
> Wenn ich diesen Satz verlassen will kommt (völlig berechtigt)
> "Spalte id akzeptiert keine Nullen"

Genau deshalb solltest du eine DefaultValue setzen, womit du erst einmal das
Feld bei der Neuanlage ohne Bedienereingriff belegst. Im nächsten Schritt
musst du nach dem Hinzufügen eines Datensatzes die GUID aktualisieren, da
sonst alle neuen Datensätze die gleiche GUID aus der DefaultValue erhalten
würden. Nach dem Update mit der Datenbank musst du dann im letzten Schritt
dir bei Bedarf die endgültig vom Datenbankserver vergebene GUID holen:


dadp.Fill(dtbl)
dtbl.Columns("ID").DefaultValue = Guid.NewGuid
AddHandler dtbl.RowChanged, AddressOf SetNewGuid
DataGrid1.DataSource = dtbl
...

Private Sub SetNewGuid(ByVal sender As Object, ByVal e As
DataRowChangeEventArgs)
If e.Action = DataRowAction.Add Then
e.Row("ID") = Guid.NewGuid
End If
End Sub

> Wie bekomme ich eine von der Datenbank erzeugte GUID in das Feld?

Da kann im OnRowUpdated-Ereignis die vergebene Guid aus der Identity
zurücklesen (bzw. beim SQL-Server Scope_Identity). Das ist möglich über
separates Select, ein nachgestelltes Select oder einen Output-Parameter oder
...

Peter

Peter

Jens

unread,
Jul 2, 2004, 7:32:45 AM7/2/04
to
Peter,

> Genau deshalb solltest du eine DefaultValue setzen, womit du erst einmal
> das
> Feld bei der Neuanlage ohne Bedienereingriff belegst.

was bedeutet erst einmal?
Wenn ich programmseitig einen Wert für das Feld festlege wird der auch in die DB geschrieben.
Der Standardwert kommt dabei nicht zur Anwendung.
*Der Standardwert wird nur verwendet wenn keine Eingabe für das Feld erfolgt.

> Im nächsten Schritt
> musst du nach dem Hinzufügen eines Datensatzes die GUID aktualisieren

wie? Die vom Programm eingetragene GUID bleibt bestehen (*)

> , da
> sonst alle neuen Datensätze die gleiche GUID aus der DefaultValue erhalten
> würden.

wieso, es wir doch immer eine neue GUID erzeugt

> Nach dem Update mit der Datenbank musst du dann im letzten Schritt
> dir bei Bedarf die endgültig vom Datenbankserver vergebene GUID holen:

was soll den Server denn dazu veranlassen die GUID endgültig zu vergeben? (*)

Peter Fleischer

unread,
Jul 2, 2004, 8:59:37 AM7/2/04
to
Jens wrote:
...

>> Genau deshalb solltest du eine DefaultValue setzen, womit du erst
>> einmal das
>> Feld bei der Neuanlage ohne Bedienereingriff belegst.
>
> was bedeutet erst einmal?

Jens,
üblicherweise sieht der Anwender die GIUD-Spalte nicht. Wenn jetzt eine neue
Datenzeile angelegt wird, wird die DefaulValue eingetragen. Damit läuft die
Neuanlage eines Datensatzes fehlerfrei.

> Wenn ich programmseitig einen Wert für das Feld festlege wird der
> auch in die DB geschrieben.

Das hängt von dem von dir genutzten CommandText ab.

> Der Standardwert kommt dabei nicht zur Anwendung.

Wie erzeugst du denn eine neue DataRow?

> *Der Standardwert wird nur verwendet wenn keine Eingabe für das Feld
> erfolgt.

Da du eine GUID nicht anzeigst und auch nicht durch den Anwender eingeben
lässt, dürfte letzte Aussage nicht zutreffend sein.

>> Im nächsten Schritt
>> musst du nach dem Hinzufügen eines Datensatzes die GUID aktualisieren
>
> wie? Die vom Programm eingetragene GUID bleibt bestehen (*)

Wie erzeugst du denn eine neue Datenzeile? Wozu noch Programmcode zum
Überwchreiben des Standardwertes?

>> , da
>> sonst alle neuen Datensätze die gleiche GUID aus der DefaultValue
>> erhalten würden.
>
> wieso, es wir doch immer eine neue GUID erzeugt

Wenn du einen Standardwert vorgibst, wird keine neue GUID erzeugt.

>> Nach dem Update mit der Datenbank musst du dann im letzten Schritt
>> dir bei Bedarf die endgültig vom Datenbankserver vergebene GUID
>> holen:
>
> was soll den Server denn dazu veranlassen die GUID endgültig zu
> vergeben? (*)

...

Wenn du mit INSERT einen neune Datensatz im Server erzeugst, kannst die das
GUID-Feld auslassen und die GUID durch den Server erzeugen lassen.

Peter

Jens

unread,
Jul 5, 2004, 6:53:54 AM7/5/04
to
Peter,

leider habe ich immer noch ein Problem.

Ich habe die Vorgehensweise so verstanden:

- das INSERT-Command des da wird so definiert, dass es das Feld id nicht enthält
(wenn das so stimmt, wäre das eine einfache Antwort auf meine erste Frage gewesen :-)
- in der DataTable werden alle Standardwerte vergeben, im Fall der Guid's Guid.NewGuid
- bei der Eingabe eines neuen Datensatzes wird bei RowChanged eine Guid erzeugt und eingetragen

Meine Commands sehen so aus:
SELECT id, name FROM tblEmployeesStaff

UPDATE tblEmployeesStaff SET id = @id, name = @name
WHERE (id = @Original_id) AND (name = @Original_name OR @Original_name IS NULL AND name IS NULL);
SELECT id, name FROM tblEmployeesStaff WHERE (id = @id)

INSERT INTO tblEmployeesStaff (name)
VALUES (@name);
SELECT id, name FROM tblEmployeesStaff

Im Datagrid sehe ich, dass die ID richtig gesetzt wird.
Die Update-Funktion (welche ich zum Testen auf das Schreiben der neuen Sätze reduziert habe) sieht so aus:

DataRow[] dr;

//new rows only
dr=ds.Tables["tblEmployeesStaff"].Select(null,null,DataViewRowState.Added);
sqlDataAdapter.Update(dr);

Beim Update bekomme ich Ausnahme des Typs 'System.Data.SqlClient.SqlException' in system.data.dll.
Zusätzliche Informationen: Systemfehler.

Was ist denn jetzt wieder falsch?

Gibt es irgendwo ein Beispiel, dass diese Situation beinhaltet?

Vielleicht noch was zu den Standardwerten. Ich reite da so ein bisschen drauf rum, weil wir vorhandene Datenbanken mit ADO.NET verwenden müssten, wenn wir denn umsteigen. Diese DB's enthalten oft einige hundert Tabellen mit insgesamt wohl einigen Tausend wenn nicht zehntausend Feldern. Fast alle Felder enthalten Standardwerte. Diese bestehen natürlich zum großen Teil aus Konstanten wie "" oder 0 aber auch as sp und udf. Wenn ich mir vorstelle, dass wir die ganze Logik auf die Datenadapter übertragen müssten...
Gibt es da wirklich keine Alternative?

Vielen Dank.
Gruss Jens

Peter Fleischer

unread,
Jul 5, 2004, 7:14:05 AM7/5/04
to
Jens wrote:
...

> leider habe ich immer noch ein Problem.

Jens,
du musst glücklich sein, dass nur noch EIN Problem hast:-) Ist das dein
fehlender Realname, den dir dein Eltern verheimlichen? :-)

> Ich habe die Vorgehensweise so verstanden:
>
> - das INSERT-Command des da wird so definiert, dass es das Feld id
> nicht enthält
> (wenn das so stimmt, wäre das eine einfache Antwort auf meine erste
> Frage gewesen :-)

Wenn du das so machst, dann muss der Datenbankserver die GUID erzeugen, was
beim SQL Server der Fall ist. Die vom Datenbankserver vergebene GUID musst
du dann natürlich zurücklesen, wenn darauf im Client Beziehungen aufbauen,
damit Fremdschlüsselwerte eingetragen werden können.

> - in der DataTable werden alle Standardwerte vergeben, im Fall der
> Guid's Guid.NewGuid

Genau, aber dieser Wert wird einmal eingestellt und alle neuen Datensätze
erhalten diesen gleichen Wert, weshalb dieser Wert nach dem Erzeugen einer
neuen DataRow zu überschreiben ist. Anderfalls gibt es bei der Neuanlage des
nächsten Datensatzes Konflikte.

> - bei der Eingabe eines neuen Datensatzes wird bei RowChanged eine
> Guid erzeugt und eingetragen
>
> Meine Commands sehen so aus:
> SELECT id, name FROM tblEmployeesStaff
>
> UPDATE tblEmployeesStaff SET id = @id, name = @name
> WHERE (id = @Original_id) AND (name = @Original_name OR
> @Original_name IS NULL AND name IS NULL);
> SELECT id, name FROM tblEmployeesStaff WHERE (id = @id)
>
> INSERT INTO tblEmployeesStaff (name)
> VALUES (@name);
> SELECT id, name FROM tblEmployeesStaff
>
> Im Datagrid sehe ich, dass die ID richtig gesetzt wird.
> Die Update-Funktion (welche ich zum Testen auf das Schreiben der
> neuen Sätze reduziert habe) sieht so aus:
>
> DataRow[] dr;
>
> //new rows only
>
>
dr=ds.Tables["tblEmployeesStaff"].Select(null,null,DataViewRowState.Added);
> sqlDataAdapter.Update(dr);
>
> Beim Update bekomme ich Ausnahme des Typs
> 'System.Data.SqlClient.SqlException' in system.data.dll.
> Zusätzliche Informationen: Systemfehler.

Und was weisen die Error-Objekte aus?

> Was ist denn jetzt wieder falsch?

Schreib mit die Information, die in den Error-Objekten (InnerException)
enthalten sit und man kann weiter sehen.

> Gibt es irgendwo ein Beispiel, dass diese Situation beinhaltet?

Beispiel wofür genau?

> Vielleicht noch was zu den Standardwerten. Ich reite da so ein
> bisschen drauf rum, weil wir vorhandene Datenbanken mit ADO.NET
> verwenden müssten, wenn wir denn umsteigen. Diese DB's enthalten oft
> einige hundert Tabellen mit insgesamt wohl einigen Tausend wenn nicht
> zehntausend Feldern. Fast alle Felder enthalten Standardwerte. Diese
> bestehen natürlich zum großen Teil aus Konstanten wie "" oder 0 aber
> auch as sp und udf. Wenn ich mir vorstelle, dass wir die ganze Logik
> auf die Datenadapter übertragen müssten...
> Gibt es da wirklich keine Alternative?

Wozu willst du denn diese sp und udf auf den Client übertragen? Der
Entwickler der Datenbank muss doch einen Grund haben, dass er diese
Funktionen nicht dem Client überlässt.

Die Konstanten als Standardwerte kannst du mit den entsprechenden Mitteln
aus der Datenbank auslesen und dann im Client setzen. Welche Probleme siehts
du denn da?

Peter

Jens

unread,
Jul 5, 2004, 7:42:02 AM7/5/04
to

> Jens,
> du musst glücklich sein, dass nur noch EIN Problem hast:-) Ist das dein
> fehlender Realname, den dir dein Eltern verheimlichen? :-)

Was soll dieser Schwachsinn? Wenn Du mir helfen möchtest bin ich dankbar, ansonsten antworte doch einfach nicht.

> > Beim Update bekomme ich Ausnahme des Typs
> > 'System.Data.SqlClient.SqlException' in system.data.dll.
> > Zusätzliche Informationen: Systemfehler.
>

Schuldigung, hier habe ich beim kopieren wohl was vergessen oder überschrieben.
Message:
"Der Wert NULL kann in die id-Spalte, ADOTest.dbo.tblEmployeesStaff-Tabelle, nicht eingefügt werden. Die Spalte lässt NULL-Werte nicht zu. Fehler bei INSERT."
Source:
Source
".Net SqlClient Data Provider"

Inner Exceptions sind nicht vorhanden.


Peter Fleischer

unread,
Jul 5, 2004, 7:52:29 AM7/5/04
to
Jens wrote:
>> Jens,
>> du musst glücklich sein, dass nur noch EIN Problem hast:-) Ist das
>> dein fehlender Realname, den dir dein Eltern verheimlichen? :-)
>
> Was soll dieser Schwachsinn? Wenn Du mir helfen möchtest bin ich
> dankbar, ansonsten antworte doch einfach nicht.

OK,
werde mich in Zukunft bei anonymen Postings zurückhalten.

Peter

Stefan Falz [MVP]

unread,
Jul 5, 2004, 7:51:01 AM7/5/04
to
Hallo Noname,

"Jens" schrieb:

> Was soll dieser Schwachsinn? Wenn Du mir helfen möchtest bin ich dankbar,
> ansonsten antworte doch einfach nicht.

Die Fragen, die du selbst stellst, kannst du dir aussuchen. Die Antworten
nicht. Wenn dir eine Antwort nicht gefällt, ignorier sie.

Was Peter dir sagen wollte, ist, dass die Angabe eines Vor- _und_ Zunamens
die Chance auf eine kompetente Antwort erhöht. Allerdings nützt das bei
solchen Antworten wie "Was soll dieser Schwachsinn?" auch nichts.

--
Tschau, Stefan
MS MVP für ASP / ASP.Net
http://aspnet.codebooks.de/ - Das ASP.Net Codebook (VB.Net)
http://asp.codebooks.de/ - Das ASP Codebook
http://www.aspfaq.de/ - Active Server Pages FAQ


Jens Götze

unread,
Jul 5, 2004, 8:17:39 AM7/5/04
to
Hallo Stefan,

warum sagt er das denn nicht. Ein kleiner Hinweis wie
"poste bitte unter Deinem vollen Namen" hätte genügt

> Jens,
> du musst glücklich sein, dass nur noch EIN Problem hast:-) Ist das dein
> fehlender Realname, den dir dein Eltern verheimlichen? :-)

Diesen Hinweis habe ich nicht verstanden.


Trotzdem Danke für die Mühe.
Jens Götze

Michael Mueller

unread,
Jul 6, 2004, 2:19:43 AM7/6/04
to
Ich denke mal was Jens eigentlich möchte ist folgende Funktionalität:

Wenn der User auf die "Hinzufügezeile" im DataGrid geht sollen automatisch
die Werte in dem Grid eingetragen werden die von der Datenbank als Standart
Wert vorgegeben werden.

Also im Prinzip so wie Access das macht.

Richtig Jens?

Gruß

Michael


Jens Götze

unread,
Jul 6, 2004, 3:12:02 AM7/6/04
to
Hallo Michael,

ja, genau so ist es.
Die Programme laufen bisher unter VS6 mit ADO und auch noch mit DAO.
Die Standardwerte der Datenfelder werden teilweise durch Konstanten vorbelegt,
teilweise aber auch durch sp und udf gefüllt (hier habe ich mich vorher wohl etwas unklar ausgedrückt)
Momentan machen wir das so, dass wir eine Art Minimalsatz erzeugen, der alle unbedingt
erforderlichen Werte enthält (z.B. eine sp die eine Erfassungsnummer aus einem globalen Nummernkreis ermittelt und Konstantenvorbelegungen)

Zur Sicherheit schreiben wir immer noch ein Kennzeichen (Standard ist dann 0), das gesetzt wird (z.B. auf 1) wenn der Anwender speichert.
Ansonsten gilt der Satz als "Erfassung abgebrochen" und wird reorganisiert.

Wir schreiben also diesen Minimalsatz, lesen ihn wieder zurück und der Anwender kann seine Daten eingeben.
Das hat den Vorteil, dass bereits wenn der Anwender den Satz das erste mal zu Gesicht bekommt
- dieser eindeutig ist
- er alle Anforderungen hinsichtlich der Datenintegrität erfüllt
aber auch den Nachteil dass wir alles sofort in die DB schreiben und immer nur einen Satz bearbeiten.

Wenn ich Peter richtig verstanden habe ist das bei ADO.NET im Grunde auch so und man regelt das über die unterschiedlichen Command-Texte.
Der Ansatz mit verknüpften verbindungsosen Resultsets gefällt mir an sich ganz gut. Aber wir müssten eben die Logik, die wir bisher mit der Datenbankfuktionalität implementieren (z.B. diese globalen Nummernkreise) in den DataTables zumindest zum Teil nachstellen
um mehrere Sätze verbindungslos zu erfassen. Ich will nicht die Geschäftslogik aus der Datenbank nehmen, die ist da gut aufgehoben(war wohl auch unklar)

Die Alternative besteht dann eben darin einen neuen Satz sofort auf die Datenbank loszulassen und
zurückzulesen wie wir das bisher machen (auch hier habe ich mich vorher unklar ausgedrückt)

Für mich ist die ganze Sache etwas schwierig. Ich muss Möglichkeiten finden wie wir in Zukunft unseren Datenbankzugriff gestalten ohne
praktische Erfahrung mit ADO.NET zu haben.

In der Hoffnung, dass ich die Situation jetzt etwas besser beschreiben konnte frage ich nochmal nach Literatur/Beispielen etc.
Sehr geholfen hat mir bisher das Beispiel von den DevDays2004. Wenn jemand noch etwas in dieser Art kennt... Danke!

Jens Götze

Michael Mueller

unread,
Jul 6, 2004, 7:44:51 AM7/6/04
to

"Jens Gtze" <JGoetze_sp...@spedifix.de> schrieb im Newsbeitrag
news:1001000040EA...@msnews.microsoft.com...

> ja, genau so ist es.

Also wenn du eine möglichkeit findest diese Standartwerte aus der
DB dem DataGrid zuzuführen dann gib mal laut bis jetzt hab ich
das immer per Hand eingestellt wie Peter weiter oben schon
beschrieben hat:

myDataSet.Tables("Tab1").Columns("Feld3").DefaultValue = "leer"
myDataSet.Tables("Tab1").Columns("Datum").DefaultValue = Now

Naja villeicht weiss Peter ja da auch mehr.
aber mit Postings ala "schwachsinn" nimmst du
einem Poster natürlich jegliche Lust weiter zu posten

Gruss

Michael


Peter Fleischer

unread,
Jul 6, 2004, 7:50:29 AM7/6/04
to

Michael,
und woher soll der "disconnect client" wissen, was die Datenbank mit einem
neuen Datensatz machen würde? Wenn man die Datenbank-Funktionalität im
Client haben will, muss sich das Programm entweder verbinden und die
Information im Ergebnis der Anlage eines neuen Datensatzes holen oder das
Programm muss die Funktionalitäten selbst ausführen, was zu einer
Implementation der im Datenbankserver hinterlegten Initialisierungsprogramme
im Client-Programm führt.

Access geht praktisch den ersten Weg. Es legt eine Datensatz an, füllt ihn
mit den Standardwerten und stellt ihn bereit. Nachfolgend kann das Programm
den neuen Datensatz bearbeiten und auch wieder löschen, was man bei der
Vergabe von Autowerten anhand der dabei entstehenden "Löcher" bemerken kann.
Diese "connected" Arbeitsweise kann man problemlos auch in ADO.NET
organisieren: INSERT mit anschließendem SELECT ID und nachfolgend Refresh
nur des Datensatzes mit der ID.

Der Vorteil von ADO.NET besteht aber in weiteren Möglichkeiten. So wird ein
neuer Datensatz erst als Instanz angelegt, ohne dass er in die
Rows-Auflistung eingefügt wird (Status "detached"). Erst mit Abschluss der
Datenerfassung braucht man den Datensatz hinzuzufügen (Status "added"). In
der Zwischenzeit kann man jederzeit den neuen Datensatz ohne Folgen
verwerfen. Man kann Datensätzänderungen "sammeln" und "im Packen" in die
Datenbank schreiben. Das war übrigens auch in ADO Classic mit
adLockBatchOptimistic so.

Peter

Jens Götze

unread,
Jul 6, 2004, 8:05:01 AM7/6/04
to
Mach ich. Zum Glück hab ich etwas Zeit zur Verfügung bekommen.
Mit dem Schwachsinn das ist mir so rausgerutscht.
In manchen Foren wirst Du wirklich blöd angemacht wenn Du keine Ahnung hast
und ich dachte das geht so in diese Richtung.
Ich wusste nicht, dass man hier Wert auf Namen legt und hab nicht verstanden was er von mir will.
Er hätte es ja einfach sagen können. Trotzdem Schuldigung Peter, war nicht so gemeint!
Wenn ich meinem Pferd die Hacken in die Seite haue und am Zügel reisse macht's auch einen Bocksprung :-)

Gruss Jens

-------- Original Message --------
Subject: Re: [newBe] Standardwerte in Datenfeldern (06-Jul-2004 13:44)
From: Michael Mueller <fris...@gmx.net>
To: microsoft.public.de.german.entwickler.dotnet.datenbank

Michael Mueller

unread,
Jul 6, 2004, 8:43:02 AM7/6/04
to

"Peter Fleischer" <peter.fleis...@gmx.de> schrieb im Newsbeitrag
news:2kvi0cF...@uni-berlin.de...

> und woher soll der "disconnect client" wissen, was die Datenbank mit einem
> neuen Datensatz machen würde?

Naja wenns nur sachen wie ne 0 oder ein Datum wäre könnte man das
ja theoretisch über DefaultValue einstellen.

Wüsste allerdings nicht wie man einen Standart Wert von der Datenbank
abrufen könnte
Pseudecode mässig würd ich so machen

foreach(xColumn DataColumn in Tables.Columns){
xColumn.DefaultValue = holDirDenDefaultWertAusderDatenBank;
}

ich hab schon öfter das verlangen nach den Default werten aus der DB gehabt
wenn dann musste ich es bis jetzt immer per Hand einstellen.

Gruss

Michael

Peter Fleischer

unread,
Jul 6, 2004, 10:07:36 AM7/6/04
to
Michael Mueller wrote:
...

> Wüsste allerdings nicht wie man einen Standart Wert von der Datenbank
> abrufen könnte

Michael,
dafür kenne ich eigentlich nur ADOX:-(

Peter

Jürgen Beck

unread,
Jul 6, 2004, 10:40:41 AM7/6/04
to
Jens wrote:
> Ich habe in einer SQL-Server DB eine GUID als Primary Key. Der
> Standardwert ist newid().
> [..]

> Wie kriege ich meinen DataAdapter dazu das Feld zu ignorieren oder den
> Standardwert zu übernehmen?

Hallo Jens,

mit der Stored Procedure "sp_columns" erhälst Du alle Metainformationen
aller Spalten oder einer Spalte einer Tabelle. Dabei steht in der Spalte
"COLUMN_DEF" der Standardwert.

Also bspw.:
///
sp_columns @table_name = 'Products'
\\\

--
Jürgen Beck
MCSD.NET, MCDBA, MCSE, MCT, MVP .NET
MCP CRM Application/Installation/Customization
www.Juergen-Beck.de

Michael Mueller

unread,
Jul 7, 2004, 2:11:31 AM7/7/04
to

"Jürgen Beck" <nospam2N...@Juergen-Beck.de> schrieb im Newsbeitrag
news:eoJfDd2...@TK2MSFTNGP09.phx.gbl...

Michael Mueller

unread,
Jul 7, 2004, 2:20:30 AM7/7/04
to

"Peter Fleischer" <peter.fleis...@gmx.de> schrieb im Newsbeitrag
news:2kvq1hF...@uni-berlin.de...

> Michael,
> dafür kenne ich eigentlich nur ADOX:-(

Das würd man wohl für jet Datenbanken nehmen hab hier nen news beitrag
gefunden
der beschäftigt sich mit dem selben Thema für sql server/msde:

http://groups.google.de/groups?hl=de&lr=&ie=UTF-8&threadm=On0XpRx2DHA.2460%40TK2MSFTNGP10.phx.gbl&rnum=1&prev=/groups%3Fq%3Ddotnet%2Bsp_columns%2BDefaultValue%26hl%3Dde%26lr%3D%26ie%3DUTF-8%26selm%3DOn0XpRx2DHA.2460%2540TK2MSFTNGP10.phx.gbl%26rnum%3D1

Der Entscheidene Post ist der hier:

Hi mdjhome,

Thank you for using MSDN Newsgroup! My name is Kevin, and I will be
assisting you on this issue.

First of all, I would like to confirm my understanding of your issue. From
your description, I understand that you cannot get the default value of the
column in the database table into the DataTable when using FillSchema
method. Have I fully understood you? If there is anything I misunderstood,
please feel free to let me know.

I've checked the MSDN document, and found that this issue is by design.
According to the document, the FillSchema method will only configures the
following five DataColumn properties if they exist at the data source.

1. AllowDBNull
2. AutoIncrement. You must set AutoIncrementStep and AutoIncrementSeed
separately.
3. MaxLength
4. ReadOnly
5. Unique

Please refer to the following link for more information.

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/
frlrfsystemdatacommondataadapterclassfillschematopic.asp

As default value is not listed here, I think you have to set it explicitly.
To get the default value from a SQL Server database, executing the
"sp_columns" stored procedure is a good idea. The default value is in the
COLUMN_DEF field of the result set. Please refer to the SQL Book Online for
more information.

If you're using an OleDbConnection, you can also use the
OleDbConnection.GetOleDbSchemaTable method to get the default value. Here's
an example:

Dim t As DataTable =
Me.OleDbConnection1.GetOleDbSchemaTable(OleDbSchemaGuid.Columns, _
New Object() {Nothing, Nothing, "Table11", Nothing})

The default value is in the COLUMN_DEFAULTcolumn. For more information
about GetOleDbSchemaTable method, please check the following link:

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/
frlrfsystemdataoledboledbconnectionclassgetoledbschematabletopic.asp

If anything is unclear, please feel free to reply to the post.

Kevin Yu
=======
"This posting is provided "AS IS" with no warranties, and confers no
rights."


Jens Götze

unread,
Jul 7, 2004, 2:25:44 AM7/7/04
to
Hallo Jürgen,

Donnerwetter, man lernt nie aus. Ich habe die sp_tables/sp_columns dauernd in
Benutzung um das Vorhandensein von Tabellen und Feldern zu überprüfen oder die Datentypen zu ermitteln.
Das da auch der default drinsteht ist mir völlig entgangen.
Ich habe mich bestimmt das letzte mal im SQL-Server6 mit den sys-sp's befasst.:-)

Ich denke damit können wir arbeiten.

Danke Jürgen

Peter Fleischer

unread,
Jul 7, 2004, 3:35:17 AM7/7/04
to
Jürgen Beck wrote:
...

> mit der Stored Procedure "sp_columns" erhälst Du alle
> Metainformationen aller Spalten oder einer Spalte einer Tabelle.
> Dabei steht in der Spalte "COLUMN_DEF" der Standardwert.
...

Jürgen,
Danke, man lernt nie aus:-)

Peter

0 new messages