How do I correct "SQL Error: ORA-02270: no matching unique or primary key for this column-list" errors? - oracle

I'm working on a project in which I'm writing queries from this database that I am attempting to create in PLSQL. However, before I can do that I must create the db, and some of the table-create statemens I'm trying to run are returning errors. Specifically, the errors seem to indicate that some of the primary keys I'm referencing don't exist. When I check to see if that is true I see the likely issue. For example, I try to do
create table group_disforum ( df_id int,
ig_id int,
constraint gdf_FK foreign key(ig_id) references Course_Interest_group(interest_gid),
constraint gdf_PK primary key(df_id, ig_id),
comments varchar(150)
)
setting the foreign key to the primary key(interest_gid) in Course_Interest_group.
However, the Course_Interest_group is this:
create table Course_Interest_group( interest_gid int,
gname varchar(20),
courseid int,
facultyid int,
past_gpa float,
constraint IG_PK primary key(interest_gid, courseid, facultyid),
constraint IG_FK1 foreign key(courseid) references course(courseid),
constraint IG_FK2 foreign key(facultyid) references User_Faculty(userid)
);
The primary key for Course_Interest_group is not just interest_gid, but interest_gid, courseid, and facultyid.
There are several other instances of the same issue.
My question is, when referencing Course_Interest_group how can I reference just interest_gid? Is it possible? Should I change something?
I would like to keep the current Course_Interest_group pk of (interest_gid, courseid, facultyid) intact but I will modify it if needed.
my code
my output

If in the course_interest_group table interest_gid uniquely identifies each row in the table then interest_gid should be the primary key. Similarly, in the group_disforum if df_id uniquely identifies each row in the table then df_id should be the primary key. Modifying the primary keys of both these tables should solve the issue.

I think the way around for your question will be a TRIGGER to customize the data Integrity. You can create a before INSERT Trigger which will check first whether the data in your case (Course_Interest_group(interest_gid)). So basic structure of your Trigger will be like. Hope this may be a workwround.
SET SQLBL ON;
SET DEFINE OFF;
CREATE OR REPLACE TRIGGER group_disforum_tg BEFORE
INSERT OR
UPDATE
/*OF ig_id*/
ON group_disforum FOR EACH ROW
DECLARE lv_chck PLS_INTEGER;
BEGIN
SELECT COUNT(1)
INTO lv_chck
FROM Course_Interest_group
WHERE interest_gid = :new.interest_gid;
IF lv_chck = 0 THEN
RAISE_APPLICATION_ERROR(-20001,'Parent key (interest_gid) not found in group_disforum_tg',TRUE);
END IF;
END;
/

Related

ORA-02264: name already used by an existing constraint (error)

CREATE TABLE Flight (
FlightNo int NOT NULL PRIMARY KEY,
FlightDate Date,
PlaneSerialNo int,
EmployeeID int,
RouteNo int,
CONSTRAINT FK_PlaneSerialNo FOREIGN KEY(PlaneSerialNo)
REFERENCES Plane(PlaneSerialNo),
CONSTRAINT FK_EmployeeID FOREIGN KEY(EmployeeID)
REFERENCES Employee(EmployeeID),
CONSTRAINT FK_RouteNo FOREIGN KEY(RouteNo)
REFERENCES Route(RouteNo)
);
trying to create a sort of database system using oracle where it tracks flights but it just says the name is already used but havent seen any similarities in constraints other than identifying FKs
Oracle doesn't rely much on similarities - it has found object with exactly the same name in its dictionary and - as you can't have two objects with the same name - it raised the error.
Query user_constraints (and then user_objects, if previous search didn't find anything).
If you want to find out which table it is, you might try
select owner, table_name from dba_constraints where constraint_name = '<some value from your create table command>';

How to add primary key constraint on two columns to make composite key in oracle?

I am new to here, please help me to find an answer to the below query.
"How to add a primary key constraint on two columns to make a composite key column in a table?"
Instead of writing so many lines, kindly provide the answer as short as possible with code.
(I am creating a table in which I can have only one primary key on the values of two-columns as a composite key.)
JacknJill
You can create such constraint in scope of CREATE TABLE operator
CREATE TABLE foo (
id INTEGER,
name VARCHAR(25),
bar VARCHAR(255),
CONSTRAINT foo_pk PRIMARY KEY (id,name)
);
or ALTER TABLE operator
CREATE TABLE foo (
id INTEGER,
name VARCHAR(25),
bar VARCHAR(255)
);
ALTER TABLE foo ADD CONSTRAINT foo_pk PRIMARY KEY (id,name);

oracle foreign key returns null

currently i am facing an oracle constraints issue.
After submiting an insert my foreign key constraint(s) won't fire. What it should do is giving two tables the same ID, but unfortunately only the one table with the primary Key is giving an ID. The column with the foreign key in the second table remains null.
For Instance: Insert into table t1 (t1_id,name, dpt) values (value1 (trigger with autoincrement for id), value2, value3); The same procedure is behind table 2, table 3 ... All constraints are written correctly
Table 1 (Emp)
ID Name Department
1 Joe HR
Table 2 (Projects)
ID Project EmpID
1 new (null) -> must be 1
Thank you in advanced.
Constraint: ALTER TABLE "PROJECTS" ADD CONSTRAINT "EMP_FK" FOREIGN KEY ("EMP_ID")
REFERENCES "EMP" ("EMP_ID") ON DELETE CASCADE ENABLE
Trigger: create or replace TRIGGER Projects_TRG BEFORE
INSERT ON Projects FOR EACH ROW BEGIN :NEW.Project_ID := Projects_SEQ.NEXTVAL;
END;
How do i manage to populate the parent id from the parent table into the child table?
Please note that I used different names in my application.
It appears that you've misunderstood the purpose of a foreign key constraint. A foreign key constraint does NOT automatically propagate constraint values from the parent table to the child table. The purpose of the constraint is to ensure that the values of the key column in the child table, when populated, have matching values in the key column of the parent table. Your application is responsible for ensuring that the key column on the child table is populated with the appropriate value. The constraint doesn't do that for you. It's also perfectly legitimate to have a NULL in the key column of the child table, assuming the the column on the child table doesn't have a NOT NULL constraint on it.

Delete Cascade with Script

I have 3 tables,which are not created with the ON DELETE CASCADE option, nor is it an option to create them as such.
I may need to delete from all three tables in succession. Is there a way to do this using only the promotion_id as a key? Because I need to delete in reverse order, the promotion_id is gone by the time I get to the dependent tables.
I am thinking that the only way to do this is to SELECT the keys of the 3 tables using a JOIN, and then use them individually. But it would be nice if there was a pure SQL solution to it.
I am using JDBC, Spring, and Oracle. Thanks.
create table test_rates (
rate_id varchar2(10) primary key,
rate number
);
create table test_offers (
offer_id varchar2(10) primary key ,
rate_id varchar2(10),
foreign key (rate_id) references test_rates (rate_id)
);
create table test_promotions (
promotion_id varchar2(10) primary key ,
offer_id varchar2(10),
foreign key (offer_id) references test_offers (offer_id)
);
insert into test_rates (rate_id,rate) values (1,199);
insert into test_offers (offer_id,rate_id) values (11,1);
insert into test_promotions (promotion_id,offer_id) values (21,11);
commit;
delete from test_promotions where promotion_id = 21;
delete from test_offers where offer_id in (select offer_id from test_promotions where promotion_id = 1); -- key is gone by now
In the common case, when there are N promotions (N>1) for a single offer, it wouldn't make sense to delete the offer if one promotion only is deleted. You would end up with orphaned promotions.
If you want to delete a rate, it would make sense to start with deleting all children promotions then all children offers then delete the rate. In that case though, the rate_id could be used along the way.
If you delete a child record, there's no need to delete the parent record unless of course this is a requirement, in which case start with looking for the parent id and see above.

Oracle Foreign Key Issues with Multi-Table Inserts and Blobs

We have a single table that we want to break up into a tree of tables based upon a particular source column. I wanted to try using a multi-column insert, but it seems that if I insert a blob into a sub table, I wind up with a foreign key constraint violation.
I don't think this violates the rules about multi-table inserts but I could be wrong...
I am hoping that someone could point me to some more in-depth resources around what is actually going on here, so that I can feel confident that whatever solution will work as part of a liquibase changeset on Oracle databases 9i -> 11g.
Hopefully Simplified Scenario
CREATE TABLE source (
pk NUMBER NOT NULL PRIMARY KEY,
type VARCHAR2(20) NOT NULL,
content VARCHAR2(20) NOT NULL
);
INSERT INTO source (pk,type,content) values (1,'two','n/a');
INSERT INTO source (pk,type,content) values (2,'one','Content');
CREATE TABLE dest (
pk NUMBER NOT NULL PRIMARY KEY,
type VARCHAR2(20) NOT NULL
);
CREATE TABLE dest_one (
pkfk NUMBER NOT NULL PRIMARY KEY,
data BLOB NOT NULL,
CONSTRAINT XFK1DEST_ONE FOREIGN KEY (pkfk) REFERENCES dest (pk)
);
CREATE TABLE dest_two (
pkfk NUMBER NOT NULL PRIMARY KEY,
CONSTRAINT XFK1DEST_TWO FOREIGN KEY (pkfk) REFERENCES dest (pk)
);
Source contains our original data. dest will be our parent table, with children dest_one and dest_two (which will contain information on things of type 'one' or 'two' respectively). Things of type one have content, but things of type two do not.
The Failed Attempt
INSERT ALL
WHEN 1=1 THEN INTO dest (pk,type) VALUES (pk,type)
WHEN type='one' THEN INTO dest_one (pkfk,data) VALUES (pk,content)
WHEN type='two' THEN INTO dest_two (pkfk) VALUES (pk)
SELECT pk,type,utl_raw.cast_to_raw(content) as content from source where type in ('one','two');
As previously mentioned, I wound up with a foreign key constraint violation here. To further illustrate that the blob was the issue I tried two seperate similar queries (below) realizing the one without the blob insert worked, but with the blob insert failed.
INSERT ALL
WHEN 1=1 THEN INTO dest (pk,type) VALUES (pk,type)
WHEN type='two' THEN INTO dest_two (pkfk) VALUES (pk)
SELECT pk,type,utl_raw.cast_to_raw(content) as content from source where type = 'two';
/* Successful */
INSERT ALL
WHEN 1=1 THEN INTO dest (pk,type) VALUES (pk,type)
WHEN type='one' THEN INTO dest_one (pkfk,data) VALUES (pk,content)
SELECT pk,type,utl_raw.cast_to_raw(content) as content from source where type = 'one';
/* ORA-02291: integrity constraint violated, no parent key */
Solution 1 - Traditional Inserts
INSERT INTO dest (pk,type) SELECT pk,type from source where type in ('one','two');
INSERT INTO dest_two (pkfk) SELECT pk from source where type = 'two';
INSERT INTO dest_one (pkfk,data) SELECT pk,utl_raw.cast_to_raw(content) from source where type = 'one';
One option I am considering is going back to multiple seperate insert statements, but unlike how I have stated them here, I'm concerned that I'll have to make sure I write my sub-table inserts to only attempt to insert those rows present in parent dest table... I need to do more research on how Liquibase handles multiple sql statements in the same changeset.
Solution 2 - Temporarily disabling foreign key constraints
ALTER TABLE dest_one DISABLE CONSTRAINT XFK1DEST_ONE;
INSERT ALL
WHEN 1=1 THEN INTO dest (pk,type) VALUES (pk,type)
WHEN type='one' THEN INTO dest_one (pkfk,data) VALUES (pk,content)
WHEN type='two' THEN INTO dest_two (pkfk) VALUES (pk)
SELECT pk,type,utl_raw.cast_to_raw(content) as content from source where type in ('one','two');
ALTER TABLE dest_one ENABLE CONSTRAINT XFK1DEST_ONE;
This is the solution I'm leaning toward. While disabling the foreign key on my blob table seems to make it work in my test environment (10g - 10.2.0.1.0), I'm not sure if I should also be disabling the foreign key on the non-blob table as well (due to how 9i, 11g, or other versions of 10g may behave). Any resources here too would be appreciated.
Thanks a bunch!
Another solution would be to defer the constraint evaluation until COMMIT. I suspect (but am not sure) that the multi-table insert is inserting rows in an order other than the one you expect and want. Recreate your constraints as follows:
ALTER TABLE DEST_ONE DROP CONSTRAINT XFK1DEST_ONE;
ALTER TABLE DEST_ONE
ADD CONSTRAINT XFK1DEST_ONE
FOREIGN KEY (pkfk) REFERENCES dest (pk)
INITIALLY DEFERRED DEFERRABLE;
ALTER TABLE DEST_TWO DROP CONSTRAINT XFK1DEST_TWO;
ALTER TABLE DEST_TWO
ADD CONSTRAINT XFK1DEST_TWO
FOREIGN KEY (pkfk) REFERENCES dest (pk)
INITIALLY DEFERRED DEFERRABLE;
This re-creates the constraints so that they can be deferred, and are deferred from the time they're created. Then try your original INSERT again.
Share and enjoy.

Resources