Can't figure out the SQL code - sql

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.

Related

Date constraint

I need a check constraint for date so no data can be entered in the past. I'm using oracle live SQL for a school project and cant find a solution.
(BookingID Varchar2(6) PRIMARY KEY NOT NULL,
App_Date Date NOT NULL,
App_Time varchar2(8) NOT NULL,
Location Varchar2(15) NOT NULL,
Query Varchar(50) NOT NULL);
Oracle interprets check constraints as forever constraints on the data. That is, the check constraint is valid not only when the data changes but forever thereafter.
For this reason, Oracle does not allow volatile functions in check constraints. A volatile function is one whose values can change over time. A very good example are the date/time functions, such as sysdate (which is really a function without parentheses).
So, you cannot do what you want with a check constraint. You need to set this up using an insert trigger.
You can't use sysdate in a check constraint, because, as explained by Gordon Linoff, it is a non-deterministic function (ie the value it gives is not constant over time).
Instead, you can implement the validation with a trigger:
create or replace trigger app_date_not_in_past
before insert or update on mytable
for each row
begin
if (:new.app_date < sysdate)
then
raise_application_error( -20001, 'app_date date must not be in the past' );
end if;
end;
/

i feel like i got this wrong

The commission classification column should be able to store integers up to a maximum value of 99 and be named Comm_id. The value of the Comm_id column should be set to a value of 10 automatically if no value is provided when a row is added. The benefits code column should also accommodate integer values up to a maximum of 99 and be named Ben_id.
alter table ACCTMANAGER
add (Comm_id varchar2(99),
Ben_id varchar2(99));
I dont know if this is right
alter table ACCTMANAGER add(Comm_id number(2) default 10, Ben_id number(2));
Basically for number data type you have precision and scale. and if scale is not specified scale is 0 which means no decimal places after the number. number(2) means you can only store up to two digit number here and default keyword set the value automatically if column was not specified.
BTW try using oracle documentation for this homework type of stuff. here is with good examples.
https://docs.oracle.com/cd/B28359_01/server.111/b28318/datatype.htm#i16209
EDITED
alter table ACCTMANAGER add(Comm_id number(2) default 10 constraint lowchk1 check(comm_id>=0) , Ben_id number(2) constraint lowchk2 check(ben_id>=0));
Sorry I can't check syntax for sure as I don't have Oracle installed at home. I only work at it at office.
#MSStp provided a good answer, but you still need constraints to make sure you don't get bad data in the table (such as negative numbers). If the constraint is that the commission and the benefit columns must contain integers between 0 and 99, and you want to make sure Oracle will not accept an input of 2.2 (which it WILL accept in MS's solution, it will just truncate it to 2 and store 2 in the database), you need to add constraints as Abdul Rehman Sayed suggested in a Comment to your question.
alter table acctmanager
add ( comm_id number(2) default 10
constraint check_comm ( comm_id >= 0 and comm_id = trunc(comm_id) ),
ben_id number(2)
constraint check_ben ( ben_id >= 0 and ben_id = trunc(ben_id) )
)
;
However: Just a thought..... What are comm_id and ben_id? If they are some sort of codes to specific commission and benefit descriptions/levels/whatever, do you really need check constraints? Do you have different tables explaining these codes, where comm_id and ben_id are (or should be) primary keys? In which case you need foreign key constraints, NOT check constraints?
ALTER TABLE ACCTMANGER ADD(Comm_id NUMBER(2) DEFAULT 10 NOT NULL, Ben_id NUMBER(2));
After that, you can see that the table is altered.
To see the Output write this:
DESC ACCTMANAGER;
You will see the whole table with the updated column.

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

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'

SQL unique index without leading zeros

I have set-up a table using the following SQL script:
CREATE TABLE MY_TABLE (
ID NUMBER NOT NULL,
CODE VARCHAR2(40) NOT NULL,
CONSTRAINT MY_TABLE PRIMARY KEY (ID)
);
CREATE UNIQUE INDEX XUNIQUE_MY_TABLE_CODE ON MY_TABLE (CODE);
The problem is that I need to ensure that CODE does not have a leading zero for its value.
How do I accomplish this in SQL so that a 40-char value without a leading zero is stored?
CODE VARCHAR2 NOT NULL CHECK (VALUE not like '0%')
sorry - slight misread on the original spec
If you can guarantee that all INSERTs and UPDATEs to this table are done through a stored procedure, you could put some code there to check that the data is valid and return an error if not.
P.S. A CHECK CONSTRAINT would be better, except that MySQL doesn't support them.