on ‎2023 Dec 16 7:33 AM
We are adding a Cross Reference table to identify parts that are equivalents. This is the first time I have modeled this any comments or suggestions are appreciated.
Thanks
Jim
The core Parts Table has a single surrogate integer primary key "PartId". The cross reference table has a PK of PartId and ReferenceId where ReferenceId is the PartId of the cross referenced part.
The insert procedure checks for existing cross reference as well as related cross references so
| 1 | 2 | | 1 | 3 | | 2 | 1 | -- Not Allowed | 3 | 1 | -- Not Allowed | 2 | 3 | -- Not Allowed
We then use the following procedure to return all cross referenced parts
CREATE OR REPLACE PROCEDURE NSP.CrossReferencedParts(
IN @PartId INTEGER
)
RESULT(
CrossReferenceId INTEGER
)
BEGIN
-- {JJD} Retirn all parts directly or indirectly cross referenced to @PartId
DECLARE @Count INTEGER;
DECLARE @TargetId INTEGER;
SELECT COUNT(*)
INTO @Count
FROM NSP.PartsCrossReference
WHERE PartId = @PartId;
IF @Count > 0 THEN
-- This is the master PartId
SELECT ReferenceId AS CrossReferenceId
FROM NSP.PartsCrossReference
WHERE PartId = @PartId
UNION
SELECT @PartId AS CrossReferenceId;
ELSE
SELECT PartId
INTO @TargetId
FROM NSP.PartsCrossReference
WHERE ReferenceId = @PartId;
IF @TargetId IS NOT NULL THEN
-- This is a referenced PartId
SELECT ReferenceId AS CrossReferenceId
FROM NSP.PartsCrossReference
WHERE PartId = @TargetId
UNION
SELECT @TargetId AS CrossReferenceId;
ELSE
SELECT COUNT(*)
INTO @Count
FROM NSP.Parts
WHERE PartId = @PartId;
IF @Count > 0 THEN
-- The part exists but there are no cross references to this part
SELECT @PartId AS CrossReferenceId;
END IF;
END IF;
END IF;
END;
Request clarification before answering.
Maybe this is what you're asking for:
// Parts table
create table parts(
partID integer,
partDescr nchar(40),
primary key (partID)
);
// Relationstable between parent and child
create table pc(
pPartID integer, // Parent/main part
cPartID integer // Child/underlaying part
);
alter table pc add foreign key FK_p (pPartID) references parts (partID) on update restrict on delete restrict;
alter table pc add foreign key FK_c (cPartID) references parts (partID) on update restrict on delete restrict;
// Add trigger to prevent wrong inserts to pc:
create or replace trigger tb_pc before insert, update order 1 on pc referencing new as New_Record old as Old_Record for each row
begin
if new_record.pPartID > new_record.cPartID then
begin
// Make sure the relation always is from lower to higher
declare buf integer = new_record.pPartID;
set new_record.pPartID = new_record.cPartID;
set new_record.cPartID = buf;
end;
end if;
// Test if relation already exists
begin
declare ExistOnLevel integer = 0;
with recursive Relation (pPartID, cPartID, level) as
(
(
select pPartID, cPartID, 1 level
from pc AS tab
// where cPartID = pPartID
)
UNION ALL
(
select tab.pPartID, rel.cPartID, rel.level+1
from pc AS tab
inner join relation AS rel on (tab.cPartID = rel.pPartID /*and tab.pPartID <> tab.cPartID*/ and rel.level < 20)
)
)
select first level
into ExistOnLevel
from relation
where pPartID = new_record.pPartID and cPartID = new_record.cPartID;
if ExistOnLevel > 0 then
raiserror 17000 'Relation already exists as ' || if ExistOnLevel = 1 then 'direct' else 'indirect' endif || ' relation';
end if;
end;
end;
// Add parts
insert into parts(partID, partDescr)
values
(1, 'Part 1'),
(2, 'Part 2'),
(3, 'Part 3'),
(4, 'Part 4');
// Add some relations to test
insert into pc(pPartID, cPartID) values(1,2);
insert into pc(pPartID, cPartID) values(2,3);
insert into pc(pPartID, cPartID) values(2,4);
// Some wrong ones
insert into pc(pPartID, cPartID) values(4,2);
insert into pc(pPartID, cPartID) values(1,3);
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
| User | Count |
|---|---|
| 12 | |
| 9 | |
| 7 | |
| 5 | |
| 4 | |
| 2 | |
| 2 | |
| 2 | |
| 2 | |
| 2 |
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.