2009-03-05 14 views
19

Mit Transact SQL gibt es eine Möglichkeit, eine Standard-Datetime für eine Spalte (in der create table-Anweisung) anzugeben, so dass die Datetime der minimal mögliche Wert für Datetime-Werte ist?TSQL Standard Minimum DateTime

 
create table atable 
(
    atableID int IDENTITY(1, 1) PRIMARY KEY CLUSTERED, 
    Modified datetime DEFAULT XXXXX?????? 
) 

Vielleicht sollte ich es einfach null lassen.

Antwort

36

Soweit mir bekannt ist, gibt es keine Funktion, um dies zurückzugeben, Sie müssen es hart einstellen.

Der Versuch, aus Werten wie 0 zu konvertieren, um ein Mindestdatum zu erhalten, wird standardmäßig auf 01-01-1900 gesetzt.

Wie bereits erwähnt, sollten Sie NULL setzen (und beim Lesen ISNULL verwenden), oder wenn Sie Bedenken haben, die Einstellung korrekt vorzunehmen, können Sie sogar einen Trigger auf die Tabelle setzen, um das Änderungsdatum für die Änderungen festzulegen.

Wenn Sie Ihr Herz auf immer die minimal mögliche Datum festgelegt haben, dann:

 
create table atable 
(
    atableID int IDENTITY(1, 1) PRIMARY KEY CLUSTERED, 
    Modified datetime DEFAULT '1753-01-01' 
) 

11

„Vielleicht sollte ich es null verlassen“

nicht magischen Zahlen Verwenden Sie - es ist eine schlechte Praxis - wenn Sie es keinen Wert verlassen haben null

Andernfalls, wenn Sie wirklich ein Standarddatum wollen - eine der anderen Techniken geschrieben verwenden, um ein Standarddatum

+3

würde ich eher zustimmen. Haben Sie nebenbei eine Antwort auf die Frage? – user72491

+4

Ich hasse es, wenn Benutzer versuchen, den Benutzer umzuleiten, anstatt zu antworten und dann versuchen, umzuleiten. – TheTXI

+1

"Vielleicht sollte ich es einfach null lassen." - Ich habe diesen Teil beantwortet –

0

ich diese Arbeit ...

create table atable 
(
    atableID int IDENTITY(1, 1) PRIMARY KEY CLUSTERED, 
    Modified datetime DEFAULT ((0)) 
) 

bearbeiten würde denken, setzen: Das ist falsch ... Die minimale SQL DATETI Mein Wert ist 1/1/1753. Meine Lösung bietet eine datetime = 1/1/1900 00:00:00. Andere Antworten haben das richtige Mindestdatum ...

+0

+1. Doing WHERE Modified = 0 ist SARGable, WHERE Modified IS NULL ist dies nicht. – Tomalak

+1

das wird nicht funktionieren - 0 ist '1/1/1900'. -53690 würde Ihnen den Wert von "1/1/1753" geben. –

+0

Hm. Vielleicht verstehe ich es nicht, aber was ist "1/1/1753"? Und warum wird '1/1/1900' nicht funktionieren? – Tomalak

0

Ich denke, die einzige Möglichkeit hier eine Konstante ist. Mit dem gesagt - benutze es nicht - bleibe bei Nullen anstatt gefälschten Daten.

create table atable 
(
    atableID int IDENTITY(1, 1) PRIMARY KEY CLUSTERED, 
    Modified datetime DEFAULT '1/1/1753' 
) 
5

Sofern Sie eine DB tun als vor einem Jahrhundert mehr historische Zeit zu verfolgen, ist

Modified datetime DEFAULT ((0)) 

mit vollkommen sicher und gesund und ermöglicht elegantere Abfragen als ‚1753.01.01‘ und effizientere Abfragen als NULL.

Da jedoch erste datetime Modified ist der Zeitpunkt, an dem der Datensatz eingefügt wurde, können Sie verwenden:

Modified datetime NOT NULL DEFAULT (GETUTCDATE()) 

, die das ganze Problem vermeidet und Ihre Einsätze einfacher und sicherer - wie in Sie dies nicht tun fügen Sie es überhaupt und SQL macht die Hausarbeit :-)

Mit diesem an Ort und Stelle können Sie immer noch elegante und schnelle Abfragen haben mit 0 als praktisches Minimum, da es garantiert ist immer niedriger als jede Insert-generierte GETUTCDATE().

14

Ich stimme der Einstellung in "keine magischen Werte verwenden" zu. Ich möchte jedoch darauf hinweisen, dass es manchmal legitim ist, auf solche Lösungen zurückzugreifen.

Es gibt einen Preis für das Setzen von Spalten, die nullable sind: NULLs sind nicht indexierbar.Eine Abfrage wie "Alle Datensätze, die seit Anfang 2010 nicht geändert wurden" enthält diejenigen, die noch nie geändert wurden. Wenn wir eine NULL-Spalte verwenden, sind wir gezwungen, [modified] < @cutoffDate OR [modifiziert] IS NULL zu verwenden, und dies wiederum zwingt das Datenbankmodul, einen Tabellenscan durchzuführen, da die Nullen nicht indiziert sind. Und dieses letzte kann ein Problem sein.

In der Praxis sollte man mit NULL gehen, wenn dies keine praktische, reale Leistungseinbuße einführt. Aber es kann schwierig sein, es zu wissen, es sei denn, Sie haben eine Vorstellung davon, welche realistischen Datenmengen heute vorliegen und in der sogenannten vorhersehbaren Zukunft liegen werden. Sie müssen auch wissen, ob es einen großen Teil der Datensätze gibt, die den speziellen Wert haben - wenn ja, dann hat es keinen Sinn, sie trotzdem zu indizieren.

Kurz gesagt, durch Taubheit/Faustregel sollte man für NULL gehen. Wenn es jedoch eine große Anzahl von Datensätzen gibt, werden die Daten häufig abgefragt, und nur ein kleiner Teil der Datensätze hat den NULL/Spezialwert. Es könnte einen erheblichen Leistungsgewinn für das Auffinden von Datensätzen auf der Grundlage dieser Informationen geben Index!) und IMHO kann dies manchmal die Verwendung von "magischen" Werten rechtfertigen.

3

Manchmal erben Sie spröden Code, der an vielen Stellen bereits magische Werte erwartet. Jeder ist richtig, Sie sollten NULL verwenden, wenn möglich. Als Abkürzung, um sicherzustellen, dass jeder Verweis auf diesen Wert derselbe ist, setze ich "Konstanten" (mangels eines besseren Namens) in SQL in eine Scaler-Funktion und rufe diese Funktion dann auf, wenn ich den Wert brauche. Auf diese Weise, wenn ich sie alle aktualisieren möchte, kann ich es leicht machen. Oder wenn ich den Standardwert nach vorne ändern möchte, habe ich nur einen Ort, um ihn zu aktualisieren.

Der folgende Code erstellt die Funktion und eine Tabelle, die sie für den Standardwert DateTime verwendet. Dann Einfügen und Auswählen aus der Tabelle, ohne den Wert für Modifiziert anzugeben. Dann räumt er auf. Ich hoffe das hilft.

-- CREATE FUNCTION 
CREATE FUNCTION dbo.DateTime_MinValue () 
RETURNS DATETIME 
AS 
    BEGIN 
     DECLARE @dateTime_min DATETIME ; 
     SET @dateTime_min = '1/1/1753 12:00:00 AM' 
     RETURN @dateTime_min ; 
    END ; 
GO 


-- CREATE TABLE USING FUNCTION FOR DEFAULT 
CREATE TABLE TestTable 
(
    TestTableId INT IDENTITY(1, 1) 
        PRIMARY KEY CLUSTERED , 
    Value VARCHAR(50) , 
    Modified DATETIME DEFAULT dbo.DateTime_MinValue() 
) ; 


-- INSERT VALUE INTO TABLE 
INSERT INTO TestTable 
     (Value) 
VALUES ('Value') ; 


-- SELECT FROM TABLE 
SELECT TestTableId , 
     VALUE , 
     Modified 
FROM TestTable ; 


-- CLEANUP YOUR DB 
DROP TABLE TestTable ; 
DROP FUNCTION dbo.DateTime_MinValue ;