2009-03-05 35 views
19

Sử dụng Transact SQL là có cách để chỉ định datetime mặc định trên một cột (trong câu lệnh tạo bảng) sao cho datetime là giá trị tối thiểu có thể cho giá trị datetime?TSQL Thời gian tối thiểu mặc định

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

Có lẽ tôi chỉ nên để trống.

Trả lời

36

Theo như tôi biết không có chức năng tồn tại để trả lại điều này, bạn sẽ phải khó thiết lập nó.

Cố gắng truyền từ các giá trị như 0 để có được ngày tối thiểu sẽ mặc định là 01-01-1900.

Như đề xuất trước đó tốt nhất còn lại để NULL (hoặc sử dụng ISNULL khi đọc nếu bạn cần), hoặc nếu bạn đang lo lắng về việc thiết lập nó một cách chính xác bạn thậm chí có thể thiết lập một kích hoạt trên bàn để thiết lập ngày sửa đổi của bạn trên chỉnh sửa.

Nếu bạn có trái tim của bạn đặt vào việc ngày tối thiểu có thể sau đó:

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

11

"Có lẽ tôi nên rời khỏi nó null"

Không sử dụng con số kỳ diệu - đó là thực tế xấu - nếu bạn không có một giá trị để nó vô

Nếu không, nếu bạn thực sự muốn có một ngày mặc định - sử dụng một trong các kỹ thuật khác được đăng để thiết lập một ngày mặc định

+3

Tôi có xu hướng đồng ý. Là một sang một bên, bạn có một câu trả lời cho câu hỏi? – user72491

+4

Tôi ghét khi người dùng cố gắng chuyển hướng người dùng thay vì trả lời và - cố gắng chuyển hướng. – TheTXI

+1

"Có lẽ tôi nên để nó vô giá trị." - Tôi đã trả lời phần –

0

tôi nghĩ rằng điều này sẽ làm việc ...

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

chỉnh sửa: Đây là sai ... Tối thiểu SQL DateTi tôi Giá trị là 1/1/1753. Giải pháp của tôi cung cấp datetime = 1/1/1900 00:00:00. Các câu trả lời khác có ngày tối thiểu chính xác ...

+0

+1. Làm WHERE được sửa đổi = 0 là SARGable, WHERE được sửa đổi IS NULL thì không. – Tomalak

+1

điều này sẽ không hoạt động - 0 là '1/1/1900'. -53690 sẽ cho bạn giá trị '1/1/1753'. –

+0

Hm. Có lẽ tôi không hiểu, nhưng '1/1/1753' là gì? Và tại sao '1/1/1900' không hoạt động? – Tomalak

0

Tôi nghĩ rằng lựa chọn duy nhất của bạn ở đây là một hằng số. Với điều đó nói - không sử dụng nó - gắn với null thay vì ngày không có thật.

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

Trừ khi bạn đang làm một DB để theo dõi thời gian lịch sử hơn một thế kỷ trước, tận dụng

Modified datetime DEFAULT ((0)) 

là hoàn toàn an toàn và âm thanh và cho phép truy vấn thanh lịch hơn '1753/01/01' và truy vấn hiệu quả hơn NULL.

Tuy nhiên, kể từ khi lần đầu tiên thay đổi datetime là thời gian mà các bản ghi được chèn, bạn có thể sử dụng:

Modified datetime NOT NULL DEFAULT (GETUTCDATE()) 

mà tránh toàn bộ vấn đề và làm cho chèn bạn dễ dàng hơn và an toàn hơn - như trong bạn không chèn nó ở tất cả và SQL làm việc nhà :-)

Với điều đó, bạn vẫn có thể truy vấn nhanh và thanh lịch bằng cách sử dụng 0 ở mức tối thiểu thực tế vì nó đảm bảo luôn thấp hơn bất kỳ GETUTCDATE() được chèn.

14

Tôi đồng ý với ý kiến ​​"không sử dụng giá trị ma thuật". Nhưng tôi muốn chỉ ra rằng có những lúc nó hợp pháp để giải quyết những giải pháp như vậy.

Có một mức giá để thanh toán cho các cột đặt giá trị rỗng: NULL không thể lập chỉ mục.Truy vấn như "nhận tất cả các bản ghi chưa được sửa đổi kể từ đầu năm 2010" bao gồm những bản chưa bao giờ được sửa đổi. Nếu chúng ta sử dụng một cột nullable, chúng ta buộc phải sử dụng [sửa đổi] < @cutoffDate OR [sửa] IS NULL, và điều này sẽ buộc công cụ cơ sở dữ liệu thực hiện quét bảng, vì các giá trị rỗng không được lập chỉ mục. Và điều này mới nhất có thể là một vấn đề.

Trong thực tế, người ta nên đi với NULL nếu điều này không giới thiệu một hình phạt thực tế thực tế, thực tế. Nhưng có thể khó biết, trừ khi bạn có một số ý tưởng về khối lượng dữ liệu thực tế hiện nay và sẽ có trong cái gọi là tương lai có thể nhìn thấy được. Bạn cũng cần phải biết nếu có một tỷ lệ lớn các bản ghi có giá trị đặc biệt - nếu vậy, không có điểm nào trong việc lập chỉ mục nó.

Tóm lại, bằng điếc/quy tắc ngón tay cái, bạn nên dùng NULL. Nhưng nếu có một số lượng lớn các bản ghi, dữ liệu thường được truy vấn và chỉ một tỷ lệ nhỏ các bản ghi có giá trị NULL/đặc biệt, có thể đạt được hiệu suất đáng kể để định vị các bản ghi dựa trên thông tin này. index!) và IMHO điều này đôi khi có thể biện minh cho việc sử dụng các giá trị "ma thuật".

3

Đôi khi bạn thừa kế mã giòn đã được mong đợi giá trị ma thuật ở rất nhiều nơi. Mọi người đều đúng, bạn nên sử dụng NULL nếu có thể. Tuy nhiên, như một phím tắt để đảm bảo mọi tham chiếu đến giá trị đó giống nhau, tôi muốn đặt "hằng số" (vì thiếu tên tốt hơn) trong SQL trong hàm scaler và sau đó gọi hàm đó khi tôi cần giá trị. Bằng cách đó, nếu tôi muốn cập nhật tất cả những thứ khác, tôi có thể làm như vậy một cách dễ dàng. Hoặc nếu tôi muốn thay đổi giá trị mặc định di chuyển về phía trước, tôi chỉ có một nơi để cập nhật nó.

Đoạn mã sau tạo hàm và bảng sử dụng nó cho giá trị Ngày giờ mặc định. Sau đó chèn và chọn từ bảng mà không chỉ định giá trị cho Đã sửa đổi. Sau đó làm sạch sau khi chính nó. Tôi hi vọng cái này giúp được.

-- 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 ; 
Các vấn đề liên quan