【问题标题】:Initialising a pl/sql record type初始化 pl/sql 记录类型
【发布时间】:2011-12-23 21:26:44
【问题描述】:

在 PL/SQL 中,varray 可以在创建时初始化为:

TYPE colour_tab IS VARRAY(3) OF VARCHAR2(20);
    french_colours colour_tab := colour_tab('RED','WHITE','BLUE');

对于 PL/SQL 记录类型是否有等效的初始化方法?

type location_record_type is record (
      street_address       varchar2(40),
     postal_code          varchar2(12),
      city                 varchar2(30),
     state_province       varchar2(25),
     country_id           char(2) not null := 'US'
    );

【问题讨论】:

  • 如果您将该类型设置为数据库对象,那么您可以这样做。或者我认为如果你不为对象类型创建构造函数,你必须这样做。
  • *.com/a/28208606/214728 上查看我的答案,这应该类似于 colour_tab := colour_tab('RED','WHITE','BLUE') 编码
  • Oracle 18c 引入了您正在寻找的功能 - 有关详细信息,请参阅下面的答案

标签: sql oracle plsql oracle10g


【解决方案1】:

不,没有。您必须明确分配每个值。 Documentation reference here.

【讨论】:

  • *.com/a/28208606/214728 上查看我的回答,这应该类似于 colour_tab := colour_tab('RED','WHITE','BLUE') 编码
【解决方案2】:

记录类型实际上是为保存 SELECT 语句中的行而设计的。

    ....
    type location_record_type is record (
          street_address       varchar2(40),
         postal_code          varchar2(12),
          city                 varchar2(30),
         state_province       varchar2(25),
         country_id           char(2) not null := 'US'
        );
    type location_record_nt is table of location_record_type;
    loc_recs location_record_nt;
begin
    select street_name
           , pcode
           , city
           , region
           , country_code
    bulk collect into loc_recs
    from t69
    where ....

显然,对于查询不是 SELECT * FROM 单个表的情况(因为在这种情况下,我们可以改用 %ROWTYPE

【讨论】:

    【解决方案3】:

    使用函数充当一种“构造函数”(查看函数 f()):

    DECLARE
      TYPE ty_emp IS RECORD(
        id INTEGER,
        name VARCHAR(30),
        deptcode VARCHAR(10)
        );
      TYPE ty_tbl_emp IS TABLE OF ty_emp;
      tbl_emp ty_tbl_emp;
      FUNCTION f (             -- <==============
        id INTEGER,
        name VARCHAR,
        deptcode VARCHAR) RETURN ty_emp IS
      e ty_emp;
      BEGIN
        e.id := id;
        e.name := name;
        e.deptcode := deptcode;
        RETURN e;
      END f;
    BEGIN
    
      tbl_emp := ty_tbl_emp(
        f(1, 'Johnson', 'SALES'), 
        f(2, 'Peterson', 'ADMIN'));
      Dbms_Output.put_line(tbl_emp(2).name);
    END;  
    

    【讨论】:

      【解决方案4】:

      您可以创建一个返回该记录类型的函数。

      参见下面的示例代码:

      DECLARE
         type location_record_type is record (
            street_address       varchar2(40),
            postal_code          varchar2(12),
            city                 varchar2(30),
            state_province       varchar2(25),
            country_id           char(2) not null := 'US');
         v_loc_rec location_record_type;
         FUNCTION new_loc_rec RETURN location_record_type
         IS
            v_new_loc_rec location_record_type;
         BEGIN
            return v_new_loc_rec;
         END;
      BEGIN
          v_loc_rec := new_loc_rec;
          v_loc_rec.state_province := 'SomeState';
          v_loc_rec.country_id := 'SU';
          dbms_output.put_line('State: '||v_loc_rec.state_province||'; Country_ID: '||v_loc_rec.country_id);
          v_loc_rec := new_loc_rec;
          dbms_output.put_line('State: '||v_loc_rec.state_province||'; Country_ID: '||v_loc_rec.country_id);
      END;
      

      【讨论】:

        【解决方案5】:

        Oracle 18c 允许使用qualified expressions 进行记录初始化:

        declare 
        type location_record_type is record (
              street_address       varchar2(40),
             postal_code          varchar2(12),
              city                 varchar2(30),
             state_province       varchar2(25),
             country_id           char(2) not null := 'US'
            );
        
        myvar location_record_type;
        myvar2 location_record_type := location_record_type(street_address => 'my street'
                                                           ,postal_code    => 'my code'
                                                           ,city           => 'my city'
                                                           ,state_province => 'my state'
                                                           ,country_id     => 'GB'
                                                           );
        
        begin
          dbms_output.put_line(myvar.country_id);
          dbms_output.put_line(myvar2.city);
        end;
        /
        

        上面的输出是...

        US
        my city
        

        您可以在 Oracle Live SQL here 中运行上述示例代码。 (不幸的是,该网站需要登录。)

        【讨论】:

          【解决方案6】:

          记录初始化在其声明中执行 并通过从 DUAL 中选择来记录分配:

              declare
                  type location_record_type is record
                  (
                      street_address       varchar2(40) := '1234 Fake Street',
                      postal_code          varchar2(12) := '90210',
                      city                 varchar2(30) := 'Springfield',
                      state_province       varchar2(25) := 'KY',
                      country_id           char(2) not null := 'US'
                  );
                  v_location location_record_type;
          
             begin 
                select 
                  '4321 Another St.', '48288', 'Detroit', 'MI', v_location.country_id
                into v_location from dual;
              end;
              /
          

          【讨论】: