2013-04-05 19 views
12

Pracuję z tabelą użytkowników i chcę wstawić "koniec daty okresu próbnego". Zasadniczo każdy nowy użytkownik ma 2 pełne miesiące od momentu przyłączenia się w ramach okresu próbnego. Widziałem, że mogę umieścić formułę w kolumnie dla mojej tabeli użytkowników, ale zastanawiam się, czy powinienem mieć skrypt, który aktualizuje to zamiast lub jeśli jest to odpowiedni czas na wykorzystanie kolumn obliczeniowych. Mam dostęp do tej tabeli dla różnych rzeczy i od czasu do czasu aktualizuję wiersz użytkowników na podstawie osiągnięć w zakresie wydajności. Data aplikacji nigdy się nie zmieni/nie zostanie zaktualizowana.Najważniejsze wskazówki dotyczące kolumny obliczeniowej na serwerze SQL

Moje pytanie brzmi: czy używanie wyliczonej kolumny jest dobrą praktyką w tej sytuacji, czy będzie przeliczać się za każdym razem, gdy aktualizuję ten wiersz (mimo że nie zamierzam aktualizować daty aplikacji)? Nie chcę tworzyć więcej narzutów, gdy aktualizuję wiersz w przyszłości.

Formula używam w definicji kolumny dla Kuratorów data zakończenia:

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

są "datę join" i „Data złożenia (zawiadomienie użyłem nieco mniej convulted podejście do dostać się do końca miesiąca, za dwa miesiące się.) " to samo? Czy chcesz później móc aktualizować datę zakończenia próbnego niezależnie od innych kolumn daty? –

+0

Czy polityka 2-miesięczna kiedykolwiek się zmieni? Czy może to być 1 lub 3 (lub inna wartość) w przyszłości? –

+0

Tak, JoinDate/AppDate same (przepraszam, używam ich zamiennie). Nigdy nie zastąpię daty, ale do punktu marc_s, ponieważ nie zostanie ona zaktualizowana, uwzględnię to jako część skryptu wstawiania. Muszę to zindeksować, a bez tego, co trwa, to nie zadziała tak dobrze. Dzięki za szybką odpowiedź błyskawiczną! – Brian

Odpowiedz

15

Widząc, że termin ten najprawdopodobniej nigdy się nie zmieni po jego ustawienie, to prawdopodobnie nie jest dobrym kandydatem dla kolumny obliczanej.

Po tym wszystkim: po wstawieniu wiersza do tego stołu można łatwo obliczyć datę "końca okresu próbnego" w tym miejscu (np. W wyzwalaczu), a po ustawieniu data ta nigdy się nie zmieni .

Tak więc, chociaż możesz zdecydowanie zrobić to w ten sposób, prawdopodobnie wolałbym użyć wyzwalacza AFTER INSERT (lub procedury przechowywanej dla operacji INSERT), która oblicza je tylko raz, a następnie zapisuje tę datę.

Również jako heads-up: obliczana kolumna z samą formułą jest obliczana za każdym razem, aby uzyskać do niej dostęp - po prostu bądź tego świadomy. Oznacza to, że jeśli nie podasz słowa kluczowego PERSISTED, wynik zostanie zapisany obok innych danych w wierszu, a to będzie o wiele lepiej pasować tutaj - znowu, ponieważ ta wartość, po obliczeniu, nie jest powiązana z zmienić się ponownie.

+0

Dziękuję za odpowiedź, więc lepsze wykorzystanie kolumny obliczeniowej może być tam, gdzie stale zmieniają się dane.Mam przełomowe osiągnięcie, w którym różne osiągnięcia spotkały się z pozytywnym wynikiem "osoby". To brzmi jak bardziej odpowiednie użycie kolumny obliczeniowej, prawda? – Brian

+0

@Brian: tak, coś w tym stylu. Lub jeśli masz datę, która może się zmieniać z czasem, a dla niektórych zapytań musisz wybrać lub pogrupować według miesiąca i roku tej daty - wtedy obliczony (i utrwalony!) Miesiąc i rok dla tej daty będzie idealny, ponieważ możesz również łatwo indeksuj te utrzymane, obliczone kolumny. –

+1

Dziękuję bardzo, to było bardzo pomocne! – Brian

0

Nie ma kosztów ogólnych podczas wstawiania danych; tylko po przeczytaniu kolumny wartości są obliczane dla tej kolumny. Powiedziałbym, że twoje podejście jest poprawne.

11

Jeśli chcesz później przedłużyć czyjąś próbę bez zmiany daty jej zastosowania, to obliczona kolumna NIE jest drogą do zrobienia. Dlaczego po prostu nie stosować ograniczenia dla obu kolumn?

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; 

Wyniki:

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

+3

Uwielbiam tę metodę na ostatni dzień miesiąca, używając zamiast tego :) – Brian