Reputation: 19
Table ApprovedLeave
Column names:
EmployeeID (int)
Leave(varchar(MAX))
Approved(bit)
I want to set Leave
column unique so that user cannot enter same date twice. I cannot take employee id as primary key because same employee can take leave multiple times
Upvotes: 0
Views: 3003
Reputation: 363
Create a column for date. SQL Server 2008 has a new date
datatype instead of using datetime
. Don't use a varchar(max)
to represent a date.
LeaveDate ( date )
Now your primary key must include the new column.
alter table ApprovedLeave add constraint PK_ApprovedLeave primary key ( EmployeeID, LeaveDate );
/* don't forget to drop it if already exists */
This means that you can enter multiple records for the same employee, but not on the same date.
Upvotes: 1
Reputation: 4609
Building on doublesharp's answer, you will have to convert the Leave column data type to datetime. Depending on the format of the date values already in that column you will have to tweak the code a bit to handle the format(s):
-- // 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'
Upvotes: 0
Reputation: 13965
Since you said that Leave represents a date range, you could represent your table as
EmployeeID int
LeaveStart date
LeaveEnd date
Approved bit
... and make EmployeeID, LeaveStart, and LeaveEnd the components of a composite unique index.
But that only solves a subset of your real problem, which is that you don't want employees to take leave on overlapping time periods. (The exact same start and end dates are a special case of overlap). Consider these records:
Employee ID = 101, LeaveStart = 1/1/2012, LeaveEnd = 2/1/2012
Employee ID = 101, LeaveStart = 1/1/2012, LeaveEnd = 2/2/2012
That would satisfy your unique constraint, but would still be very wrong.
You can address that with a trigger, or with a constraint involving a UDF, or through very careful business logic in your calling program, but an index won't be enough.
Upvotes: 0
Reputation: 27599
You need to use a UNIQUE CONSTRAINT
on multiple columns - EmployeeID
andLeave
. Just setting the Leave
column as unique will mean that it will be enforced regardless of the EmployeeID
, and I am assuming you want to allow different employees to use the same Leave
date.
ALTER TABLE [tablename]
ADD CONSTRAINT [unique_leave] UNIQUE NONCLUSTERED
(
[EmployeeID], [Leave]
)
Upvotes: 0