繁体   English   中英

Oracle存储过程要插入到带有嵌套表的表中?

[英]Oracle Stored procedure to insert into a table with a nested table?

这个问题有很多答案,但我无法解决!

我有一个包含嵌套表的表:

    CREATE OR REPLACE TYPE town_objtyp AS OBJECT (
          townName   VARCHAR,
          population     NUMBER,
          desc    VARCHAR(20),   
          ) 
        /

    CREATE TYPE town_nestedtyp AS TABLE OF town_objtyp 
        /

    CREATE OR REPLACE TYPE country_objtyp AUTHID CURRENT_USER AS OBJECT (
          countryName              CHAR(5),
          continent            VARCHAR,
          town_nested     town_nestedtyp,
          ) 
        /

CREATE TABLE Country_objtab OF Country_objtyp (  
           PRIMARY KEY (countryName)
           )                                          

           NESTED TABLE town_nested STORE AS town_store (     
             (PRIMARY KEY(NESTED_TABLE_ID, townName))              
             ORGANIZATION INDEX COMPRESS)                                                                     
        / 

因此,我想创建一个存储过程,以允许用户填充此表。

如果它没有嵌套表,那么它就是这样:

CREATE OR REPLACE PROCEDURE Add_Country (O_countryName IN CHAR, O_continent IN CHAR)
AS

BEGIN
    DBMS_OUTPUT.PUT_LINE ('Insert attempted');

    INSERT INTO Country_objtab(countryName, continent) 
    VALUES(O_countryName, O_continent);

    DBMS_OUTPUT.PUT_LINE ('Insert succeeded');

      END;
/

那么,如何更改此过程,以便用户可以同时在嵌套表中输入n个城镇?

鉴于您当前的过程标头以两个字符串传递并且没有镇信息,因此这应该对您有用:

CREATE OR REPLACE PROCEDURE add_country (o_countryname   IN varchar2,
                                         o_continent     IN varchar2)
AS
BEGIN
   DBMS_OUTPUT.put_line ('Insert attempted');

   INSERT INTO country_objtab (countryname, continent)
           VALUES (
                     NEW country_objtyp (o_countryname,
                                         o_continent,
                                         NEW town_nestedtyp ()));

   DBMS_OUTPUT.put_line ('Insert succeeded');
END;

换句话说,您需要使用构造函数来获取各个属性值(参数)并返回对象类型的实例。

“我们如何更改此过程,以便用户可以同时在嵌套表中输入n个城镇?”

问题是,您想向程序的用户显示多少实施细节? 您可以完全保护他们免受对象类型的侵害,但这只会使他们每次只能添加一个城镇。

CREATE OR REPLACE PACKAGE pkg_country AS
    PROCEDURE add_country (o_countryname   IN varchar2
                        , o_continent     IN varchar2
                        , p_town_name in varchar2
                        , p_town_pop in varchar2 
                        , p_town_descr in varchar2  );
    PROCEDURE add_town (o_countryname   IN varchar2
                        , p_town_name in varchar2
                        , p_town_pop in varchar2 
                        , p_town_descr in varchar2  );                        
END;
/                        
CREATE OR REPLACE PACKAGE BODY pkg_country AS
    PROCEDURE add_country (o_countryname   IN varchar2
                        , o_continent     IN varchar2
                        , p_town_name in varchar2
                        , p_town_pop in varchar2 
                        , p_town_descr in varchar2  )
    IS
    BEGIN
       INSERT INTO country_objtab VALUES 
       ( NEW country_objtyp (o_countryname,
                             o_continent,
                             NEW town_nestedtyp (
                                new town_objtyp(p_town_name , 
                                                 p_town_pop , 
                                                 p_town_descr ) 
                                )
                            )
                        );
    END  add_country;   

    PROCEDURE add_town (o_countryname   IN varchar2
                        , p_town_name in varchar2
                        , p_town_pop in varchar2 
                        , p_town_descr in varchar2  )
    IS
    BEGIN
      insert into the 
            (select t.town_nested  from Country_objtab t
            where t.countryname  = o_countryname) 
       values ( new town_objtyp(p_town_name , 
                                p_town_pop , 
                                p_town_descr ));
        END  add_town;                                     

END pkg_country;
/

要一次创建一个具有多个城镇的国家,可以更改签名以接受多个城镇对象:

CREATE OR REPLACE PACKAGE pkg_country AS
    PROCEDURE add_country (o_countryname   IN varchar2
                        , o_continent     IN varchar2
                        , p_town_1 in town_objtyp := null
                        , p_town_2 in town_objtyp := null
                        , p_town_3 in town_objtyp := null );
    PROCEDURE add_town (o_countryname   IN varchar2
                        , p_town in town_objtyp  );
END;
/                        
CREATE OR REPLACE PACKAGE BODY pkg_country AS
    PROCEDURE add_country (o_countryname   IN varchar2
                        , o_continent     IN varchar2
                        , p_town_1 in town_objtyp := null
                        , p_town_2 in town_objtyp := null
                        , p_town_3 in town_objtyp := null  )
    IS
        l_towns town_nestedtyp := new town_nestedtyp();
    BEGIN
       if p_town_1 is not null then
           l_towns.extend();
           l_towns(l_towns.count()) := p_town_1;
       end if;
       if p_town_2 is not null then
           l_towns.extend();
           l_towns(l_towns.count()) := p_town_2;
       end if;
       if p_town_3 is not null then
           l_towns.extend();
           l_towns(l_towns.count()) := p_town_3;
       end if;

       INSERT INTO country_objtab VALUES 
       ( NEW country_objtyp (o_countryname,
                             o_continent,
                             l_towns
                            )
                        );
    END  add_country;   

    PROCEDURE add_town (o_countryname   IN varchar2
                        , p_town_name in varchar2
                        , p_town_pop in varchar2 
                        , p_town_descr in varchar2  )
    IS
    BEGIN
      insert into the 
            (select t.town_nested  from Country_objtab t
            where t.countryname  = o_countryname) 
       values ( new town_objtyp(p_town_name , 
                                p_town_pop , 
                                p_town_descr ));

    END  add_town;                                     

END pkg_country;
/

这显然是一个笨拙的接口和笨拙的实现。 而且,它对第一个呼叫中可以包含多少个城镇施加了人为的和不希望的限制。 因此,您应该做的是将数组填充外包给调用程序:

CREATE OR REPLACE PACKAGE pkg_country AS
    PROCEDURE add_country (o_countryname   IN varchar2
                        , o_continent     IN varchar2
                        , p_towns in town_nestedtyp);
    PROCEDURE add_town (o_countryname   IN varchar2
                        , p_town in town_objtyp  );

END;
/                        
CREATE OR REPLACE PACKAGE BODY pkg_country AS
    PROCEDURE add_country (o_countryname   IN varchar2
                        , o_continent     IN varchar2
                        , p_town_1 in town_objtyp := null
                        , p_town_2 in town_objtyp := null
                        , p_town_3 in town_objtyp := null  )
    IS
    BEGIN

       INSERT INTO country_objtab VALUES 
       ( NEW country_objtyp (o_countryname,
                             o_continent,
                             p_towns
                            )
                        );
    END  add_country;   

    PROCEDURE add_town (o_countryname   IN varchar2
                        , p_town_name in varchar2
                        , p_town_pop in varchar2 
                        , p_town_descr in varchar2  )
    IS
    BEGIN
      insert into the 
            (select t.town_nested  from Country_objtab t
            where t.countryname  = o_countryname) 
       values ( new town_objtyp(p_town_name , 
                                p_town_pop , 
                                p_town_descr ));

    END  add_town;                                     

END pkg_country;
/

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM