如何从select语句的结果集中插入嵌套表?

时间:2018-12-19 15:14:00

标签: sql database oracle plsql user-defined-types

我有两个表,它们的嵌套表类型相同,类型为:

CREATE OR REPLACE TYPE tipo_valor AS OBJECT (
ano        DATE,   --year
cantidad   INTEGER  --ammount of exported wine
) ;

CREATE OR REPLACE TYPE hist_export AS OBJECT (
   nombre_pais   VARCHAR2(100),  --name of importer country
   cantidad      tipo_valor --type referenced above
 );

嵌套表:

CREATE OR REPLACE TYPE nt_hist_exp IS
TABLE OF hist_export;

我的两个表是:

CREATE TABLE bodega (  --winery
    id_bod                   INTEGER NOT NULL,
    exp_an_bod               nt_hist_exp ,
)

CREATE TABLE marca (  --wine
id_marca                INTEGER NOT NULL,
exp_an_marca            nt_hist_exp 
)

我有一个带有select语句的程序,该语句从特定年份的葡萄酒表中收集出口量并按国家/地区进行订购,

PROCEDURE exp_bod ( p_ano DATE,
                      p_bod_nom VARCHAR2)IS
    sumatoria INTEGER;
    p_idbod INTEGER;
    BEGIN
      SELECT id_bod INTO p_idbod
      FROM bodega 
      WHERE nombre_bod = p_bod_nom;
      DBMS_OUTPUT.PUT_LINE(to_char(p_idbod));
      SELECT nt.nombre_pais,sum(nt.cantidad.cantidad)
      INTO sumatoria
      FROM bodega b
      JOIN presentacion p on p.bodega_fk = b.id_bod
      JOIN marca m on m.id_marca = p.marca_fk
      CROSS JOIN TABLE(m.exp_an_marca) nt
      WHERE b.id_bod = p_idbod
      AND nt.cantidad.ano = p_ano
      group by nt.nombre_pais
      order by nt.nombre_pais;
      );

end exp_bod;

此过程中的第二个选择成功返回了我需要的结果,这是一个具有两列的结果集,其中一个具有国家名称,第二个具有导出数量,所有这些都被总结和排序,我想要的是从中插入行将该结果集放入酒厂表的嵌套表中,其中包括该函数作为参数接收的年份

2 个答案:

答案 0 :(得分:2)

您可以使用insert as select在查询中创建对象类型的实例:

INSERT INTO TABLE (SELECT exp_an_bod FROM bodega b WHERE b.nombre_bod = p_bod_nom)
SELECT hist_export(nt.nombre_pais, tipo_valor(nt.cantidad.ano, sum(nt.cantidad.cantidad)))
FROM bodega b
JOIN presentacion p on p.bodega_fk = b.id_bod
JOIN marca m on m.id_marca = p.marca_fk
CROSS JOIN TABLE(m.exp_an_marca) nt
WHERE b.nombre_bod = p_bod_nom
AND nt.cantidad.ano = p_ano
GROUP BY nt.nombre_pais, nt.cantidad.ano;

我假设nombre_bodbodega上的一列,尽管您没有在表定义中显示它,这意味着您实际上不需要为此单独进行查找。

这还假设exp_an_bod不为null;它可以是空的。它也没有为该国家的现有行留出任何余地,但是从您的数据模型中并不清楚是否可以存在,或者如果存在将会发生什么。不过,只要您可以识别它,就可以使用相同的机制更新现有条目。

答案 1 :(得分:1)

您可以像这样在PL / SQL中做到这一点:

declare
   hist_exp nt_hist_exp;
begin
   select exp_an_bod
   into hist_exp
   from bodega 
   where id_bod = 123;

   hist_exp.extend;
   hist_exp(hist_exp.LAST) := hist_export('xyz', 456);

   update bodega 
   set exp_an_bod = hist_exp
   where id_bod = 123;

end;

如果您想先更新而不是插入,也可以使用

UPDATE (select nombre_pais, cantida, id_bod FROM bodega CROSS JOIN TABLE(exp_an_bod))  
SET nombre_pais = 'abc'
WHERE id_bod = 123
   and cantida = 456;

您也可以尝试

INSERT INTO (select nombre_pais, cantida, id_bod FROM bodega CROSS JOIN TABLE(exp_an_bod)) ...

但是我认为这是不可能的-我从未尝试过。