Is any way, how to create table with CHECK (or maybe TRIGGER?), that will check, if inserted value is already in another table?
Example
CREATE TABLE Employee(
Name VARCHAR(10),
Adress VARCHAR(20)
);
CREATE TABLE Section(
Section_name VARCHAR(10),
Managers_name VARCHAR(10)
);
And I want to check, that value inserted to Managers_name is already in Employee, if it isnt, then print error.
I found any ways, how it could be done, but everything I tried in Oracle, didnt work.
Add a PRIMARY KEY constraint to the employee table and a FOREIGN KEY constraint to the section table:
CREATE TABLE Employee(
Name VARCHAR(10) CONSTRAINT Employee_Name_PK PRIMARY KEY,
Adress VARCHAR(20)
);
CREATE TABLE Section(
Section_name VARCHAR(10),
Managers_name VARCHAR(10)
CONSTRAINT section_manager_fk REFERENCES Employee( Name )
);
Check constraint is, as explained by mt0, devoted to single table.
Trigger is to be avoided for consistency reasons: while you're selecting a record, another session might be in the process of deleting it.
The Foreign Key is the correct way to implement it: Trap FK constraint violation in your code (ORA-02291 i guess), search for "section_manager_fk" in the message and finally rewrite a user-friendly error message.
Related
Sorry, I don't well English.
CREATE TABLE Reservation(
tno NUMBER,
sno NUMBER,
cno NUMBER,
seat_no NUMBER,
Res_Date DATE,
CONSTRAINT FK_RES_TNO FOREIGN KEY (tno) REFERENCES Theater(tno),
CONSTRAINT FK_RES_SNO FOREIGN KEY (sno) REFERENCES Screen(sno),
CONSTRAINT FK_RES_CNO FOREIGN KEY (cno) REFERENCES T_Customer(cno),
CONSTRAINT PK_RESERVATION PRIMARY KEY (tno,sno,cno)
--CONSTRAINT RES_UNIQUE UNIQUE (cno)
);
I Write Oracle Table.
But throw me Error "ORA-02270"
I don't know come to me this message.
Could you tell me some advise?
There would be multiple reasons for having this error,
You may have same primary key already, which might be disabled
Composite primary key in the table may not provide you the unique (this error many happen only when the table is ALTERED, since its new table, this logical check can be ignored)
I'm creating a couple of Tables for an assignment.
So I created a Gardener Table and an Offering Table, with all the appropriate data types and NULL statuses, as well as the Primary Key constraint for each. In the Gardener table I've included offeringID, and vice versa.
When I try to add Foreign Key constraint offeringID to the Gardener Table I get an error.
After checking online, I realized I had forgotten to make offeringID and gardenerID in each other's tables UNIQUE, hence I altered table to add uniqueness.
Tried adding Foreign Key constraint and I get the same error. I reckon I may be understanding something wrongly, but I can't seem to put my finger on it.
Create Table Gardener
(gardenerID NUMBER(10) NOT NULL,
offeringID NUMBER(10) NOT NULL,
CONSTRAINT gardener_pk PRIMARY KEY(gardenerID)
);
Create Table Offering
(offeringID NUMBER(10) NOT NULL,
gardenerID NUMBER(10) NOT NULL,
CONSTRAINT offering_pk PRIMARY KEY(offeringID)
);
Alter Table Gardener
add CONSTRAINT offering_fk FOREIGN KEY(offeringID)
REFERENCES Offering(offeringID);
Alter Table Gardener
add Unique(offeringID);
Alter Table Offering
add Unique(gardenerID);
This is the error:
ORA-02270: no matching unique or primary key for this column-list
02270. 00000 - "no matching unique or primary key for this column-list"
Cause: A REFERENCES clause in a CREATE/ALTER TABLE statement gives a column-list
for which there is no matching unique or primary key constraint in the referenced table.
Like, I still don't get it. Isn't offeringID a Primary Key hence pointing to it from Gardener shouldn't be an issue still?
Since you're trying to add a a foreign key constraint for offering.offeringID column within the Gardener table, whereas that column has no unique/primary key key when you try to add a foreign key. i.e. operation stops at the 3rd command.
So, just exchange the order of commands as :
Alter Table Gardener
add Unique(offeringID); -- should be prior to the below command
Alter Table Gardener
add CONSTRAINT offering_fk FOREIGN KEY(offeringID)
REFERENCES Offering(offeringID);
Demo
I have two tables with a one-to-one relationship (and relationship is mandatory from one side only). As follows:
create table PRS (
id number(18) not null,
common_code varchar2(10),
constraint pk_prs primary key (id));
create table RLP {
id number(18),
spec_code varchar2(20),
constraint pk_rlp primary key (id),
constraint fk_rlp_prs foreign key (id) references prs(id) on delete cascade);
So the problem is when inserting a record in RLP at least one of common_code or spec_code must have value.
Is it possible to enforce this constraint using a constraint or the only solution is having a trigger?
It seems there is no way to create a constraint on two tables, and the only solution is to create a trigger to throw an exception on desired situation.
The tables:
SIGN_OBJECT:
ID VARCHAR2(32) PRIMARY KEY,
DESCRIPTION VARCHAR2(100),
X NUMBER(10,3),
Y NUMBER(10,3),
...
GEOMETRYID VARCHAR2(32)
LAMPPOST_OBJECT:
ID VARCHAR2(32) PRIMARY KEY,
DESCRIPTION VARCHAR2(100),
X NUMBER(10,3),
Y NUMBER(10,3),
...
GEOMETRYID VARCHAR2(32)
OBJGEOMETRY:
GEOMETRYID VARCHAR2(32) PRIMARY KEY,
GEOMETRY MDSYS.SDO_GEOMETRY,
...
There are many X_OBJECT tables. Unfortunately the schema designers (in their infinite wisdom) didn't see any crossover between the various object types. I am unable to change these tables without creating much more work.
For each object table there is a trigger that creates the relevant SDO_GEOMETRY value BEFORE insert or update ( GEOMETRYID is unique - it comes from a sequence ). At the moment the trigger calls a package function which inserts the OBJGEOMETRY record and returns the geometryid.
The problem is that if the parent record is deleted I would like the OBJGEOMETRY child record to be also deleted.
Initially I thought this could be done with Foreign Keys cascade delete, but of course the FK requires a Primary Key in the parent table - obviously this won't work.
However, I discovered that actually a FK requires a unique constraint in the parent table. I can make X_OBJECT.GEOMETRYID unique but then I'm finding issues because that GEOMETRYID isn't yet populated in the parent table but the FK requires it exists. I cannot do that inside the trigger ( by setting :NEW.GEOMETRYID ) so do I have to write the GEOMETRYID first and then commit? I'm not sure and this has bad code smell.
So am I wrong? Is this a more suitable case for a delete trigger? or is there something I'm missing.
Thanks.
If you insert both the OBJGEOMETRY and the X_OBJECT rows in the same transaction, then you can set the FK to DEFERRABLE INITIALLY DEFERRED.
In that case it will be evaluated at COMMIT time, not when you run the INSERT statement.
The triggers should fire before insert or update, not after. Then you can set :NEW.GEOMETRYID with the value returned by your package.
Besides, the foreign keys point the wrong way. It should be
ALTER TABLE x_OBJECT ADD FOREIGN KEY (geometryid) REFERENCES objgeometry(geometryid);
Therefore, you'll need a delete trigger...
Having issues declaring a FK in Oracle 9i. I've looked at a number of examples here on SO and in some online docs (e.g. http://www.techonthenet.com/oracle/foreign_keys/foreign_delete.php) without any real luck; trying a similar syntax to that in the link generates the same error:
Error at Command Line:19 Column:4
Error report:
SQL Error: ORA-02253: constraint specification not allowed here
02253. 00000 - "constraint specification not allowed here"
*Cause: Constraint specification is not allowed here in the statement.
*Action: Remove the constraint specification from the statement.
An excerpt of the SQL itself is as below. "Line 19" refers to the line starting with CONSTRAINT
CREATE TABLE Flight (
flight_no varchar2(10) NOT NULL,
airplane_id varchar2(20) NOT NULL
CONSTRAINT flight_airplane_id_fk FOREIGN KEY (airplane_id) REFERENCES Airplane (airplane_id)
ON UPDATE RESTRICT ON DELETE RESTRICT,
dept_date date NOT NULL,
...
Alternatively, trying it without the CONSTRAINT keyword generates an error about a right parenthesis that I can't seem to see is missing.
PS: I understand ON UPDATE RESTRICT is the default behaviour in Oracle, but I prefer to be explicit wherever possible.
First off, in Oracle, there is no ON UPDATE RESTRICT or ON DELETE RESTRICT option. Those appear to be valid in other database engines but they aren't present in the constraint syntax diagram and do not appear to be valid. There is an ON DELETE clause but the only two valid options are CASCADE or SET NULL. There is no ON UPDATE clause.
If we add a comma at the end of the airplane_id definition before the constriant definition and remove the two invalid clauses, your DDL should be valid
CREATE TABLE Flight (
flight_no varchar2(10) NOT NULL,
airplane_id varchar2(20) NOT NULL,
CONSTRAINT flight_airplane_id_fk
FOREIGN KEY (airplane_id) REFERENCES Airplane (airplane_id),
dept_date date NOT NULL,
<<more columns>>
);
Put your constraint at the end:
CREATE TABLE Flight (
flight_no varchar2(10) NOT NULL,
airplane_id varchar2(20) NOT NULL,
dept_date date NOT NULL,
CONSTRAINT flight_airplane_id_fk FOREIGN KEY (airplane_id) REFERENCES Airplane (airplane_id) ON UPDATE RESTRICT ON DELETE RESTRICT
);