How to return materials from a product or product levels with PL/SQL

Asked

Viewed 80 times

0

I have a table that contains products and each product has other products that are used to manufacture. The products that are used to manufacture the parent product, can also be manufactured and contain other manufactured products.EX:

ID_PRODUCT_MATERIAL   PRODUCTION   ID_MATERIAL
1                     2            2
1                     2            3
1                     2            4
2                     1            9
2                     1            10
3                     1            8
8                     1            5

Product 1 needs products 2,3 and 4, but product 2 and 3 are also manufactured. Product 2 needs 9 and 10 and 3 needs 8 and finally 8 needs 5. In case we have levels here, product 1 is at level 1, products 2,3 and 4 are at level 2 and product 8 is at level 3. I tried using recursive level hierarchy to select, But it turns out it’s not really a hierarchy. SELECT used below returns me the following error:

Erro de SQL: ORA-32044: Ciclo detectado ao executar a consulta WITH recursiva

WITH CTE (ID_PRODUCT_MATERIAL,PRODUCTION,ID_MATERIAL) AS (
  SELECT ID_PRODUCT_MATERIAL,
  PRODUCTION,
  ID_MATERIAL,
  FROM MATERIAL

  UNION ALL

  SELECT ID_PRODUCT_MATERIAL,
  M.PRODUCTION,
  M.ID_MATERIAL,
  FROM MATERIAL M
  INNER JOIN CTE C
  ON M.ID_PRODUCT_MATERIAL = C.ID_MATERIAL
  )
SELECT * FROM CTE;

The columns ID_PRODUCT_MATERIAL and ID_MATERIAL are derived from the products table. How to proceed in this case? Follows the structure of the tables:

CREATE TABLE PRODUCT(
  ID_PRODUCT NUMBER(6,0) PRIMARY KEY,
  NAME VARCHAR2(200),
  WEIGHT NUMBER(6,2),
  PRICE NUMBER(6,2)
 );

CREATE TABLE PRODUCTION(
  ID_PRODUCT_PRODUCTION NUMBER(6,0) PRIMARY KEY,
  PRODUCTION NUMBER(3,0),
  CONSTRAINT FK_PRODUCTIONPRODUCT FOREIGN KEY(ID_PRODUCT_PRODUCTION) REFERENCES PRODUCT(ID_PRODUCT)
 );

CREATE TABLE MATERIAL(
      ID_PRODUCT_MATERIAL NUMBER(6,0),
      PRODUCTION NUMBER(3,0),
      ID_MATERIAL NUMBER(6,0), 
      CONSTRAINT PK_MATERIAL PRIMARY KEY(ID_PRODUCT_MATERIAL, ID_MATERIAL),
      CONSTRAINT FK_PRODUCT FOREIGN KEY (ID_PRODUCT_MATERIAL) REFERENCES PRODUCT(ID_PRODUCT),
      CONSTRAINT FK_PRODUCTION FOREIGN KEY (ID_PRODUCT_MATERIAL) REFERENCES PRODUCTION(ID_PRODUCT_PRODUCTION),
      CONSTRAINT FK_PRODUCT2 FOREIGN KEY (ID_MATERIAL) REFERENCES PRODUCT(ID_PRODUCT)
     );

 INSERT INTO PRODUCT (ID_PRODUCT,NAME,WEIGHT,PRICE) VALUES (1,'PRODUCT A',10,5),
 (2,'PRODUCT B',10,5),
 (3,'PRODUCT C',10,5),
 (4,'PRODUCT D',10,5),
 (5,'PRODUCT E',10,5),
 (6,'PRODUCT F',10,5),
 (7,'PRODUCT G',10,5),
 (8,'PRODUCT H',10,5),
 (9,'PRODUCT I',10,5),
 (10,'PRODUCT J',10,5)

INSERT INTO PRODUCT (ID_PRODUCT_PRODUCTION,PRODUCTION) VALUES (1,2),
(2,1),
(3,1)

INSERT INTO MATERIAL (ID_PRODUCT_MATERIAL, PRODUCTION, ID_MATERIAL) VALUES (1,2,2),
(1,2,3),
(1,2,4),
(2,1,9),
(2,1,10),
(3,1,8)
  • Tried with "CONNECT BY" ?

  • I tried, but I didn’t do it the right way. As it would be with "CONNECT BY"?

  • I thought of creating a Protocol with loop to search in column ID_MATERIAL if it exists in column ID_PRODUCT_MATERIAL. But I do not know how to do.

  • I think it would be something like SELECT * FROM MATERIAL M CONNECT BY PRIOR ID_MATERIAL = ID_PRODUCT_MATERIAL , would have the hierarchy as materials

  • @Lucianoamaro which database are you using? By the error I believe it to be Oracle

  • @Tiedttech exactly is oracle

  • if I want to return only 1 level. Is there a way to do with a subselect? How would it look?

  • @Lucianoamaro I couldn’t help you yesterday, but I’ll try to help you. How do you wish to get out?

  • @ as I put up the table, perhaps as the materials of the product materials in front

Show 4 more comments
No answers

Browser other questions tagged

You are not signed in. Login or sign up in order to post.