Postgresql: syntax error at or near “.” - sql

Why do I get syntax error at or near “.” ?
CREATE TABLE myschema.products (
product_no SERIAL PRIMARY KEY,
date date,
group_number INTEGER,
CHECK (myschema.products >1 AND myschema.products <1001)
);
CREATE TABLE myschema.orders (
order_id SERIAL PRIMARY KEY,
name varchar,
schedule integer[][]
);
CREATE TABLE myschema.tabletime (
id SERIAL,
products INTEGER,
orders INTEGER,
CONSTRAINT pkey PRIMARY KEY (id),
CONSTRAINT integrity CHECK (products IS NOT NULL
AND orders IS NOT NULL),
CONSTRAINT products_exists FOREIGN KEY(products)
REFERENCES myschema.products(product_no),
CONSTRAINT orders_exists FOREIGN KEY(orders)
REFERENCES myschema.orders(order_id)
);

The error is at the line:
CHECK (myschema.products >1 AND myschema.products <1001)
you cannot use the name of the relation inside a check, only the name of the columns. The manual says:
Currently, CHECK expressions cannot contain subqueries nor refer to variables other than columns of the current row.

Related

Oracle SQL "invalid identifier error" when trying to create a table

I have successfully built these tables:
CREATE TABLE Tables
(
tnum NUMBER(4) PRIMARY KEY,
floor NUMBER(1), CHECK (floor >= 0 AND floor <= 4),
capacity NUMBER(2), CHECK(capacity >= 0 AND capacity <= 25),
location VARCHAR(50)
);
CREATE TABLE Customer
(
name VARCHAR(25),
phone VARCHAR(16),
city VARCHAR(25),
PRIMARY KEY(name, phone)
);
CREATE TABLE Menu
(
pid NUMBER(4) PRIMARY KEY,
pname VARCHAR(25),
price NUMBER(4, 1)
);
BUT when I try build this one, I got an error:
Error report -
ORA-00904: : invalid identifier
00904. 00000 - "%s: invalid identifier"
*Cause:
*Action:
CREATE TABLE Orders
(
orderid NUMBER(4) PRIMARY KEY,
custname VARCHAR(25),
CONSTRAINT fk_customer
FOREIGN KEY (custname)
REFERENCES Customer(customer.name),
phone VARCHAR(16),
CONSTRAINT fk_customer
FOREIGN KEY(phone)
REFERENCES Customer(customer.phone),
date DATE,
tnum NUMBER(4),
CONSTRAINT fk_tables
FOREIGN KEY(tnum)
REFERENCES Tables(tables.tnum),
numofdiners NUMBER(2)
);
I tried to understand what can cause the problem, even though I checked this link and some more other links, I didn't manage to solve the problem.
You can specify a column level constraint directly after the column, but then you have to get rid of the comma and the foreign key part as it's clear which column is meant.
But you need to include all columns of the primary key in the foreign key definition. And because the primary key of the customer table consist of two columns, you can't use an inline foreign key in the table orders.
The foreign key "references" part needs to specify the column name in the target table without a prefix for the table (the table is already clear because of the references table_xxx part, so there is no need to prefix the target column with the table name).
Additionally DATE is a reserved keyword.
CREATE TABLE Orders
(
orderid NUMBER(4) PRIMARY KEY,
custname VARCHAR(25) not null
phone VARCHAR(16) not null,
reservation_date DATE,
tnum NUMBER(4) --<< no comma here!
-- no FOREIGN KEY keyword here
CONSTRAINT fk_tables
REFERENCES Tables(tnum), --<< only the column name between the (...)
numofdiners NUMBER(2), --<< you need a comma before the table level constraints
CONSTRAINT fk_customer
FOREIGN KEY(name, phone) --<< list both columns here
REFERENCES Customer(name, phone) --<< and here
);
Note that the columns in a multi-column foreign key are matched by position, not by name.
Therefore, the following would be wrong
CONSTRAINT fk_customer
FOREIGN KEY(phone, name)
REFERENCES Customer(name, phone)

How to fix "ERROR: FK name length exceeds maximum allowed length(30)" in SQL Developer Data Modeller

I'm trying to turn the Logical Model of my Database into a DDL script, but I don't know how to fix this error in the DDL script or Data Modeller:-- ERROR: FK name length exceeds maximum allowed length(30)
It seems to be based on my junction-table's Primary Key, which is made up from two Foreign Keys from the two neighboring tables.
I have tried changing the names of the Primary Keys in the neighboring tables, but when I try to generate a NEW DDL script with Data Modeler, it still generates the old script.
Here's the sections of code that create the 3 tables and link them together:
CREATE TABLE items (
item_no NUMBER (8) NOT NULL,
"year" DATE,
price NUMBER (20,2)
);
ALTER TABLE items ADD CONSTRAINT items_pk PRIMARY KEY ( item_no );
CREATE TABLE purchase_order (
order_no NUMBER(8) NOT NULL,
quantity INTEGER,
item_description VARCHAR2(200),
unit_price NUMBER(20,2),
total NUMBER(20,2),
order_date DATE,
sales_person_code VARCHAR2(5) NOT NULL,
supplier_id NUMBER(3) NOT NULL
);
ALTER TABLE purchase_order ADD CONSTRAINT purchase_order_pk PRIMARY KEY ( order_no );
CREATE TABLE purchase_order_items (
purchase_order_order_no NUMBER(8) NOT NULL,
items_item_no NUMBER(8) NOT NULL
);
ALTER TABLE purchase_order_items ADD CONSTRAINT purchase_order_items_pk PRIMARY KEY ( items_item_no,
purchase_order_order_no );
ALTER TABLE purchase_order_items
ADD CONSTRAINT purchase_order_items_items_fk FOREIGN KEY ( items_item_no )
REFERENCES items ( item_no );
-- ERROR: FK name length exceeds maximum allowed length(30)
ALTER TABLE purchase_order_items
ADD CONSTRAINT purchase_order_items_purchase_order_fk FOREIGN KEY ( purchase_order_order_no )
REFERENCES purchase_order ( order_no );
ALTER TABLE purchase_order
ADD CONSTRAINT purchase_order_sales_person_fk FOREIGN KEY ( sales_person_code )
REFERENCES sales_person ( code );
ALTER TABLE purchase_order
ADD CONSTRAINT purchase_order_supplier_fk FOREIGN KEY ( supplier_id )
REFERENCES supplier ( id );
So I'm not sure exactly what FK name length is too long and what I need to change in the script to fix this error.
Oracle limits identifiers to 30 characters, so
purchase_order_items_purchase_order_fk needs to be shorted. Perhaps to something like poi_purchase_porder_fk.

Cannot create table. SQL Error 02270

This is the table I am trying to create. However, I get the error
SQL Error: ORA-02270: no matching unique or primary key for this column-list
SQL:
create table Meets_In
(
cid char(20),
rno integer,
time char(20),
CONSTRAINT PRIM_KEY PRIMARY KEY(time),
constraint meets_fk1 foreign key(cid) references COURSES(CID),
constraint meets_fk2 foreign key(rno) references ROOMS(RNO)
);
These are the parent tables:
create table Courses
(
cid char(20),
cname char(20),
credits integer,
constraint CoursesKey Primary Key (cid, cname)
);
CREATE TABLE ROOMS
(
rno INTEGER,
address CHAR(20),
capacity INTEGER,
CONSTRAINT room_key PRIMARY KEY(rno)
);
I don't understand why I am getting this error.
Cause
The ORA-2270, as the error message suggests, happens when there is no matching unique or primary key for this column-list. This could be because
the parent lacks a constraint altogether
the parent table's constraint is a compound key and we haven't referenced all the columns in the foreign key statement.
Now in your COURSES table, CID is not a primary key. It is a combination of cid,cname. So for every cid, there can be multiple rows.
Now when you reference cid as foreign key for meets_in, it will not work as it violates the second point as I mentioned above.
Workaround
Add column cname in your meets_in table as well. Then use it like below.
create table Meets_In
(
cid char(20) not null,
cname char(20),
rno integer not null,
time1 char(20) not null,
CONSTRAINT PRIM_KEY PRIMARY KEY(time1),
constraint meets_fk1 foreign key(cid,cname) references COURSES (cid,cname), /*Added cid,cname */
constraint meets_fk2 foreign key(rno) references ROOMS (RNO)
);
Meets_In is acting as an associative table. Therefore its primary key should include the foreign keys into the tables it is associating.
Try a primary key consisting of: cid, cname, rno and time.
As others have noted, your primary key for courses is (cid, cname), so you also need to include both of these in your foreign key constraint meets_fk1. Or, if possible, ensure that cid only is the primary key on courses.
(I think time may be a reserved word, so perhaps consider renaming it.)

Foreign keys referring other foreign keys in PostgreSQL

In PostgreSQL I have a database, which I intend to make the following table declaration:
CREATE TABLE canvas_user (
id INTEGER,
login_id VARCHAR(50) UNIQUE NOT NULL,
email VARCHAR(355) UNIQUE NOT NULL,
name_given VARCHAR(30),
name_family VARCHAR(30),
name_full VARCHAR(50),
role canvas_role,
last_login TIMESTAMP,
PRIMARY KEY (id)
);
CREATE TABLE problem (
id SERIAL,
title VARCHAR(50),
author VARCHAR(50),
path TEXT,
compiler VARCHAR(20),
PRIMARY KEY (id)
);
CREATE TABLE assignment (
id INTEGER,
title TEXT NOT NULL,
points_possible INTEGER NOT NULL,
problem_id INTEGER,
PRIMARY KEY (id),
FOREIGN KEY (problem_id) REFERENCES problem(id)
);
CREATE TABLE submission (
num SERIAL,
user_id INTEGER,
assignment_id INTEGER,
timestamp TIMESTAMP,
path TEXT,
lti_info TEXT[],
PRIMARY KEY(num, user_id, assignment_id),
FOREIGN KEY (user_id) REFERENCES canvas_user(id),
FOREIGN KEY (assignment_id) REFERENCES assignment(id)
);
CREATE TABLE correction (
num INTEGER,
user_id INTEGER,
assignment_id INTEGER,
timestamp TIMESTAMP,
path TEXT,
execution_time interval,
PRIMARY KEY(num, user_id, assignment_id),
FOREIGN KEY (num) REFERENCES submission(num),
FOREIGN KEY (user_id) REFERENCES submission(user_id),
FOREIGN KEY (assignment_id) REFERENCES submission(assignment_id)
);
Everything works fine, except for the following error at the creation of the last table (correction):
ERROR: there is no unique constraint matching given keys for
referenced table "submission"
What I intend with the correction table is to have an unique correction for each submission but a submission can have (or not) a correction.
How can I solve this error? Is it a problem of design or just a table declaration mistake?
A foreign key constraint does not care whether the referenced column(s) is referencing another column itself. But the referenced column(s) must be unique. That's what the error message tells you (quite clearly).
What you are missing is that a foreign key constraint can be based on multiple columns. This should work:
FOREIGN KEY (num, user_id, assignment_id) REFERENCES submission
Replacing:
FOREIGN KEY (num) REFERENCES submission(num),
FOREIGN KEY (user_id) REFERENCES submission(user_id),
FOREIGN KEY (assignment_id) REFERENCES submission(assignment_id)
The short form of the syntax (REFERENCES submission) is possible, because you are referencing the primary key, which is the default.
Plus, you can simplify: make submission.num the sinlge-column primary key, drop the redundant columns user_id and assignment_id from correction and reduce the fk constraint to just (num) - as discussed in #Tim's answer.
As long as you have the multicolumn fk constraint, consider NOT NULL constraints on each of the referencing columns (as commented by #joop). Else, one or more NULL values in the referencing columns allow to escape the fk constraint with the default MATCH SIMPLE behaviour. This may or may not be intended, typically it is not.
Alternatively consider MATCH FULL for multicolumn fk constraints to only allow that if all referencing columns are NULL. Details:
MATCH FULL vs MATCH SIMPLE
Make the foreign key from the correction table to the submission table a compound key that is unique.
Also, review the design of the submission table; num is a serial type and should be the unique primary key. You can add a unique constraint to the columns num, user_id, and assignment_id
CREATE TABLE canvas_user (
id INTEGER,
login_id VARCHAR(50) UNIQUE NOT NULL,
email VARCHAR(355) UNIQUE NOT NULL,
name_given VARCHAR(30),
name_family VARCHAR(30),
name_full VARCHAR(50),
role canvas_role,
last_login TIMESTAMP,
PRIMARY KEY (id)
);
CREATE TABLE problem (
id SERIAL,
title VARCHAR(50),
author VARCHAR(50),
path TEXT,
compiler VARCHAR(20),
PRIMARY KEY (id)
);
CREATE TABLE assignment (
id INTEGER,
title TEXT NOT NULL,
points_possible INTEGER NOT NULL,
problem_id INTEGER,
PRIMARY KEY (id),
FOREIGN KEY (problem_id) REFERENCES problem(id)
);
CREATE TABLE submission (
num SERIAL,
user_id INTEGER,
assignment_id INTEGER,
timestamp TIMESTAMP,
path TEXT,
lti_info TEXT[],
PRIMARY KEY(num, user_id, assignment_id),
FOREIGN KEY (user_id) REFERENCES canvas_user(id),
FOREIGN KEY (assignment_id) REFERENCES assignment(id)
);
CREATE TABLE correction (
num INTEGER,
user_id INTEGER,
assignment_id INTEGER,
timestamp TIMESTAMP,
path TEXT,
execution_time interval,
PRIMARY KEY(num, user_id, assignment_id),
FOREIGN KEY (num, user_id,assignment_id ) REFERENCES submission(num, user_id, assignment_id)
);

Oracle composite primary key / foreign key question

I have a composite primary key in 1 table in oracle. I want to create a foreign key for one table entry in my second table that references the composite primary key in the first table. I am getting the error ORA-02256. Any thoughts on how I can enter this?
CREATE TABLE groupspersonx (
personid number,
groupid number,
CONSTRAINT pk_persongroupid PRIMARY KEY(personid, groupid)
);
CREATE TABLE restrictedgroups (
groupid number,
name varchar2(50),
dateadded date,
since date,
notes varchar2(1024),
CONSTRAINT pk_groupid PRIMARY KEY(groupid),
CONSTRAINT fk_persongroup FOREIGN KEY(groupid) REFERENCES groupspersonx(personid, groupid)
);
The error is because the FOREIGN KEY is one column, but you're trying to supply two columns as the parent. There's no need to tie to the composite key, because the restrictedgroups doesn't have a personid column...
You also have the relationship backwards - use:
CREATE TABLE restrictedgroups (
groupid number,
name varchar2(50),
dateadded date,
since date,
notes varchar2(1024),
CONSTRAINT pk_groupid PRIMARY KEY(groupid)
);
CREATE TABLE groupspersonx (
personid number,
groupid number,
CONSTRAINT pk_persongroupid PRIMARY KEY(personid, groupid),
CONSTRAINT fk_persongroup FOREIGN KEY(groupid) REFERENCES restrictedgroups(groupid)
);
I would add a foreign key constraint for whatever table the personid would be coming from.
CREATE TABLE groupspersonx(
personid number, groupid number,
CONSTRAINT pk_persongroupid PRIMARY KEY(personid, groupid));
CREATE TABLE restrictedgroups (
pid number,
groupid number,
name varchar2(50),
dateadded date,
since date,
notes varchar2(1024),
CONSTRAINT pk_groupid PRIMARY KEY(groupid),
CONSTRAINT fk_persongroup FOREIGN KEY(pid,groupid) REFERENCES groupspersonx(personid, groupid));
* number of references columns is equals with foreign key columns
Whenever you want to create a composite primary key or unique constraint on a column, you can't give reference in another table.
for ex.
sql>create table t1( a number,b number,c number ,primary key(a,b,c));
table created.
sql>create table g1(a number constraint con_fg references t1(a));
ERROR at line 1:
ORA-02270: no matching unique or primary key for this column-list
Here t1 is parent table and g1 is child table. The child table can contains duplicate values in one column. So oracle will not allow that table of column.
See also
SQL>select constraint_name,constraint_type from user_constraints where table_name='T1';
CONSTRAINT_NAME C
------------------------------ -
SYS_C005822 P
So, here also the only constraint for all three columns i.e a,b,c in t1 table.
That's why you can't create a foreign on composite primary key or composite unique constraint
You can't use:
CONSTRAINT fk_persongroup FOREIGN KEY(groupid) REFERENCES groupspersonx(personid, groupid)
Change that too:
CONSTRAINT fk_persongroup FOREIGN KEY(groupid) REFERENCES groupspersonx(groupid)
That should work.