I am a beginner with SQL. I have created 4 tables and added data to my SHIP table. I am having some issues with inserting data into the CRUISE table. I get the error message at the bottom.
I have researched and can not figure out what i am doing wrong. Is there an issue with my sequence and/or trigger that is not allowing me to do this or is my syntax in the CREATE TABLE CRUISE causing the error? Everything i have done has been successful up until trying to insert the first column into the CRUISE table.
The tables:
CREATE TABLE SHIP
( Ship_Name VARCHAR2(100) PRIMARY KEY,
Ship_Size INTEGER,
Ship_Registry VARCHAR2(50),
Ship_ServEntryDate INTEGER,
Ship_PassCapacity INTEGER,
Ship_CrewCapacity INTEGER,
Ship_Lifestyle VARCHAR2(40),
CONSTRAINT Size_ck CHECK (Ship_Size > 0),
CONSTRAINT Registry_ck CHECK (Ship_Registry IN ('Norway','Liberia','The Netherlands','Bahamas'))
)
CREATE TABLE CRUISE (
Cruise_ID INTEGER Primary Key,
Ship_Name VARCHAR(100),
Cruise_DeptDate DATE NOT NULL,
Cruise_DeptCity VARCHAR(80) NOT NULL,
Cruise_Duration INTEGER,
FOREIGN KEY (Ship_Name) REFERENCES SHIP(Ship_Name)
)
CREATE TABLE PASSENGERS (
Pass_ID INTEGER PRIMARY KEY,
Pass_Name VARCHAR(100) NOT NULL,
Pass_City VARCHAR(80),
Pass_Telephone VARCHAR(15),
Pass_NextOfKin VARCHAR(100)
)
CREATE TABLE RESERVATIONS (
Pass_ID INTEGER NOT NULL,
Cruise_ID INTEGER NOT NULL,
Res_TotalCost NUMERIC(9,2),
Res_BalanceDue NUMERIC(9,2),
Res_SpecialRequest VARCHAR(30),
Res_Room VARCHAR(10),
FOREIGN KEY (Pass_ID) REFERENCES PASSENGERS(Pass_ID),
FOREIGN KEY (Cruise_ID) REFERENCES CRUISE(Cruise_ID),
CONSTRAINT Cost_ck CHECK (Res_TotalCost >= 0),
CONSTRAINT BalanceDue_ck CHECK (Res_BalanceDue >= 0),
CONSTRAINT SpecialRequest_ck CHECK (Res_SpecialRequest IN ('Vegetarian','Vegan','Low salt','Gluten free','Kosher','Other'))
)
The sequence/trigger is an attempt to auto number Cruise_ID.
Create SEQUENCE cruise_id_sq
START WITH 1
INCREMENT BY 1;
CREATE OR REPLACE TRIGGER cruise_id_t
BEFORE INSERT
ON CRUISE
REFERENCING NEW AS NEW
FOR EACH ROW
BEGIN
if(:new.Cruise_ID is null) then
SELECT cruise_id_sq.nextval
INTO :new.Cruise_ID
FROM dual;
end if;
END;
ALTER TRIGGER cruise_id_t ENABLE;
Inserting into SHIP is okay....
INSERT INTO SHIP
(Ship_Name, Ship_Size, Ship_Registry,Ship_ServEntryDate, Ship_PassCapacity,Ship_CrewCapacity,Ship_Lifestyle)
Values ('Carribean Princess',142000,'Liberia',1000,3100,1181,'Contemporary');
INSERT INTO SHIP
(Ship_Name, Ship_Size, Ship_Registry,Ship_ServEntryDate, Ship_PassCapacity,Ship_CrewCapacity,Ship_Lifestyle)
Values ('Carribean Sunshine',74000,'Norway',1992,1950,760,'Premium');
INSERT INTO SHIP
(Ship_Name, Ship_Size, Ship_Registry,Ship_ServEntryDate, Ship_PassCapacity,Ship_CrewCapacity,Ship_Lifestyle)
Values ('Ship of Dreams',70000,'Liberia',2004,1804,735,'Contemporary');
INSERT INTO SHIP
(Ship_Name, Ship_Size, Ship_Registry,Ship_ServEntryDate, Ship_PassCapacity,Ship_CrewCapacity,Ship_Lifestyle)
Values ('Sunshine of the Seas',74000,'The Netherlands',1990,2354,822,'Luxury');
Inserting into CRUISE fails...
INSERT INTO Cruise
(Ship_Name, Cruise_DeptDate,Cruise_DeptCity,CruiseDuration)
Values ('Sunshine of the Seas',25-may-15,'Miami',10);
Error starting at line : 1 in command - INSERT INTO Cruise (Ship_Name,
Cruise_DeptDate,Cruise_DeptCity,CruiseDuration) Values ('Sunshine of
the Seas',25-may-15,'Miami',10) Error at Command Line : 3 Column : 35
Error report - SQL Error: ORA-00984: column not allowed here
00984. 00000 - "column not allowed here"
*Cause:
*Action:
Oracle thinks that 25-may-15 is the expression 25 minus may minus 15. In looking up the value for may Oracle finds that there is nothing there. Thus the error.
You can, but probably don't want to, quote it like so, '25-may-15'. This will make a string that may or may not be implicitly converted to a date, depending on the settings of NLS_DATE_FORMAT and or NLS_TERRITORY.
To form a date independent of session setting one can use the TO_DATE function with explicit date format, to_date('25-may-15', 'DD-Mon-YY'). Another option is a date literal, date '2015-05-25', which is always YYYY-MM-DD no matter the session settings..
Related
I am beginner in sql.I am using sqlplus to run the sql query .I used simple query but it shows an error like "MISSING RIGHT PARENTHESIS".My objective is to create the autoincrement primary key .Can anyone solve the error?Thanks in advance...
create table student(rollno int identity(1,1) primary key,
name varchar(20),marks int);
For Oracle, the rollno column could be defined as NUMBER(0010) and primary key.
Then you would need to add an ON INSERT trigger to populate rollno from a SEQUENCE. There are many samples of triggers and sequences on this site.
In oracle 12 you can use a identity column to automatically fill your ID
CREATE TABLE students
(
"ID" NUMBER GENERATED BY DEFAULT AS IDENTITY MINVALUE 1 MAXVALUE 9999999999
INCREMENT BY 1 START WITH 1 ,
"NAME" VARCHAR2(20),
"MARKS" NUMBER(2,0),
CONSTRAINT PK_STUDENTS PRIMARY KEY (ID) ENABLE
);
/
This creates a table without any triggers needed and automatically fills the id column (of not specified with a value) with the next number up to 99999...
If you're using oracle 11 and below, you need a trigger on insert and assign a value (custom_sequence.nextval) to the id column.
CREATE TABLE students
(
"ID" NUMBER(5,0) not null,
"NAME" VARCHAR2(20),
"MARKS" NUMBER(2,0),
CONSTRAINT PK_STUDENTS PRIMARY KEY (ID) ENABLE
);
/
CREATE SEQUENCE SEQ_STUDENTS INCREMENT BY 1 START WITH 1;
/
TRIGGER TC_students
before insert on students
for each row
begin
if (:new.id is null) then
select SEQ_students.nextval into :new.id from dual;
end if;
end;
/
And please use VARCHAR2.
CREATE TABLE Time(
Tipo VARCHAR(15) PRIMARY KEY,
DataInizio DATE,
DataFine DATE NOT NULL);
INSERT INTO Time VALUES('PreIscrizione', '2017-02-01', '2017-04-30');
INSERT INTO Time VALUES('Candidatura', '2017-05-01', '2017-07-30');
CREATE TABLE PreIscrizione(
Studente VARCHAR(16) REFERENCES Persona ON DELETE CASCADE ON UPDATE CASCADE PRIMARY KEY,
DataPreIscrizione DATE CHECK(DataPreIscrizione<(SELECT DataFine FROM Time WHERE Tipo = 'PreIscrizione')));
The table PreIscrizione allows to sign up a student, but it has to be done before a date indicated in the table Time. Obviously what i wrote above doesn't work, but it explains my idea. Which is the right way to solve this?
I'm try to create table with clever sequence generator for using this insert-strucure:
insert into SOMEUSERS (SOMEUSERS_NAME, SOMEUSERS_PASSWORD)
values ('Artem', 'PracTimPatie');
instead of this:
insert into SOMEUSERS (SOMEUSERS_ID, SOMEUSERS_NAME, SOMEUSERS_PASSWORD)
values (2, 'Artem', 'PracTimPatie');
or this structure:
insert into SOMEUSERS (SOMEUSERS_ID, SOMEUSERS_NAME, SOMEUSERS_PASSWORD)
values (GEN_ID_SOMEUSERS.nextval, 'Artem', 'PracTimPatie');
When I executing the following sql script:
create sequence gen_id_someUsers START WITH 1 INCREMENT BY 1 NOCACHE NOCYCLE;
CREATE TABLE loc_db.someUsers
( someUsers_id number(10) DEFAULT gen_id_someUsers.NEXTVAL NOT NULL, --because of this row
someUsers_name varchar2(50) NOT NULL,
someUsers_password varchar2(50),
CONSTRAINT someUsers_pk PRIMARY KEY (someUsers_id)
);
the following notice is given to me:
Error report - SQL Error: ORA-00984: column not allowed here
00984. 00000 - "column not allowed here"
For clarity, said that in this case:
...
CREATE TABLE loc_db.someUsers
( someUsers_id number(10) NOT NULL, --correct this row
...
Sequence GEN_ID_SOMEUSERS created.
Table LOC_DB.SOMEUSERS created.
How can I configure comfortable sequence generator?
(in case of PostgreSQL too. If possible with no trigger(as easily as possible)
Oracle 12c introduces Identity columns:
CREATE TABLE SOMEUSERS (
SOMEUSERS_ID NUMBER(10) GENERATED ALWAYS AS IDENTITY
CONSTRAINT SOMEUSERS__SOMEUSERS_ID__PK PRIMARY KEY,
SOMEUSERS_NAME VARCHAR2(50)
CONSTRAINT SOMEUSERS__SOMEUSERS_NAME__NN NOT NULL,
SOMEUSERS_PASSWORD VARCHAR2(50)
);
If you want to do it in earlier versions then you will need a trigger and a sequence:
CREATE TABLE SOMEUSERS (
SOMEUSERS_ID NUMBER(10)
CONSTRAINT SOMEUSERS__SOMEUSERS_ID__PK PRIMARY KEY,
SOMEUSERS_NAME VARCHAR2(50)
CONSTRAINT SOMEUSERS__SOMEUSERS_NAME__NN NOT NULL,
SOMEUSERS_PASSWORD VARCHAR2(50)
);
/
CREATE SEQUENCE gen_id_someUsers START WITH 1 INCREMENT BY 1 NOCACHE NOCYCLE;
/
CREATE OR REPLACE TRIGGER SOMEUSERS__ID__TRG
BEFORE INSERT ON SOMEUSERS
FOR EACH ROW
BEGIN
:new.SOMEUSERS_ID := gen_id_someUsers.NEXTVAL;
END;
/
You can then just do (either with the identity column or the trigger combined with your sequence):
INSERT INTO SOMEUSERS (
SOMEUSERS_NAME,
SOMEUSERS_PASSWORD
) VALUES (
'Name',
'Password'
);
In postgres just use a serial like this:
CREATE TABLE SOMEUSERS (
SOMEUSERS_ID serial NOT NULL,
SOMEUSERS_NAME text,
SOMEUSERS_PASSWORD text
);
Your insert statement is then easy as:
INSERT INTO SOMEUSERS (SOMEUSERS_NAME, SOMEUSERS_PASSWORD)
values ('Artem', 'PracTimPatie');
If you wanna query the sequence you can just query it like any other relation.
Other answers have addressed postgreSQL and Oracle 12c, so I'll address Oracle 11.2 or earlier here.
From the 11.1 SQL Reference Manual:
DEFAULT
The DEFAULT clause lets you specify a value to be assigned to the column if a subsequent INSERT statement omits a value for the column. The datatype of the expression must match the datatype of the column. The column must also be long enough to hold this expression.
The DEFAULT expression can include any SQL function as long as the function does not return a literal argument, a column reference, or a nested function invocation.
Restriction on Default Column Values
A DEFAULT expression cannot contain references to PL/SQL functions or to other columns, the pseudocolumns CURRVAL, NEXTVAL, LEVEL, PRIOR, and ROWNUM, or date constants that are not fully specified.
(Emphasis mine)
So since you can't put sequence.NEXTVAL in as a DEFAULT value you're basically going to have to use a trigger:
CREATE OR REPLACE TRIGGER SOMEUSERS_BI
BEFORE INSERT
ON LOC_DB.SOMEUSERS
FOR EACH ROW
BEGIN
IF :NEW.SOMEUSERS_ID THEN
:NEW.SOMEUSERS_ID := GEN_ID_SOMEUSERS.NEXTVAL;
END IF;
END SOMEUSERS_BI;
In my experience there is no reliable alternative to using a trigger such as this in Oracle 11.2 or earlier.
Best of luck.
This question already has answers here:
Set ORACLE table fields default value to a formular
(2 answers)
Closed 8 years ago.
I got a table which I used the below code to create.
create table Meter (MeterID CHAR(8) CONSTRAINT MeterPK PRIMARY KEY,
Value CHAR(8) CONSTRAINT ValueNN NOT NULL,
InstalledDate Date CONSTRAINT InDateNN NOT NULL);
Then I tried adding a derived column that adds 6 months to the installeddate.
alter table meter add ExpiryDate as (add_months(installedDate,6)) not null;
This returns an error of invalid datatype.
I read somewhere that I do not have to specify the datatype of ExpiryDate as it can be derived from the function. So where did I go wrong?
EDIT: Turns out Mike was right. I used the trigger method to get things going, but I was confused whether I'm using mysql or oracle. Think in the end I'm using oracle actually. Have problems with the trigger but turns out I do not need to have the command "set" in the trigger. Below is the code that works.
CREATE OR REPLACE
TRIGGER trigexpdate1
BEFORE INSERT ON Meter
FOR EACH ROW
BEGIN
:NEW.ExpiryDate := ADD_MONTHS(:NEW.InstalledDate, 6);
END;
If I don't have the begin and end in the statement, it will throw an error saying illegal trigger specification.
MySQL doesn't support
derived columns in table definitions,
a function named add_months(), or
inline constraints.
This is a more or less standard way to write that statement in MySQL.
create table `Meter` (
`MeterID` CHAR(8) NOT NULL,
`Value` CHAR(8) NOT NULL,
`InstalledDate` Date NOT NULL,
primary key (`MeterID`)
);
You have two options for a derived column like "ExpiryDate".
Create a view, and do the date arithmetic in the view. Use date_add().
Add the column "ExpiryDate" to the table, and keep it up-to-date with a trigger.
BEFORE INSERT trigger example
create table `Meter` (
`MeterID` CHAR(8) NOT NULL,
`Value` CHAR(8) NOT NULL,
`InstalledDate` Date NOT NULL,
`ExpiryDate` Date not null,
primary key (`MeterID`)
);
create trigger trigexpdate1
before insert on `Meter`
FOR EACH ROW
SET NEW.`ExpiryDate` = date_add(NEW.`InstalledDate`, interval 6 month);
Note how ExpiryDate changes from the insert statement to the select statement below.
insert into Meter
values ('1', '1', '2014-07-01', '2014-07-01');
select * from Meter;
MeterID Value InstalledDate ExpiryDate
--
1 1 2014-07-01 2015-01-01
I am getting strange errors while trying to create a simple database using isql tools from the Firebird package.
The same code for creating a table works for other tables with other names.
I've tried with and without quotes surrounding fields and table names, no success.
It is Firebird 2.5 server version.
The code I'm trying to execute:
SET SQL DIALECT 3;
SET NAMES UTF8;
CREATE DATABASE 'localhost:C:\fuzzdb.fdb' user 'SYSDBA' password 'masterkey'
DEFAULT CHARACTER SET UTF8;
CREATE TABLE RULES (
RULE_ID INTEGER NOT NULL,
IF_FUZZY SMALLINT,
CONSTRAINT PK_RULE_ID
PRIMARY KEY (RULE_ID),
);
CREATE TABLE VARS (
VAR_ID INTEGER NOT NULL,
VRULE_ID INTEGER,
INPOUTP SMALLINT,
RANGE_STRT INTEGER,
RANGE_END INTEGER,
VAR_NAME VARCHAR(40),
FUZ_SET INTEGER,
CONSTRAINT PK_VAR_ID
PRIMARY KEY (VAR_ID)
);
CREATE TABLE FUZZSETS (
FS_ID INTEGER NOT NULL,
FS_NAME VARCHAR(40),
INPOUTP SMALLINT,
PAR1 FLOAT,
PAR2 FLOAT,
PAR3 FLOAT,
PAR4 FLOAT,
PAR5_HEDGE INTEGER,
FUZ_SET INTEGER,
CONSTRAINT PK_FS_ID
PRIMARY KEY (FS_ID)
);
CREATE TABLE FRULES (
FRULE_ID INTEGER NOT NULL,
RULE_ID INTEGER,
VAR_ID INTEGER,
FS_ID INTEGER,
INPOUTP SMALLINT,
CONSTRAINT PK_FRULE_ID
PRIMARY KEY (FRULE_ID)
);
CREATE TABLE LINK_RV (
LINK_RULES INTEGER,
LINK_VARS INTEGER,
CONSTRAINT FK_LINK_RV
PRIMARY KEY (LINK_RULES, LINK_VARS)
);
CREATE TABLE LINK_VARFS (
LINK_VRS INTEGER,
LINK_FS INTEGER,
CONSTRAINT FK_LINK_VARFS
PRIMARY KEY (LINK_VRS, LINK_FS)
);
CREATE TABLE LINK_RLVR (
LINK_RULE INTEGER NOT NULL,
LINK_VR INTEGER NOT NULL,
CONSTRAINT FK_LINK_RLVR
PRIMARY KEY (LINK_RULE, LINK_VR)
);
CREATE TABLE LINK_FRL_RL (
LINK_FRULE INTEGER NOT NULL,
LINK_RULE INTEGER NOT NULL,
CONSTRAINT FK_LINK_FRL_RL
PRIMARY KEY (LINK_FRULE, LINK_RULE)
);
CREATE TABLE LINK_FRL_VAR (
LINK_FRULE INTEGER NOT NULL,
LINK_VAR INTEGER NOT NULL,
CONSTRAINT FK_LINK_FRL_VAR
PRIMARY KEY (LINK_FRULE, LINK_VAR)
);
CREATE TABLE LINK_FRL_FS (
LINK_FSRULE INTEGER NOT NULL,
LINK_FS INTEGER NOT NULL,
CONSTRAINT FK_LINK_FRL_FS
PRIMARY KEY (LINK_FRULE, LINK_FS)
);
ALTER TABLE LINK_FRL_FS
ADD CONSTRAINT FK_LINK_FSRULE
FOREIGN KEY(LINK_FSRULE)
REFERENCES FRULES(FRULE_ID);
ALTER TABLE LINK_FRL_FS
ADD CONSTRAINT FK_LINK_FS
FOREIGN KEY(LINK_FS)
REFERENCES FUZZSETS(FS_ID);
ALTER TABLE LINK_FRL_VAR
ADD CONSTRAINT FK_LINK_FRULE
FOREIGN KEY(LINK_FRULE)
REFERENCES FRULES(FRULE_ID);
ALTER TABLE LINK_FRL_VAR
ADD CONSTRAINT FK_LINK_VAR
FOREIGN KEY(LINK_VAR)
REFERENCES FUZZSETS(VAR_ID);
ALTER TABLE LINK_FRL_RL
ADD CONSTRAINT FK_LINK_FRULE
FOREIGN KEY(LINK_FRULE)
REFERENCES FRULES(FRULE_ID);
ALTER TABLE LINK_FRL_RL
ADD CONSTRAINT FK_LINK_RULE
FOREIGN KEY(LINK_RULE)
REFERENCES RULES(RULE_ID);
CREATE GENERATOR GEN_RULE_ID;
CREATE GENERATOR GEN_VAR_ID;
CREATE GENERATOR GEN_FS_ID;
CREATE GENERATOR GEN_FRULE_ID;
SET TERM ^ ;
CREATE TRIGGER BI_RULES FOR RULES
ACTIVE BEFORE INSERT POSITION 0
AS
BEGIN
IF (NEW.RULE_ID IS NULL) THEN
NEW.RULE_ID = GEN_ID(GEN_RULE_ID, 1);
END^
CREATE TRIGGER BI_VARS FOR VARS
ACTIVE BEFORE INSERT POSITION 0
AS
BEGIN
IF (NEW.VAR_ID IS NULL) THEN
NEW.VAR_ID = GEN_ID(GEN_VAR_ID, 1);
END^
CREATE TRIGGER BI_FUZZSETS FOR FUZZSETS
ACTIVE BEFORE INSERT POSITION 0
AS
BEGIN
IF (NEW.FS_ID IS NULL) THEN
NEW.FS_ID = GEN_ID(GEN_FS_ID, 1);
END^
CREATE TRIGGER BI_FRULES FOR FRULES
ACTIVE BEFORE INSERT POSITION 0
AS
BEGIN
IF (NEW.FRULE_ID IS NULL) THEN
NEW.FRULE_ID = GEN_ID(GEN_FRULE_ID, 1);
END^
SET TERM ; ^
COMMIT;
The output from the isql commmand:
Use CONNECT or CREATE DATABASE to specify a database
Statement failed, SQLSTATE = 42000
Dynamic SQL Error
-SQL error code = -104
-Token unknown - line 6, column 3
-)
At line 10 in file c:\fdb.sql
Statement failed, SQLSTATE = 42000
unsuccessful metadata update
-Unknown columns in index FK_LINK_FRL_FS
After line 82 in file c:\fdb.sql
Statement failed, SQLSTATE = 42S02
Dynamic SQL Error
-SQL error code = -204
-Table unknown
-LINK_FRL_FS
-At line 1, column 13.
After line 89 in file c:\fdb.sql
Statement failed, SQLSTATE = 42S02
Dynamic SQL Error
-SQL error code = -204
-Table unknown
-LINK_FRL_FS
-At line 1, column 13.
After line 94 in file c:\fdb.sql
Statement failed, SQLSTATE = 42000
unsuccessful metadata update
-could not find UNIQUE or PRIMARY KEY constraint in table FUZZSETS with specifie
d columns
After line 104 in file c:\fdb.sql
Statement failed, SQLSTATE = 42S11
unsuccessful metadata update
-Index FK_LINK_FRULE already exists
After line 109 in file c:\fdb.sql
Statement failed, SQLSTATE = 42000
unsuccessful metadata update
-Table RULES not found
After line 114 in file c:\fdb.sql
Statement failed, SQLSTATE = 42S02
Dynamic SQL Error
-SQL error code = -204
-Table unknown
-RULES
-At line 1, column 29
At line 130 in file c:\fdb.sql
I don't get why it's impossible to create the first table "RULES" although the commands are similar to other tables.
Even without all the triggers and foreign keys (alter table..) I am getting at leaast the last error.
it says "Unknown columns in index FK_LINK_FRL_FS" but no mention of other similar indexing tables.
I am just starting working with databases and it could be that I missed or mixed something,
but I tried to compile with too many changes and still getting errors.
I've found more or less similar code here
http://sergworks.wordpress.com/category/firebird/
and I was able to compile it without problems.
Could somebody point me in the right direction or show how it is done in another way?
You have an unnessesary comma in the end of the PK constraint:
CONSTRAINT PK_RULE_ID
PRIMARY KEY (RULE_ID),
So the parser expexts definition of field or constraint but it finds ")". Delete the comma and you should be OK.