2013-04-05 14 views
12

Ich arbeite mit einer Benutzertabelle und möchte ein "Ende der Probezeit" setzen. Grundsätzlich hat jeder neue Benutzer zwei volle Monate ab dem Zeitpunkt seiner Teilnahme an der Probezeit. Ich habe gesehen, dass ich eine Formel in die Spalte meiner Benutzertabelle schreiben kann, aber ich frage mich, ob ich ein Skript haben sollte, das dies aktualisiert, oder ob dies ein akzeptabler Zeitpunkt ist, um berechnete Spalten zu verwenden. Ich greife auf diese Tabelle für verschiedene Dinge zu und aktualisiere gelegentlich die Reihe der Benutzer basierend auf Leistungsmeilensteinleistungen. Das Bewerbungsdatum wird sich niemals ändern/aktualisiert werden.Best Practices für berechnete Spalte in SQL Server

Meine Frage ist: Ist die Berechnung der Spalte eine gute Übung in dieser Situation oder wird sie jedes Mal neu berechnet, wenn ich diese Zeile aktualisiere (obwohl ich das App-Datum nicht aktualisieren werde)? Ich möchte nicht mehr Overhead erzeugen, wenn ich die Zeile in Zukunft aktualisiere.

Formel I bin für die Bewährungs Enddatum in der Spaltendefinition verwendet:

(dateadd(day,(-1),dateadd(month,(3),dateadd(day,(1)-datepart(day,[APP_DT]),[APP_DT])))) 
+0

Sind „join Datum“ und „Anmeldedatum (bemerke ich einen etwas weniger convulted Ansatz verwendet, um das Ende des Monats für zwei Monate zu bekommen.) " das gleiche? Möchten Sie das Enddatum der Bewährung später unabhängig von den anderen Datumsspalten aktualisieren? –

+0

Wird sich die 2-Monats-Politik jemals ändern? Könnte es in der Zukunft 1 oder 3 (oder ein anderer Wert) werden? –

+0

Ja, JoinDate/AppDate dasselbe (sorry, ich benutze sie austauschbar). Ich werde nie das Datum überschreiben, aber zu marc_s Punkt, da es nicht aktualisiert wird, werde ich das als Teil des Einfügeskriptes einschließen. Ich muss das auch indexieren, und ohne das Dauerhafte wird das nicht so gut funktionieren. Tausend Dank für die blitzschnelle Antwort! – Brian

Antwort

15

sehen, dass dieses Datum wird wahrscheinlich nie, wenn es gesetzt ist ändern, ist es wahrscheinlich nicht ein guter Kandidat für eine berechnete Spalte.

Immerhin: Sobald Sie eine Zeile in diese Tabelle eingefügt haben, können Sie einfach das Datum der "Probezeitende" genau dort und dann (zB in einem Trigger) berechnen, und einmal festgelegt, wird dieses Datum nie ändern .

So, während Sie es auf diese Weise tun können, würde ich wahrscheinlich lieber einen AFTER INSERT Trigger (oder eine gespeicherte Prozedur für die INSERT Operation) verwenden, die nur einmal berechnet und speichert dann dieses Datum.

Ebenso wie ein Heads-up: eine berechnete Spalte mit nur der Formel wird jedes Mal berechnet, um darauf zuzugreifen - nur darauf achten. Das heißt, wenn Sie das Schlüsselwort PERSISTED nicht angeben, wird das Ergebnis in diesem Fall zusammen mit den anderen Daten in der Zeile gespeichert. Dies würde hier viel besser passen - wiederum, da der einmal berechnete Wert nicht gebunden ist ändern Sie sich immer wieder.

+0

Vielen Dank für die Antwort, so könnte eine bessere Verwendung einer berechneten Spalte dort sein, wo sich Daten ständig verschieben.Ich habe eine Meilensteinleistung, bei der verschiedene Erfolge die Punktzahl einer Person erhöhen. Das klingt nach einer angemesseneren Verwendung der berechneten Spalte, richtig? – Brian

+0

@Brian: Ja, so etwas. Oder wenn Sie ein Datum haben, das sich im Laufe der Zeit ändern kann, und für einige Abfragen müssen Sie nach Monat und Jahr dieses Datums auswählen oder gruppieren - dann wäre ein berechneter (und beibehaltener!) Monat und Jahr für dieses Datum perfekt, da Sie es können Indexieren Sie diese persistenten, berechneten Spalten auch ganz einfach. –

+1

Vielen Dank, das war sehr hilfreich! – Brian

0

Beim Einfügen von Daten entstehen keine zusätzlichen Kosten. Nur wenn Sie die Spalte lesen, werden die Werte für diese Spalte berechnet. Ich würde also sagen, dass Ihre Herangehensweise richtig ist.

11

Wenn Sie die Probezeit später verlängern möchten, ohne das Anwendungsdatum ändern zu müssen, ist eine berechnete Spalte NICHT der richtige Weg. Warum nicht einfach eine DEFAULT Einschränkung für beide Spalten verwenden?

USE tempdb; 
GO 

CREATE TABLE dbo.foo 
(
    MemberID INT IDENTITY(1,1), 
    JoinDate DATE NOT NULL DEFAULT SYSDATETIME(), 
    ProbationEndDate NOT NULL DEFAULT 
    DATEADD(DAY, -1, DATEADD(MONTH, DATEDIFF(MONTH,0,SYSDATETIME())+3, 0)) 
); 

INSERT dbo.foo DEFAULT VALUES; 

SELECT MemberID, JoinDate, ProbationEndDate FROM dbo.foo; 

Ergebnisse:

MemberID JoinDate  ProbationEndDate 
-------- ---------- ---------------- 
1   2013-04-05 2013-06-30 

+3

Ich liebe diese Methode für den letzten Tag des Monats, mit dem statt :) – Brian