I haven't explored this in any depth, but you might be able to update
the foreign keys in a row-deleting procedure which runs with DEFINER
rights. This would require you to run with authentication and
authorization turned on. In normal operation, the application would be
run by an ordinary user with limited rights, NOT by the DBO. The
following script shows the basic mechanics of this. You might want to
read the section titled "Configuring fine-grained user authorization" in
the Derby Security Guide.
CONNECT 'jdbc:derby:/Users/rhillegas/derby/mainline/z/db1;create=true;user=dbo';
CALL syscs_util.syscs_create_user( 'DBO', 'dbo_password' );
-- shutdown in order to enable NATIVE authentication
CONNECT 'jdbc:derby:/Users/rhillegas/derby/mainline/z/db1;shutdown=true';
-- reboot database. it is now protected by NATIVE authentication
CONNECT
'jdbc:derby:/Users/rhillegas/derby/mainline/z/db1;user=dbo;password=dbo_password';
-- create an everyday user
CALL syscs_util.syscs_create_user( 'fred', 'fred_password' );
create table assemblies(id int primary key);
CREATE TABLE components (
id INTEGER GENERATED ALWAYS AS IDENTITY,
assembly INTEGER NOT NULL,
pred INTEGER DEFAULT NULL,
succ INTEGER DEFAULT NULL,
CONSTRAINT components_pk PRIMARY KEY (id),
CONSTRAINT components_1 FOREIGN KEY (assembly)
REFERENCES assemblies(id),
CONSTRAINT components_2 FOREIGN KEY (pred)
REFERENCES components(id),
CONSTRAINT components_3 FOREIGN KEY (succ)
REFERENCES components(id)
);
grant insert on assemblies to public;
grant update on assemblies to public;
grant delete on assemblies to public;
grant insert on components to public;
grant update on components to public;
create procedure deleteComponentRow(in rowID int)
language java parameter style java modifies sql data
external security definer
external name 'TestProcs.deleteComponentRow';
grant execute on procedure deleteComponentRow to public;
On 8/4/25 5:51 AM, John English wrote:
I have two tables, Assemblies and Components, and I want each
component to refer to the assembly it belongs to and I also want to
arrange the components in a sequence. The definition of Components I
tried looks like this:
CREATE TABLE components (
id INTEGER GENERATED ALWAYS AS IDENTITY,
assembly INTEGER NOT NULL,
pred INTEGER DEFAULT NULL,
succ INTEGER DEFAULT NULL,
CONSTRAINT components_pk PRIMARY KEY (id),
CONSTRAINT components_1 FOREIGN KEY (assembly)
REFERENCES assemblies(id)
ON DELETE CASCADE,
CONSTRAINT components_2 FOREIGN KEY (pred)
REFERENCES components(id)
ON DELETE SET NULL,
CONSTRAINT components_3 FOREIGN KEY (succ)
REFERENCES components(id)
ON DELETE SET NULL
);
The idea is that they components will form a doubly-linked list, where
the first component will have prev = null, and the last will have succ
= null, enabling me to insert, delete and rearrange components at will.
However, I get this error:
Foreign Key 'COMPONENTS_2' is invalid because 'The delete rule of
foreign key must be CASCADE. (The referential constraint is
self-referencing and the table is dependent in a relationship with a
delete rule of CASCADE.)'.
I want components to be deleted automatically when the assembly they
belong to is deleted, but I also want to ensure that pred/succ are
valid component IDs.
Can anyone suggest any other way to define this table so that I can
access components in an assembly sequentially and rearrange them at will?
TIA,