テーブルApprovedLeave
列名:
EmployeeID (int)
Leave(varchar(MAX))
Approved(bit)
Leave
ユーザーが同じ日付を2回入力できないように、列を一意に設定したい。同じ従業員が複数回休暇を取ることができるため、従業員 ID を主キーとして取得できません
テーブルApprovedLeave
列名:
EmployeeID (int)
Leave(varchar(MAX))
Approved(bit)
Leave
ユーザーが同じ日付を2回入力できないように、列を一意に設定したい。同じ従業員が複数回休暇を取ることができるため、従業員 ID を主キーとして取得できません
日付の列を作成します。SQL Server 2008 には、date
使用する代わりに新しいデータ型がありdatetime
ます。varchar(max)
日付を表すために a を使用しないでください。
LeaveDate ( date )
ここで、主キーに新しい列を含める必要があります。
alter table ApprovedLeave add constraint PK_ApprovedLeave primary key ( EmployeeID, LeaveDate );
/* don't forget to drop it if already exists */
つまり、同じ従業員の複数のレコードを入力できますが、同じ日付には入力できません。
休暇は日付範囲を表すと言ったので、テーブルを次のように表すことができます
EmployeeID int
LeaveStart date
LeaveEnd date
Approved bit
...そして、EmployeeID、LeaveStart、および LeaveEnd を複合一意インデックスのコンポーネントにします。
しかし、それはあなたの実際の問題のサブセットを解決するだけです.それは、従業員が重複する期間に休暇を取ってほしくないということです. (開始日と終了日がまったく同じ場合は、重複の特殊なケースです)。次のレコードを検討してください。
Employee ID = 101, LeaveStart = 1/1/2012, LeaveEnd = 2/1/2012
Employee ID = 101, LeaveStart = 1/1/2012, LeaveEnd = 2/2/2012
それはあなたの一意の制約を満たしますが、それでも非常に間違っています.
トリガー、UDF を含む制約、または呼び出し元プログラムの非常に慎重なビジネス ロジックを使用して、これに対処できますが、インデックスだけでは十分ではありません。
doublesharp の回答に基づいて、Leave 列のデータ型を datetime に変換する必要があります。その列に既にある日付値の形式に応じて、形式を処理するためにコードを少し調整する必要があります。
-- // Add new column using correct data type
alter table [tablename] add Leave_New datetime not null
go
-- // populate it from existing column:
update [tablename] set Leave_New = convert(datetime, [Leave], 1)
go
-- // Add the unique constraint:
ALTER TABLE [tablename]
ADD CONSTRAINT [unique_leave] UNIQUE NONCLUSTERED
(
[EmployeeID], [Leave_new]
)
-- // After you verify that the above is successful, you can drop the old column, and rename the new one:
alter table [tablename] drop column [Leave]
go
exec sp_RENAME '[tablename].Leave_New', 'Leave' , 'COLUMN'
UNIQUE CONSTRAINT
複数の列で a を使用する必要があります -EmployeeID
およびLeave
. Leave
列を一意に設定するだけで、日付に関係なく適用されます。異なる従業員が同じ日付EmployeeID
を使用できるようにしたいと考えています。Leave
ALTER TABLE [tablename]
ADD CONSTRAINT [unique_leave] UNIQUE NONCLUSTERED
(
[EmployeeID], [Leave]
)