Bir tablo oluştururken varsayılan bir kısıtlama bildirmek


100

GUI kullanmak yerine kodu yazarak Microsoft SQL server 2000'de yeni bir tablo oluşturuyorum, bunu "manuel yolla" nasıl yapacağımı öğrenmeye çalışıyorum.

Aslında kullandığım kod bu ve iyi çalışıyor:

CREATE TABLE "attachments"
(
    "attachment_id" INT NOT NULL,
    "load_date" SMALLDATETIME NOT NULL,
    "user" VARCHAR(25) NOT NULL,
    "file_name" VARCHAR(50) NOT NULL,
    CONSTRAINT "pk_attachments" PRIMARY KEY ("attachment_id"),
    CONSTRAINT "fk_users" FOREIGN KEY ("user") REFERENCES "users" ("user"),
    CONSTRAINT "ch_load_date" CHECK ("load_date" < GETDATE())
)

Birincil anahtarı, yabancı anahtarı ve kontrol kısıtlamalarını kendi başlarına belirledim çünkü bu şekilde onlar için bir ad tanımlayabilirim, aksi takdirde bunları satır içi olarak bildirmek SQL Server'ın rastgele bir ad oluşturmasına neden olur ve bunu "beğenmem".

Varsayılan değer kısıtlamasını bildirmeye çalıştığımda sorun ortaya çıktı: İnternetteki bilgilere ve Microsoft SLQ Server Management Studio'nun bunu nasıl oluşturduğuna baktığımda, hem satır içi hem de kendi başına oluşturulabileceğini anladım:

"load_date" SMALLDATETIME NOT NULL DEFAULT GETDATE()

veya

CONSTRAINT "df_load_date" DEFAULT GETDATE() FOR "load_date"

Satır içi yöntem iyi çalışıyor, ancak her zamanki gibi sabit için rastgele bir ad oluşturuyor, bağımsız yöntem bir hata veriyor diyerek Incorrect syntax near 'FOR'..

Ayrıca, tabloyu oluşturursam ve sonra ALTERbu komut çalışır:

ALTER TABLE "attachments"
ADD CONSTRAINT "df_load_date" DEFAULT GETDATE() FOR "load_date"


Referans olarak, çalıştırmaya çalıştığım kodun tamamı:

CREATE TABLE "attachments"
(
    "attachment_id" INT NOT NULL,
    "load_date" SMALLDATETIME NOT NULL,
    "user" VARCHAR(25) NOT NULL,
    "file_name" VARCHAR(50) NOT NULL,
    CONSTRAINT "pk_attachments" PRIMARY KEY ("attachment_id"),
    CONSTRAINT "fk_users" FOREIGN KEY ("user") REFERENCES "users" ("user"),
    CONSTRAINT "ch_load_date" CHECK ("load_date" < GETDATE()),
    CONSTRAINT "df_load_date" DEFAULT GETDATE() FOR "load_date"
)



Burada tamamen kayboldum, yapmaya çalıştığım şey mümkün değil mi yoksa yanlış bir şey mi yapıyorum?


Düzenle:

David M, satır içi sözdizimini kullanarak adlandırılmış bir varsayılan kısıtlamanın nasıl ekleneceğini gösterdi, hala bağımsız sözdiziminin tamamen yanlış mı yoksa benim hatam mı olduğunu anlamaya çalışıyorum.


3
Düzenlemeye katılıyorum. David M'nin yanıtı, bağımsız bir kısıtlama bildirimi aracılığıyla bir kısıtlamanın nasıl ekleneceğini kapsamaz, ancak BOL, David M'nin gösterdiği yol dışında varsayılan kısıtlamayı adlandırabileceğiniz herhangi bir örneğe sahip olmadığından, SQL'i varsaymanın güvenli olduğunu düşünüyorum. Sunucu (tutarsız olarak) bu sözdizimini desteklemiyor.
Peter Majeed

Yanıtlar:


177

Sütun oluşturma ile satır içi yapın:

[load_date] SMALLDATETIME NOT NULL
        CONSTRAINT [df_load_date] DEFAULT GETDATE()

Birçok okuyucu QUOTED_IDENTIFIERSvarsayılan olarak üzerinde çalışmayacağı için tırnak yerine köşeli parantez kullandım .


3
Teşekkürler, bu isim sorununu çözer. Şimdi bu davranışın "tasarım gereği" mi (yani bunu yapmak mümkün değil) veya yapmanın bir yolu olup olmadığını anlamaya çalışıyorum. Biliyorsunuz, kodumu "derli toplu" tutmayı ve sütunlardan sonra kısıtlamaların beyan edilmesini, SQL dosyalarını daha anlaşılır ve daha kolay anlaşılır hale getirip hata ayıklamasını (ya da en azından benim düşündüğüm gibi) yapmasını seviyorum.
Albireo

3
@Albireo - Tasarım gereği. table_constraintiçinde dilbilgisi içermezDEFAULT
Martin Smith

2
Bu çözüm, yalnızca alanın etrafındaki alıntıları ve kısıtlama adlarını kaldırdığımda işe yarıyor.
David S.

1
SQL Server'ın daha yeni sürümleri için [load_date] SMALLDATETIME NOT NULL CONSTRAINT [df_load_date] DEFAULT GETDATE(). Çift tırnak yerine köşeli parantezlere dikkat edin.
deadlydog

3
Aslında daha yeni / eski sürüm bir şey değil - SET QUOTED_IDENTIFIERgeçiş yapar. Cevabı revize edeceğim, zaten köşeli parantezleri tercih ettiğim için, sadece OP'nin sorusunun tarzını takip ettim.
David M
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.