SQL Create Table Default value as specific date - sql

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'

Related

How to set constraints based on the values of columns?

I'm working on a table of requests to link an user to another user and these requests must be approved to happen.
CREATE TABLE IF NOT EXISTS requests (
requested_at timestamp DEFAULT CURRENT_TIMESTAMP NOT NULL,
approved_at timestamp DEFAULT CURRENT_TIMESTAMP NOT NULL,
denied_at timestamp DEFAULT CURRENT_TIMESTAMP NOT NULL,
user1_id int NOT NULL,
user2_id int NOT NULL,
UNIQUE(user1_id, user2_id),
CONSTRAINT fk_requests_user FOREIGN KEY (user1_id) REFERENCES user(id),
CONSTRAINT fk_requests_user FOREIGN KEY (user2_id) REFERENCES user(id), );
Right now I have a constraint that prevent further requests of one user to another through:
UNIQUE(user1_id, user2_id)
But I want to be able to use this as history, so I need a way to these foreign keys be UNIQUE if both approved_at and denied_at are '1970-01-01 00:00:00'(zero value of TIMESTAMP).
I thought of this logic, though SYNTACTICALLY WRONG:
UNIQUE(user1_id, user2_id, approved_at='1970-01-01 00:00:00', denied_at='1970-01-01 00:00:00')
How can I make it possible?
Use a partial unique index:
create unique index on requests (requester_id, requested_agency_id)
where approved_at='1970-01-01 00:00:00'
and denied_at='1970-01-01 00:00:00'
Having magic values like that is usually not a good choice. Use null to indicate the absence of a value. Or -infinity if you need range queries to work without checking for null.

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

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'))

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.

"Not a valid month" or number

Getting this error while trying to put a few inserts into a table.
Getting an error regarding not a valid month and when I try change it around i'm getting invalid number error.
ORA-01843: not a valid month ORA-06512: at "SYS.DBMS_SQL"
Code:
CREATE TABLE ExpenseReport (
ERNo NUMERIC(10) NOT NULL,
ERDesc VARCHAR(255) NOT NULL,
ERSubmitDate DATE DEFAULT CURRENT_TIMESTAMP,
ERStatusDate DATE NOT NULL,
ERStatus VARCHAR(8) DEFAULT 'PENDING',
SubmitUserNo NUMERIC(10) NOT NULL,
ApprUserNo NUMERIC(10) NOT NULL,
CONSTRAINT ExpenseReport_CK1 CHECK (ERStatusDate >= ERSubmitDate),
CONSTRAINT ExpenseReport_CK2 CHECK (ERStatus = 'PENDING'/'APPROVED'/'DENIED'),
CONSTRAINT ExpenseReport_PK1 PRIMARY KEY(ERNo),
CONSTRAINT ExpenseReport_FK1 FOREIGN KEY(SubmitUserNo) REFERENCES Users(UserNo),
CONSTRAINT ExpenseReport_FK2 FOREIGN KEY(ApprUserNo) REFERENCES (USerNo)
);
INSERT INTO ExpenseReport
(ERNo, ERDesc, ERSubmitDate, ERStatusDate, ERStatus, SubmitUserNo, ApprUSerNo)
VALUES (1,'Sales Presentation','8/10/2002','8/26/2002','APPROVED',3,4);
I've also tried using the TO_DATE but having no luck there,
by any chance can anyone see where i'm going wrong.
Use the DATE keyword and standard date formats:
INSERT INTO ExpenseReport (ERNo, ERDesc, ERSubmitDate, ERStatusDate, ERStatus, SubmitUserNo, ApprUSerNo)
VALUES (1, 'Sales Presentation', DATE '2001-08-10', DATE '2001-08-2006', 'APPROVED', 3, 4);
In addition to the satisfaction of using standard date formats, this protects you against changes in local settings.
In your DDL statement:
CONSTRAINT ExpenseReport_CK2 CHECK (ERStatus = 'PENDING'/'APPROVED'/'DENIED')
Should be:
CONSTRAINT ExpenseReport_CK2 CHECK (ERStatus IN ( 'PENDING', 'APPROVED', 'DENIED' ) )
When you are trying to insert values the check constraint is being evaluated and it is trying to perform a division operation on the three string values'PENDING'/'APPROVED'/'DENIED' which results in ORA-01722: invalid number.
Once you change this then using TO_DATE('01/01/02','DD/MM/YY') (as you wrote in comments) or an ANSI date literal DATE '2002-01-01' should work in your DML statements.
(Note: Be careful using 2-digit years or you can find that dates are inserted with the wrong century.)
Check your date format: select sysdate from dual;
and enter as it show. OR
change your date format: alter session set nls_date_format= 'DD-Mon-YYYY HH24:MI:SS';
It Was Easy :
if Your code Like This just remove hem and write that
Example :
Your code : values ('30178','K111', '22/12/2008')
Do This : values ('30178','K111', '22/Dec/2008')

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.