I am evaluating a Laravel/PHP component meant to manage tree data in a SQL database using the "closure Table" design pattern. Code repository: https://github.com/franzose/ClosureTable
Oh my, this component gives me endless headaches. After some installation hickups (Lifetime cost: 2 days ...) I got one little step forward, and ran into what seems to be a really serious compatibility problem with the Microsoft SQL server. When the database ist created through the migration provided by the component, I get the following fatal SQL error:
[Illuminate\Database\QueryException]
SQLSTATE[42000]: [Microsoft][ODBC Driver 11 for SQL Server][SQL
Server]Introducing FOREIGN KEY constraint 'pages_parent_id_foreign' on
table 'pages' may cause cycles or multiple cascade paths. Specify ON
DELETE NO ACTION or ON UPDATE NO ACTION, or modify other FOREIGN KEY
constraints. (SQL: alter table "pages" add constraint
"pages_parent_id_foreign" foreign key ("parent_id") references "pages"
("id") on delete set null)
A similar problem has been described here:
Foreign key constraint may cause cycles or multiple cascade paths?
Anyone having an idea how I can fix this, without breaking the component?
Thnx, Armin.
P.S. I also filed an issue hoping to get teh developer's attraction: Link to Git issue
ALTER TABLE ankita.abc
ADD CONSTRAINT abc_thid_fk FOREIGN KEY (th_id)
REFERENCES ankita.theatre (id)
ON DELETE NO ACTION
ON UPDATE CASCADE;
Error report -
SQL Error: ORA-00905: missing keyword
00905. 00000 - "missing keyword"
As far as I know the syntax is correct. What could be the problem with this statement? I am using Oracle 11g Express Edition.
As far as I know, ON UPDATE CASCADE is not there in Oracle Database. You are getting the error because of that; remove that.
Simply try:
alter table ankita.abc
add constraint abc_thid_fk FOREIGN KEY (th_id) references ankita.theatre(id);
Getting error ora-00001 on oracle database while trying to insert new record.
There is no primary key in table
Error description :
unique constraint violated even if there is no primary key oracle.
There was an unique index which was causing this error
I've just started a new project and I am confronted with a production application Oracle 10g database that has just 3 foreign key constraints. I am not used to seeing databases with no foreign key constraints. I am guessing that there may be some performance/concurrency considerations to not using FKs. The reason is that in the logical database schema the architect has specified all the relationships, but these relationships are not implemented in the database as Foreign Key constraints.
Question: I read that I can define a Foreign Key Constraint with RELY NOVALIDATE that will not impact performance. Is it worth while to define RELY FK constraints on this database just so that the relationship can be easily seen? this application is not built using ORM, is it really worth while to do without foreign keys?
The database is denormalised with example below
Table 1 : FINProduct(ID (number), Description(varchar(5)), FINproductCode(varchar(10))...)
Table 2: FINProductCode(ID (number, FINproductCode(varchar(10)) , LastUpdated(datetime)...)
So instead of having a relationship between Tables 1 and 2 the FINproductCode column is just replicated in table 1.
It's too early to drink but I think i need one!
I would be very wary about assuming that the absence of foreign key constraints was a reasoned response to performance issues. There is an overhead to enforcing a foreign key constraint (particularly where appropriate indexes are missing) but it is incredibly unlikely that your application can validate the constraint more efficiently than Oracle can. So the question really is whether you want the small overhead of foreign key constraints or the near certainty that you will get invalid data inserted into the database. It would be extremely unlikely that this is a trade-off that you want to make-- I've yet to meet a business user that would be happy to capture incorrect and incomprehensible data even if doing so was a bit faster than capturing correct data.
Unless there is substantially more background, I would tend to create all the missing foreign key constraints. Creating RELY NOVALIDATE constraints is possible but it defeats the major benefit of foreign key constraints-- preventing invalid data from entering the database in the first place.
It depends on whether you want to add the FK only for documentation purposes or whether you want to prevent future INSERTs/UPDATEs with an invalid FK value.
If you want it only for documentation purposes, I'd create the FK constraint with RELY NOVALIDATE and DISABLE it afterwards - otherwise, Oracle will check it for future INSERTs / UPDATEs.
However: DON'T DO THIS UNLESS YOU ABSOLUTELY NEED IT!
I agree with Justin Cave: In most cases, you should just add "plain" FK constraints - this way, you can ensure that your existing data is correct.
I would try to create the constraints and report violations into a exception table. Fix the data and enable the constraint.
Create some test data
create table parent (pk integer
,data varchar2(1)
,CONSTRAINT PARENT_PK PRIMARY KEY (PK) ENABLE );
create table child (pk integer
,pk_parent integer
,data varchar2(1)
,CONSTRAINT CHILD_PK PRIMARY KEY (PK) ENABLE );
insert into parent values (1,'a');
insert into parent values (2,'b');
insert into child values (1,1,'a');
insert into child values (2,2,'b');
insert into child values (3,3,'c');
Create a foreign key constraint:
alter table child add constraint fk_parent foreign key(pk_parent) references parent(pk);
SQL Error: ORA-02298: Kan (ROB.FK_PARENT) niet valideren - bovenliggende sleutels zijn niet gevonden.
02298. 00000 - "cannot validate (%s.%s) - parent keys not found"
*Cause: an alter table validating constraint failed because the table has
child records.
*Action: Obvious
Create the foreign key with 'enable novalidate' option
alter table child add constraint fk_parent foreign key(pk_parent) references parent(pk) enable novalidate;
table CHILD altered.
insert into child values (4,4,'c');
SQL Error: ORA-02291: Integriteitsbeperking (ROB.FK_PARENT) is geschonden - bovenliggende sleutel is niet gevonden.
02291. 00000 - "integrity constraint (%s.%s) violated - parent key not found"
*Cause: A foreign key value has no matching primary key value.
*Action: Delete the foreign key or add a matching primary key.
No new data violating the FK can be inserted.
Now let's fix the data already in the table that violates the FK constraint
Create an exceptions table and try to enable the constraint:
create table exceptions(row_id rowid,
owner varchar2(30),
table_name varchar2(30),
constraint varchar2(30));
ALTER TABLE child ENABLE constraint fk_parent EXCEPTIONS INTO EXCEPTIONS;
Error report:
SQL Error: ORA-02298: Kan (ROB.FK_PARENT) niet valideren - bovenliggende sleutels zijn niet gevonden.
02298. 00000 - "cannot validate (%s.%s) - parent keys not found"
*Cause: an alter table validating constraint failed because the table has
child records.
*Action: Obvious
Check the exceptions table for problems:
select * from exceptions;
ROW_ID OWNER TABLE_NAME CONSTRAINT
------ ------------------------------ ------------------------------ ------------------------------
AABA78 ROB CHILD FK_PARENT
AAFAAA
Ow9AAC
select * from child where rowid = 'AABA78AAFAAAOw9AAC';
Fix the problem
delete from child where pk = 3;
1 rows deleted.
ALTER TABLE child ENABLE constraint fk_parent EXCEPTIONS INTO EXCEPTIONS;
table CHILD altered.
Constraint enabled and data correct
Oracle 11g
step 1.
create table pur_order(
po_number number primary key,
po_date date,
po_vendor number,
:)
step 2.load data with Enterprise Manager 11g from a user file podata.txt content like:
1 25-JUN-2011 1001
2 26-JUN-2011 1002
3 27-JUN-2011 1003
1 27-JUN-2011 1001
2 28-JUN-2011 1002
step 3. the loading process finished successfully.
table content is just like above
problem is as I have already defined po_number as primary key,why duplicate values of po_number still be able to be loaded?
Most likely this method of import uses the SQL*Loader utility with the Direct Path Load method. This disables some integrity constraints as explained in the documentation:
Integrity constraints that depend on other rows or tables, such as referential constraints, are disabled before the direct path load and must be reenabled afterwards. If REENABLE is specified, SQL*Loader can reenable them automatically at the end of the load. When the constraints are reenabled, the entire table is checked. Any rows that fail this check are reported in the specified error log. See Direct Loads, Integrity Constraints, and Triggers.
SQL*Loader tried to reenable the constraint but failed and thus:
The index will be left in an Index Unusable state if a violation of a UNIQUE constraint is detected. See Indexes Left in an Unusable State.
I'm pretty sure you will find that the primary key index is unusable (SELECT index_name, status FROM all_indexes WHERE table_name = 'PUR_ORDER').
Either load the datafile without direct path load or make sure that the constraint is successfully enabled afterwards.