【问题标题】:How can I insert into a nested table from the resultset of a select statement?如何从 select 语句的结果集中插入嵌套表?
【发布时间】:2018-12-19 15:14:00
【问题描述】:

我有两个同类型的嵌套表,类型是:

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;

此过程中的第二个选择成功返回了我需要的结果集,它是一个包含两列的结果集,一列是国家名称,第二个是出口金额,全部汇总并排序,我想要的是从该结果集到 winery 表中的嵌套表中,包括函数作为参数接收的年份

【问题讨论】:

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


    【解决方案1】:

    您可以使用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 不为空;它可以是空的。它也没有考虑到该国家/地区的现有行,但是从您的数据模型中不清楚是否存在或者如果存在应该发生什么。不过,您可以使用相同的机制更新现有条目,只要您可以识别它。

    【讨论】:

    • 我认为这是我的建议的正确解决方案INSERT INTO (select nombre_pais, cantida, id_bod FROM bodega CROSS JOIN TABLE(exp_an_bod)) ...
    【解决方案2】:

    您可以像这样在 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)) ...
    

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

    【讨论】:

      猜你喜欢
      • 2022-12-31
      • 1970-01-01
      • 1970-01-01
      • 2010-09-12
      • 1970-01-01
      • 2015-02-21
      • 1970-01-01
      • 1970-01-01
      • 2013-12-25
      相关资源
      最近更新 更多