Using a check constraint on a date - sql

I want to make sure that a person's Date of Birth must be less than the current date.
So I declared in a table:
staff_dob SMALLDATETIME NOT NULL CHECK (GETDATE() < staff_dob)
But when I keep getting conflicts with the check constraint. How do I fix this? Do I need to formate GETDATE() into a proper format that I use? I'm unsure on how to do it.

Try this code:
drop table test
create table test
(staff_dob datetime check (staff_dob < getdate()))
--this insert will fail
insert test
(staff_dob)
values
('1/1/2013')
--this insert will succeed
insert test
(staff_dob)
values
('1/1/2011')
I think your check comparison was in the wrong direction.

take a look at Creating and Modifying CHECK Constraints
CREATE TABLE [dbo].[Staff](
[staffid] [int] NULL,
[dob] [date] NULL
) ON [PRIMARY]
GO
ALTER TABLE [dbo].[Staff] WITH CHECK ADD CONSTRAINT [CK_Staff] CHECK (([dob]<getdate()))
GO
ALTER TABLE [dbo].[Staff] CHECK CONSTRAINT [CK_Staff]
GO
hope this helps

Related

Trigger to disallow inserting negative number to tables' column

In my mssql database I need to create a trigger that will disallow inserting negative budget to projects table. I don't really know how can I do it. All kind of help will be appreciated!
CREATE TRIGGER budget on PROJ FOR INSERT
For all answers ommiting triggers - unfortunately I need to do this with trigger
You do not need a trigger for this. SQL Server supports check constraints:
alter table projects add constraint chk_projects_budget check (budget >= 0);
There is no reason for not using a CHECK constraint. However you can certainly implement that constraint with a trigger by checking if there is any new row that has negative budget and raising an error on that case.
CREATE TRIGGER projects_positive_budget ON projects
FOR INSERT, UPDATE
IF EXISTS (SELECT * FROM inserted WHERE budget < 0)
BEGIN
RAISERROR('No negative budget is allowed', 16, -1);
ROLLBACK;
RETURN
END
GO
If you want to check multiple columns you can also
ALTER TABLE YourTableName
ADD CONSTRAINT CH_CheckForNegative CHECK(Col1 >=0 AND Col2 >= 0);
You can try this to add constraint for checking acceptable integer values either positive or negative.
CREATE TABLE [dbo].[Tbl](
[F1] [int] NULL,
[F2] [int] NULL
) ON [PRIMARY]
GO
--To accept only positive numbers and 0
ALTER TABLE [dbo].[Tbl] WITH CHECK ADD CONSTRAINT [CK_Tbl] CHECK (([F1]>=(0)))
GO
--To check constraint on the table
ALTER TABLE [dbo].[Tbl] CHECK CONSTRAINT [CK_Tbl]
GO
--To accept only negative numbers and 0
ALTER TABLE [dbo].[Tbl] WITH CHECK ADD CONSTRAINT [CK_Tbl_1] CHECK (([F2]<=(0)))
For more information you can check the link Integer Constraint

SQL Server Trigger INSTEAD OF INSERT to Set Timestamps Before Commit

In SQL Server 2008 R2, I am looking to create a trigger that imitates the behavior of an Oracle BEFORE INSERT trigger, where any insert that comes in has the trigger update the UPDATE_TS and CREATE_TS to the current timestamp right before the persist.
To issue I am seeing right now is the error:
An explicit value for the identity column in table 'MY_TABLE' can only be specified when a column list is used and IDENTITY_INSERT is ON
I am not sure if it is a good idea to turn SET IDENTITY INSERT table ON and then
SET IDENTITY INSERT table OFF within the trigger. Maybe that is a possible solution.
Please advise on best practice.
Example Table is called MY_TABLE:
CREATE TABLE [myschema].[MY_TABLE](
[MY_TABLE_ID] [bigint] IDENTITY(1,1) NOT NULL,
[FIELD_TO_UPDATE] [varchar](255) NOT NULL,
[CREATE_TS] [datetime] NULL,
[UPDATE_TS] [datetime] NULL),
PRIMARY KEY (MY_TABLE_ID))
Trigger:
CREATE TRIGGER my_table_create_ts_trigger
ON [mydb].myschema.MY_TABLE
INSTEAD OF INSERT
AS
BEGIN
INSERT INTO MY_TABLE([MY_TABLE_ID], [FIELD_TO_UPDATE], [CREATE_TS], [UPDATE_TS])
SELECT i.MY_TABLE_ID, i.FIELD_TO_UPDATE, GETDATE(), GETDATE()
FROM INSERTED as i
END
Not sure why you are using dynamic SQL, it's not really needed. Also, no need to do an UPDATE afterwards, you can just do:
CREATE TRIGGER my_table_create_ts_trigger
ON [mydb].myschema.MY_TABLE
INSTEAD OF INSERT
AS
BEGIN
INSERT INTO MY_TABLE(<list of every non identity column here>)
SELECT <list of every non identity column and the date here>, GETDATE()
FROM INSERTED
END
Also, you should list the columns explicitely in the INSERT and the SELECT.
I must be a glutton for punishment, but I have a better suggestion. Drop the trigger.
Change your table to:
CREATE TABLE [myschema].[MY_TABLE](
[MY_TABLE_ID] [bigint] IDENTITY(1,1) NOT NULL,
[FIELD_TO_UPDATE] [varchar](255) NOT NULL,
-- change this column to have a default:
[CREATE_TS] [datetime] NOT NULL DEFAULT CURRENT_TIMESTAMP,
-- and this column too, I guess:
[UPDATE_TS] [datetime] NOT NULL DEFAULT CURRENT_TIMESTAMP),
PRIMARY KEY (MY_TABLE_ID))
Why would you allow those columns to be NULL? Why do you want to use an elaborate trigger to replace something that is much simpler to implement with a default constraint?
You don't need the trigger, and I don't understand what benefit it brings or why you want to replicate a BEFORE trigger. An INSTEAD OF trigger is similar, but not exactly the same thing.

SQL Date option

I have a little doubt, I want to create a table that had a date that can't be bigger the 2012/12/31, i searched on google but only had exemples on SELECT. I'm gonna put an example:
CREATE TABLE example(
IDExample number (8) primary key,
DateExample date // Here i want to put that condition, is it possible?
);
If you're using SQL Server you can add check contraint on the column in the following way.
ALTER TABLE dbo.example ADD CONSTRAINT CK_DateExample
CHECK (DateExample < '20130101')
If you're using Oracle, the syntax is very similar:
ALTER TABLE dbo.example ADD CONSTRAINT CK_DateExample
CHECK (DateExample < DATE '2013-01-01')

Default getdate for Insert date

I have a table called sample and it has a column called [__INSERT_DATE] which is null. Now I want to alter the column with default as getdate(). When I tried the following it gave me an error.
ALTER TABLE sample
ALTER COLUMN [__INSERT_DATE] [datetime] DEFAULT (getdate()) NULL)
Can anyone tell me what the problem is?
Try this:
ALTER TABLE MyTable ADD CONSTRAINT
DF_MyTable_Inserted DEFAULT GETDATE() FOR INSERT_DATE
GO
This assumes your table is named MyTable, the column is INSERT_DATE, and the name of the contstraint is to be DF_MyTable_Inserted
Try this:
ALTER TABLE sample ADD CONSTRAINT DF_sample___INSERT_DATE DEFAULT(GETDATE()) FOR __INSERT_DATE
ALTER TABLE sample ADD INSERT_DATE [datetime] NOT NULL DEFAULT GetDate()
This will works in Microsoft SQL Server
MSDN gives this example:
ALTER TABLE MyCustomers ALTER COLUMN CompanyName SET DEFAULT 'A. Datum Corporation'
That would give you
ALTER TABLE sample ALTER COLUMN __INSERT_DATE SET DEFAULT GETDATE()
I was able to do it using SSManagement Studio
make the date field not nullable, then from properties
set Defalut Value or Binding to getdate()
ALTER TABLE sample
ALTER COLUMN [__INSERT_DATE] [datetime] DEFAULT (getdate()) NULL)
You have one too many closing brackets in the above statement. There are 2 of these -> ( but 3 of these -> )
(Your_Date_Column) Make it Null / Not Null and give default value GetDate() but still it will not work.
You have to create a trigger like this,
CREATE TRIGGER [dbo].[Trigger_Date]
ON [dbo].[TableName]
FOR INSERT
AS
BEGIN
Declare #Id int
set #Id = (select Id from inserted)
Update [dbo].[TableName]
Set Your_Date_Column = GetDate()
Where Id = #Id
END
This way worked for me:
ALTER TABLE sample ALTER COLUMN INSERT_DATE [datetime] NULL DEFAULT GetDate()
If you already have values in the column, you can do something like this:
Alter Table sample add INSERT_DATE_TEMP [datetime] NOT NULL DEFAULT GetDate()
Update sample
SET INSERT_DATE_TEMP = INSERT_DATE
Alter Table sample Drop Column INSERT_DATE
exec sp_rename 'sample.INSERT_DATE_TEMP','INSERT_DATE','COLUMN'
Does getdate() return the correct date and time datatype for your declared column? There are some new date and time datatypes in SQL Server 2008.
Here's an article that explains some of the differences.
http://www.sql-server-performance.com/articles/dev/datetime_2008_p1.aspx

CHECK CONSTRAINT on multiple columns

I use SQL Server 2008
I use a CHECK CONSTRAINT on multiple columns in the same table to try to validate data input.
I receive an error:
Column CHECK constraint for column
'AAAA' references another column,
table 'XXXX'.
CHECK CONSTRAINT does not work in this way.
Any other way to implement this on a single table without using FK?
Thanks
Here an example of my code
CREATE TABLE dbo.Test
(
EffectiveStartDate dateTime2(2) NOT NULL,
EffectiveEndDate dateTime2(2) NOT NULL
CONSTRAINT CK_CmsSponsoredContents_EffectiveEndDate CHECK (EffectiveEndDate > EffectiveStartDate),
);
Yes, define the CHECK CONSTRAINT at the table level
CREATE TABLE foo (
bar int NOT NULL,
fred varchar(50) NOT NULL,
CONSTRAINT CK_foo_stuff CHECK (bar = 1 AND fred ='fish')
)
You are declaring it inline as a column constraint
...
fred varchar(50) NOT NULL CONSTRAINT CK_foo_fred CHECK (...)
...
Edit, easier to post than describe. Fixed your commas.
CREATE TABLE dbo.Test
(
EffectiveStartDate dateTime2(2) NOT NULL,
EffectiveEndDate dateTime2(2) NOT NULL, --need comma
CONSTRAINT CK_CmsSponsoredContents_EffectiveEndDate CHECK (EffectiveEndDate > EffectiveStartDate) --no comma
);
Of course, the question remains are you using a CHECK constraint where it should be an FK constraint...?
Check constraints can refer to a single column or to the whole record.
Use this syntax for record-level constraints:
ALTER TABLE MyTable
ADD CONSTRAINT MyCheck
CHECK (...your check expression...)
You can simply apply your validation in a trigger on the table especially that either way the operation will be rolled back if the check failed.
I found it more useful for CONSTRAINT using case statements.
ALTER TABLE dbo.ProductStock
ADD
CONSTRAINT CHK_Cost_Sales
CHECK ( CASE WHEN (IS_NOT_FOR_SALE=0 and SAL_CPU <= SAL_PRICE) THEN 1
WHEN (IS_NOT_FOR_SALE=1 ) THEN 1 ELSE 0 END =1 )