Laden...

Addieren eines Dezimalwertes zum bestehenden Wert

Erstellt von NoLimit vor 13 Jahren Letzter Beitrag vor 13 Jahren 16.321 Views
N
NoLimit Themenstarter:in
191 Beiträge seit 2007
vor 13 Jahren
Addieren eines Dezimalwertes zum bestehenden Wert

verwendetes Datenbanksystem: <MS SQL 2008>

Hallo

Ich möchte in einer Datenbank zu einem schon bestehenden Dezimalwert einen neuen immer dazuaddieren.
Gibt´s dafür evtl. eine Möglichkeit dies per ComputedColumnSpecification schon auf dem SQL-Server zu erledigen, oder muss ich tatsächlich erst den bestehenden Wert auslesen, die Summe mit dem neuen Wert bilden, und das Resultat wieder zurückschreiben?

"If you give someone a
program, you will frustrate them
for a day; if you teach them how to
program, you will frustrate them
for a lifetime." :evil:

P
66 Beiträge seit 2009
vor 13 Jahren

Kannst du das nicht über ein Update-Statement machen?

Also zum Beispiel: UPDATE table SET value = value + x;

Hab bisher eher mit MySQL gearbeitet, aber müsste doch bei MSSQL auch so funktionieren, oder?

...

N
NoLimit Themenstarter:in
191 Beiträge seit 2007
vor 13 Jahren

Das würde sicher gehen. Es gibt wohl eine ganze Anzahl von Lösungen hierfür.
Ich wollte lediglich wissen ob der Server diese Berechnung nicht selbst ausführen kann. Also ähnlich wie getdate() bei dem er ja auch das Datum selbst einträgt.

"If you give someone a
program, you will frustrate them
for a day; if you teach them how to
program, you will frustrate them
for a lifetime." :evil:

S
18 Beiträge seit 2010
vor 13 Jahren

Die Frage klingt leicht strange... getdate gibt das aktuelle Datum zurück. Für eine Addition brauchst du mindestens (außer dem Wert der schon in der Tabelle ist) einen weiteren Wert. Den musst du dem Server schon irgendwie mitteilen.

Des weiteren gibt getdate() einen Wert zurück, einen Wert zu aktualisieren ist eine völlig andere Tätigkeit.

Bitte beschreibe doch einmal etwas genauer, was du eigentlcih wissen willst. Danke!

N
NoLimit Themenstarter:in
191 Beiträge seit 2007
vor 13 Jahren

Was ist Strange daran?
Wenn ich getdate() als ComputedColumnSpecification eintrage dann schreibt er mir für jede neue Zeile das Datum an die entsprechende Stelle. Genauso wie ich z.B. die ID inkrementieren lassen kann.

Und natürlich möchte ich ihm einen neuen Wert vorgeben, aber die eigentliche Addition möchte ich eben auf der SQL-Seite haben, und nicht im Code des C# Programms.

"If you give someone a
program, you will frustrate them
for a day; if you teach them how to
program, you will frustrate them
for a lifetime." :evil:

731 Beiträge seit 2006
vor 13 Jahren

Wenn Du von Addition sprichst, gehe ich davon aus, dass Du einen vorhandenen Datensatz aktualisieren möchtest und innerhalb der betroffenen Tabelle gibt es eine Spalte, deren Wert sich nun folgendermaßen ergibt: "neuer Wert" = "alter Wert" + "Konstante", richtig?

MfG
wax

N
NoLimit Themenstarter:in
191 Beiträge seit 2007
vor 13 Jahren

Fast.

In einer Spalte, nennen wir sie "Summe", steht '5'. Nun teile ich dem SQL einen neuen Wert '4' mit. Er soll nun die '5' durch eine '9' ersetzen.

"If you give someone a
program, you will frustrate them
for a day; if you teach them how to
program, you will frustrate them
for a lifetime." :evil:

1.552 Beiträge seit 2010
vor 13 Jahren

Hallo NoLimit

auch die Funktion DATEADD verändert nicht die originalen Daten, dies muss immer über eine Update Anweisung gemacht werden. Ich sehe kein Problem damit "neu = alt+irgendwas" zu schreiben. Es ginge zwar auch über eine benutzerdefinierten Funktion, aber dann bist du wieder beim selben Problem, denn es funktioniert auch nicht folgendes um ein Tag zu einem Datum hinzuzufügen:


UPDATE [...] SET DATEADD(DAY,1,mydatecolumn)

Denn dort muss auch folgendes gemacht werden:


UPDATE [...] SET mydatecolumn = DATEADD(DAY,1,mydatecolumn)

Gruß
Michael

Mein Blog
Meine WPF-Druckbibliothek: auf Wordpress, myCSharp

P
66 Beiträge seit 2009
vor 13 Jahren

Fast.

In einer Spalte, nennen wir sie "Summe", steht '5'. Nun teile ich dem SQL einen neuen Wert '4' mit. Er soll nun die '5' durch eine '9' ersetzen.

Genau das würde doch ein Update-Statement tun. Und die Berechnung wird auch nicht auf dem Client durchgeführt.

...

1.378 Beiträge seit 2006
vor 13 Jahren

Was ist Strange daran?
Wenn ich getdate() als ComputedColumnSpecification eintrage dann schreibt er mir für jede neue Zeile das Datum an die entsprechende Stelle. Genauso wie ich z.B. die ID inkrementieren lassen kann.

Und natürlich möchte ich ihm einen neuen Wert vorgeben, aber die eigentliche Addition möchte ich eben auf der SQL-Seite haben, und nicht im Code des C# Programms.

Du vergleichst Äpfel mit Birnen. Das Autoincrement ist eine Spalteneigenschaft und keine Funktion wie GetDate().

Du kannst als DefaultValue eine eigens definierte Function angeben, die dann deinen neuen Defaultwert berechnet: Working with Default Constraints

Lg XXX

N
NoLimit Themenstarter:in
191 Beiträge seit 2007
vor 13 Jahren

Ich muss aber davon ausgehen dass nicht mein Programm alleine dort irgendwelche Zahlen reinwirft, ich muss aber sicherstellen dass sie eben alle addiert werden.
Daher eben die Idee dies Serverseitig zu machen.

"If you give someone a
program, you will frustrate them
for a day; if you teach them how to
program, you will frustrate them
for a lifetime." :evil:

Gelöschter Account
vor 13 Jahren

Das ist nun etwas komplett anderes. Am besten löst du das mit einer View. Die View zeigt dann den addierten Wert an.

Das geht recht simpel mit:
SELECT (a + b + c) as AddierterWert FROM tabelle

F
10.010 Beiträge seit 2004
vor 13 Jahren

Dazu braucht es keinen View.

Um z.b. in der Northwind DB in [Order details] eine spalte einzufügen, die automatisch den Combinierten Price auszugeben braucht es nur

alter table [Order Details] add CompPrice as ( ( [UnitPrice] * [Quantity] ) * (1 - discount))
X
1.177 Beiträge seit 2006
vor 13 Jahren

huhu,

Wenn ich getdate() als ComputedColumnSpecification eintrage dann schreibt er mir für jede neue Zeile das Datum an die entsprechende Stelle.

Die Annahme ist falsch. Du wirst bei jedem Select den aktuellen Wert von getdate() zurückbekommen (also jetzt den 07.03.2011, morgenden 08.03.2011). Computed Columns werden nur (maximal) solange gespeichert, wie sich ihr Wert nicht ändert. getdate() ändert sich dauernd.

Das Beispiel von FZelle zeigt das korrekte Verwenden von ComputedColumns.

Bitte einfach ausprobieren^^

😃

Xynratron

Herr, schmeiss Hirn vom Himmel - Autsch!

Die Erfahrung zeigt immer wieder, dass viele Probleme sich in Luft auslösen, wenn man sich den nötigen Abstand bzw. Schlaf gönnt.

N
NoLimit Themenstarter:in
191 Beiträge seit 2007
vor 13 Jahren

Langsam kommen wir der Sache näher.
Nur möchte ich ja nicht neue Zeilen erzeugen, sondern in einer einzigen immer die Summe aktuell haben.

"If you give someone a
program, you will frustrate them
for a day; if you teach them how to
program, you will frustrate them
for a lifetime." :evil:

L
416 Beiträge seit 2008
vor 13 Jahren

Wie wärs mit nem UPDATE Trigger?

N
NoLimit Themenstarter:in
191 Beiträge seit 2007
vor 13 Jahren

An sowas hatte ich auch schon gedacht, muß aber zugeben noch nie etwas mit Triggern gemacht zu haben.
Aber wenn das der richtige Weg ist, dann werde ich mich da gerne reinlesen

"If you give someone a
program, you will frustrate them
for a day; if you teach them how to
program, you will frustrate them
for a lifetime." :evil:

S
18 Beiträge seit 2010
vor 13 Jahren

Hallo,

ein Udpate-Trigger bringt hier meines Erachtens nicht das Ergebnis. Es sei denn, ich habe die Aufgabe noch immer nicht verstanden. Daher schreibe ich das jetzt mal hier nach aktuellem Wissensstand:

Du hast eine Tabelle mit einer Zeile. In dieser Zeile gibt es einen Zahlenwert. Dieser gibt immer die gerade aktuelle Summe von irgendetwas an. Du willst von der/einer/den Clientapplikationen immer die Summe aus dieser Zeile auslesen und ab und zu auch verändern. Dabei willst du nicht die Summe in der Clientapplikation ausrechnen, sondern am Server. Richtig?

Dann lautet die Lösung: Es geht mit einem einfachen SQL-Statement:

UPDATE Tabelle SET Summe = Summe + @NeuerWert (evtl. WHERE ...)

Wenn du die Summe nach dem ausführen deines Statement auch wieder auslesen willst, packst du das ganze in eine Transaktion und führst direkt nach dem Update ein passendes Select aus (in der Transaktion).

Sollte ich die Aufgabenstellung falsch verstanden haben, korrigiere diese doch bitte mal so, dass sie deiner Aufgabe entspricht. Danke!

Gruß
stups

16.842 Beiträge seit 2008
vor 13 Jahren

Ich denke man sollte dazu sagen, dass hier 'Summe' der Spaltenname darstellt und automatisch von der DB ermittelt wird - es ist also nur noch das Übergeben des NeuenWerts nötig, sodass hier auch eine Stored Proc sehr einfach erstellt werden kann - somit wäre seine Anforderung sehr einfach gelöst.

UPDATE Tabelle SET Summe = Summe + @NeuerWert (evtl. WHERE ...)


SqlCommand cmd  = new SqlCommand("StoredProcUpdateSumValue", conn);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add(new SqlParameter("@AdditionalValue", 5));

// Ergibt in deinem Beispiel '9'
N
NoLimit Themenstarter:in
191 Beiträge seit 2007
vor 13 Jahren

Prinzipiell stimmt das schon so! Nur, wie gesagt, werden auch andere Programme, die nicht von mir sind, in diese Zeile Zahlen eintragen. Und auch da muß sichergestellt sein dass der Server diese Zahl zu der bestehenden addiert, und somit wieder nur die Summe auf dem Server liegt.

"If you give someone a
program, you will frustrate them
for a day; if you teach them how to
program, you will frustrate them
for a lifetime." :evil:

N
NoLimit Themenstarter:in
191 Beiträge seit 2007
vor 13 Jahren

@Abt
Das klingt gut. Ich werde das mal einfach so testen.

"If you give someone a
program, you will frustrate them
for a day; if you teach them how to
program, you will frustrate them
for a lifetime." :evil:

T
146 Beiträge seit 2004
vor 13 Jahren

Frage am Rande:

Du willst eine Spalte erfinden, die sich nach Übergabe eines Wertes automatisch addiert, egal woher diese Daten kommen?

Also jegliche anderen Programme von beliebigen Herstellern, die sich an deine Vorgaben nicht halten und einfach irgendwas mit deinen Daten tun, sollen als Ergebnis einen richtigen Wert erhalten?

Sorry, aber das ist doch reines Wunschdenken. Das ist doch immernoch eine ganz normale SQL - Datenbank, an die jeder, der die Rechte hat seine Update und Insert statements schicken kann, wie er lustig ist.

Entweder irgendjemand definiert eine Arbeitsweise, an die sich alle halten, oder jeder schickt sein Update = alt + neu where ....

Was anderes kann und wirds nicht geben.

PS: Dieser definierte Weg kann natürlich eine stored procedure sein.

N
NoLimit Themenstarter:in
191 Beiträge seit 2007
vor 13 Jahren

Frage am Rande:

Du willst eine Spalte erfinden, die sich nach Übergabe eines Wertes automatisch addiert, egal woher diese Daten kommen?

Richtig!

Also jegliche anderen Programme von beliebigen Herstellern, die sich an deine Vorgaben nicht halten und einfach irgendwas mit deinen Daten tun, sollen als Ergebnis einen richtigen Wert erhalten?

Nein, sie sollen nichts zurück bekommen. Nur in der besagten Spalte soll die Summe stehen.

"If you give someone a
program, you will frustrate them
for a day; if you teach them how to
program, you will frustrate them
for a lifetime." :evil:

T
146 Beiträge seit 2004
vor 13 Jahren

Demnach musst du doch den anderen Herstellern irgendwie mitteilen, wie sie deine Daten updaten sollen oder?

Dann würde ich den von Abt gezeigten Weg wählen.

16.842 Beiträge seit 2008
vor 13 Jahren

Richtig!

Das ist aber nicht der richtige Ansatz.
Du musst den Dritt-Herstellern eine Möglichkeit (Schnittstelle) geben, die Daten so zu verändern, wie Du es ihnen erlaubst, sodass sie nach Deinen Regeln spielen.
Wenn Du aber einen direkten Datenbankzugriff erlaubst, dann brauchst Du Dich nicht wundern, wenn Hersteller nicht nach Vorgaben arbeiten - nicht mal Du möchtest Dich an die eigentlichen Arbeitsweisen einer SQL-Datenbank halten 8)

Wenn Du keinen Zugriff auf die Tabelle direkt geben möchtest - anderst wirst Du Dein gewünschtes Vorhaben eher nicht umsetzen können - dann musst Du es über die Stored Procedures machen.

F
10.010 Beiträge seit 2004
vor 13 Jahren

Äh, hast du meine Lösung angesehen?
Die macht genau das.

Sie fügt eine Computet Column in die Tabelle ein, die dann automatisch die Berechnung beim Select durchführt.

Da wird keine neue Zeile eingefügt

L
416 Beiträge seit 2008
vor 13 Jahren

Was anderes kann und wirds nicht geben.

Doch natürlich: ein UPDATE Trigger der entsprechend reagiert. Grad wegen der Andorderung das auch andere Anwendungen Werte eintragen sehe ich eigentlich keine andere Möglichkeit. Der Weg über eine Stored Procedure erfordert ja das die anderen Anwendungen geändert werden, bei einem Trigger ist das nicht der Fall.

@FZelle:
Wenn ich das richtig verstanden habe ist es beim SELECT gar nicht mehr möglich den Wert zu berechnen.

N
NoLimit Themenstarter:in
191 Beiträge seit 2007
vor 13 Jahren

Das mit dem Trigger sieht gut aus!
Das der SQL bei UPDATE eigentlich ein DELTE und dann ein INSERT ausführt hab ich zugriff auf den alten und neuen Wert.
Das wird was 👍

"If you give someone a
program, you will frustrate them
for a day; if you teach them how to
program, you will frustrate them
for a lifetime." :evil:

F
10.010 Beiträge seit 2004
vor 13 Jahren

@Lennart:
Eine Computed Column wird nur beim Select überhaupt vom SQL Server erzeugt.
Sie wird also bei jedem Select neu berechnet.

@NoLimit:
Das hast du falsch verstanden.
Ein update macht nicht delete und dann Insert, sonst würde sich ja z.b. eine AutoID ändern.
Aber du hast recht, du hast zugriff auf die alten und die neuen Daten.

S
18 Beiträge seit 2010
vor 13 Jahren

Hallo NoLimit,

nachdem jetzt klar ist, was du willst 😃 ist der Trigger die richtige Lösung.

Allerdings!!! (und die 3 Ausrufungszeichen stehen dort extra) solltest du dir UNBEDINGT Gedanken über das Datenmodell machen. Das was du tust, scheint mir eigentlich nicht sinnvoll zu sein.

Vllt. wäre das was für dich:
Eine Tabelle Buchungen/xyz, in die jeder seine Zahl einträgt, immer in eine neue Zeile.
Dann kannst du entweder per select sum(zahl) from Buchungen immer die Gesamtsumme abfragen, oder ebenfalls mit einem Trigger oder einer zeitgesteuerten Lösung die Summe in deiner anderen Tabelle aktualisieren.

Bei deiner Lösung hast du das Problem, löscht mal jemand den Datensatz, oder macht sonstigen "Quatsch", ist dein vorher zuletzt gespeicherter Wert WEG. Und du fängst wieder bei 0 oder sonstwo an...

Gruß
stups