How to limit a date constraint to only allow a user to enter dates that fall on a specific day of the week in Oracle SQL - sql

I've been stuck with this problem for a few days now and I've been through many different questions that i've found via google/stack overflow but I've been unable to solve it.
I need to create a table that allows a user to enter a date for an appointment, one of the constraints is that the date that is entered can only be a date that is a monday or a friday.
Here are several of my attempts, some worked in that they allow me to create the table, but then when it comes to entering data, it says invalid month, invalid datatype or a plethora of other errors. (I've also removed other columns from the below code just because they're not relevant to the question).
CREATE TABLE t_appointments
(appointment_id NUMBER(10,0) CONSTRAINT appointments_appoint_id_pk PRIMARY KEY,
appoint_date DATE CONSTRAINT appointments_app_date_nn NOT NULL
CONSTRAINT appointments_app_date_ck CHECK (to_char(appoint_date,'Day') IN ('Monday','Friday'));
I also tried
CREATE TABLE t_appointments
(appointment_id NUMBER(10,0) CONSTRAINT appointments_appoint_id_pk PRIMARY KEY,
appoint_date DATE CONSTRAINT appointments_app_date_nn NOT NULL
CONSTRAINT appointments_app_date_ck CHECK (to_char(to_date(appoint_date,'DD-MM-YYYY'),'Day') IN ('Monday','Friday'));
Any help would be greatly appreciated, thank you.

This is the issue in Oracle:
Name of day, padded with blanks to display width of the widest name of day in the date language used for this element.
So, try this:
CONSTRAINT appointments_app_date_ck CHECK (to_char(appoint_date, 'Day') IN ('Monday ', 'Friday '))
Or, you can do:
CONSTRAINT appointments_app_date_ck CHECK (to_char(appoint_date, 'D') IN ('2', '6'))

Related

Can't figure out the SQL code

CREATE TABLE empinf(
companyid varchar2(5) PRIMARY KEY,
companyname varchar2(30) NOT NULL,
emailid varchar2(20) REFERENCES usrinf(emailid),
Mobile number CONSTRAINT moc CHECK(LENGTH(Mobile)=10),
city varchar2(20),
industrytype varchar2(20),
functionalarea varchar2(20),
membershipplan varchar2(20) CONSTRAINT cmp CHECK(membershipplan in ('TRIAL','PREMIUM MONTHLY','PREMIUM YEARLY')),
dateofsignup date DEFAULT SYSDATE CONSTRAINT chd CHECK( dateofsignup>=SYSDATE ),
dateofrenewal date generated always as
(CASE
WHEN membershipplan='TRIAL' THEN SYSDATE+14
WHEN membershipplan='PREMIUM MONTHLY' THEN SYSDATE+30
WHEN membershipplan='PREMIUM YEARLY' THEN SYSDATE+365
ELSE SYSDATE
END
) virtual,
renewalstatus varchar2(20) CONSTRAINT chrs CHECK(renewalstatus in('ACTIVE','EXPIRED')),
CONSTRAINT mun UNIQUE(Mobile)
)
This code is to be generated in Oracle Express 11G, I am unable to figure out what's wrong with code, it shows 'missing paranthesis error'.
As far as I know, in a virtual column you need to define a deterministic function (a one which return same value, irrespective of when you call it.
You could try to use dateofsignup instead of SYSDATE inside case .
dateofrenewal date generated always as
(CASE
WHEN membershipplan='TRIAL' THEN dateofsignup+14
WHEN membershipplan='PREMIUM MONTHLY' THEN dateofsignup+30
WHEN membershipplan='PREMIUM YEARLY' THEN dateofsignup+365
ELSE dateofsignup
END
) virtual
Or you can remove it from table and use a view.
I forgot the other error (I was concentrating on the first one, so I apologize for the miss). As Thorsten say in other answer, you have a problem to set a check constraint for datesignup in that way.
Other that solution Torstein suggested, another solution could be to add another column (eg. DATE_INSERT DATE DEFAULT SYSDATE)
and write the constraint changing datesignup definition as
dateofsignup date DEFAULT SYSDATE
and add
ALTER TABLE empinf ADD CONSTRAINT chd CHECK( dateofsignup>=DATE_INSERT)
Your missing parenthesis error can be caused by your tries, while you commented some parts of the code.
Tip: I agree with g00dy comment above: create table basic structure with one command, then add constraint with separate commands.
It is strange you are getting a "missing paranthesis" error. Maybe the tool you are using to execute the statement swallows the last paranthesis?
I am getting "ORA-02436: date or system variable wrongly specified in CHECK constraint"
CONSTRAINT chd CHECK( dateofsignup>=SYSDATE )
You cannot use SYSDATE in a check constraint, as SYSDATE is subject to change. A check constraint must be stable and must not depend on the current time, a current session setting or the like. You'd need a trigger to do what you want to do.
After removing that check constraint I get "ORA-54002: only pure functions can be specified in a virtual column expression", which is about for the same reason.
dateofrenewal date generated always as
(CASE
WHEN membershipplan='TRIAL' THEN SYSDATE+14
...
A virtual column must be stable and can only depend on other columns, not on the current time, a current session setting or the like. You probably want dateofrenewal to be calculated based on dateofsignup instead.

Oracle Application Express - 'ORA-01843: not a valid month error' in one table only

I am creating a database in Oracle Application Express and am having a problem inserting a date into one of the tables.
INSERT INTO VIEWING( VIEWING_ID, VIEWING_DATE, TIME, PROPERTY_ID, AGENT_ID)
VALUES('3', '12-07-2015' ,'10:00','1', '101');
I've tried every combination of date format, and trying to force the date to my correct format
to_date('12-07-2015','MM-DD-YYYY')
But nothing is working
CREATE TABLE Viewing (
Viewing_ID number(10) NOT NULL,
Viewing_Date date NOT NULL,
Time timestamp(7) NOT NULL,
Property_ID number(10) NOT NULL,
Agent_ID number(10) NOT NULL,
PRIMARY KEY (Viewing_ID));
ALTER TABLE Viewing ADD CONSTRAINT FK_Viewing_Agent_ID FOREIGN KEY (Agent_ID) REFERENCES Agent (Agent_ID);
ALTER TABLE Viewing ADD CONSTRAINT FK_Viewing_Property_ID FOREIGN KEY (Property_ID) REFERENCES Property (Property_ID);
Every Resource I have found suggests it is most likely a parsing or syntax error but so far nothing has helped.
I have a second table in the schema that I can insert dates into without a problem, the only difference on this table is that the date is required (I have tried making it nullable to test and I still get the same error)
I should point out that Im am completely new to Oracle and this is part of a study project. If I had I choice I would be using SQL Server! But Ive been at this for hours and think its time to admit defeat!
Thanks
It is due to TIME column, not VIEWING_DATE. This worked:
INSERT INTO VIEWING( VIEWING_ID, VIEWING_DATE, TIME, PROPERTY_ID, AGENT_ID)
VALUES(4, date '2015-12-07' , timestamp '2015-12-07 10:00:00',1, 101);

I need help writing a check constraint on a smalldatetime column

I need to add a Check constraint to a Column named Departure. This column has the smalldatetime data type.
The Check Constraint should state that:
The date and time entered in the Departure column must be at least 6 hours from whatever the current time is when the date is being entered.
Can anyone help with the code.
Thank you
This should do it:
ALTER TABLE [YourTableName]
ADD CONSTRAINT DepartureLaterThan6Hours CHECK ([Departure] > dateadd(HOUR, 6, GetDate()));

SQL Create Table Default value as specific date

I'm using Oracle's APEX and trying to set the default date of one of my columns to '31-dec-2013', but for the life of me, it's not happening. I've tried many syntax variations and gotten a number of errors such as "not a valid month" and "such a unique or primary key exists" something to that effect. Please help! here's my code:
Create Table Lease(
LeaseNo number(8) not null unique,
PropertyID number(6) not null,
ClientId varchar2(4) not null,
Leasestartdate date not null,
LeaseEndDate date dEFAULT ('31-12-2013'),
MonthlyRent number(8,2) check (MonthlyRent >1000),
Primary Key (LeaseNo),
Foreign key (propertyId) references property(Propertyid),
Foreign key (clientId) references client(clientid));
It threw the "not a valid month" error.
You can use to_date with an explicit date format model as ThorstenKettner shows, which means you won't be relying on the session's NLS_DATE_FORMAT. You can also use a date literal, which is always in YYYY-MM-DD format:
...
LeaseEndDate date default date '2013-12-31',
...
Largely a matter of personal preference between the two though; I happen to prefer this, partly because it's slightly less typing, but also because there is no possibility of ambiguity between DD-MM and MM-DD.
Use TO_DATE to convert a string to date:
...
LeaseEndDate date default to_date('31-12-2013','dd-mm-yyyy')
...
Here are 2 Corrections
First remove UNIQUE clause from LeaseNo, you cant make a cols primary key that has the unique Constraint already.
And, try this Format in default clause - '31-DEC-2013'

Oracle Check Constraint Issue with to_date

So I'm new to Oracle, trying to create a table as follows:
create table Movies (
Title varchar2 primary key,
Rating NUMBER CONSTRAINT Rating_CHK CHECK (Rating BETWEEN 0 AND 10),
Length NUMBER CONSTRAINT Length_CHK CHECK (Length > 0),
ReleaseDate DATE CONSTRAINT RDATE_CHK
CHECK (ReleaseDate > to_date('1/1/1900', 'DD/Month/YYYY')),
CONSTRAINT title_pk PRIMARY KEY (Title)
)
Per my assignment, the ReleaseDate must have a constraint enforcing only dates after 1/1/1900. The input my professor has given us for dates is as follows: 13 August 2010
Can one of you experts see where my issue lies?
The spec for Title column is incorrect, as well as the date string/format model combination in your to_date function call. Specify a column length for TITLE, and fix the date string to match the format model.
Try this:
create table Movies (
Title varchar2(100),
Rating NUMBER CONSTRAINT Rating_CHK CHECK (Rating BETWEEN 0 AND 10),
Length NUMBER CONSTRAINT Length_CHK CHECK (Length > 0),
ReleaseDate date CONSTRAINT RDATE_CHK CHECK (ReleaseDate > to_date('1/January/1900', 'DD/Month/YYYY')),
CONSTRAINT title_pk PRIMARY KEY (Title)
)
Update:
As an aside, Title is a lousy primary key. Ever hear of two different movies with the same title? Can you say "remake"?
Another edit. I guess since your prof gave you the date format, you should make the date string match the format model. I've updated my answer.
I think 'Month' in TO_DATE is looking for a month name - not a number.
Either change the second 1 to January or change Month to MM.