代码之家  ›  专栏  ›  技术社区  ›  freesoft

PL/SQL:如何从游标创建类型

  •  6
  • freesoft  · 技术社区  · 11 年前

    我可以从游标定义类型吗?

    目前,为了从一些表字段创建记录变量,我必须编写以下内容:

    declare
    
        cursor cur
        is
            select 
                f_1,
                f_2,
                f_3,
                f_4
            from
                mytable
            where 
                1=0;
    
        myvar cur%rowtype;              -- use the cursor to declare myvar
    
    begin
        null;
    end;
    

    我想写这样的东西:

    declare
    
        cursor cur
        is
            select 
                f_1,
                f_2,
                f_3,
                f_4
            from
                mytable
            where 
                1=0;
    
        type mytype is cur%rowtype;     -- declare "mytype" from cursor
        myvar mytype;                   -- use "mytype" to declare "myvar"
    
    begin
        null;
    end;
    

    这在这个微不足道的例子中看起来没有什么用处,但在实际问题中可能有用。

    另一种方法是手动创建记录类型:

    declare
    
        type mytype is record           -- declare "mytype"
        (
            f_1    mytable.f_1%type,
            f_2    mytable.f_2%type,
            f_3    mytable.f_3%type,
            f_4    mytable.f_4%type
        );
        myvar mytype;                   -- use "mytype" to declare "myvar"
    
    begin
        null;
    end;
    

    但这对我来说更脏(我必须重复每个字段名两次,重复表名多次)。

    2 回复  |  直到 11 年前
        1
  •  7
  •   Nick Krasnov    11 年前

    我可以从游标定义类型吗?

    是的,您可以定义基于 cursor_name%rowtype 记录类型(在这种情况下基本上是同义词),使用 subtype 关键字,而不是 type

    下面是一个示例:

    set serveroutput on;
    declare
      cursor c1 is
        select 1 as col1
             , 2 as col2
             , 3 as col3
         from dual;
    
      subtype mytype is c1%rowtype;
      l_myvar mytype;
    begin
      open c1;
      fetch c1 into l_myvar;
      dbms_output.put(to_char(l_myvar.col1) || ' : ');
      dbms_output.put(to_char(l_myvar.col2) || ' : ');
      dbms_output.put_line(to_char(l_myvar.col3));
      close c1;
    end;
    

    结果:

    anonymous block completed
    
    1 : 2 : 3
    
        2
  •  0
  •   Bob Jarvis - Слава Україні    11 年前

    我认为您在这里要做的是使用ROWTYPE变量,如下所示:

    DECLARE
      CURSOR c1 IS
        SELECT t.COL1, t.COL2, t.COL3
          FROM MY_TABLE t
          WHERE t.ADD_DATE >= TRUNC(SYSDATE, 'MONTH');
    
      c1Row  c1%ROWTYPE;
    BEGIN
      OPEN c1;
    
      LOOP
        FETCH c1 INTO c1Row;
        EXIT WHEN c1%NOTFOUND;
    
        DBMS_OUTPUT.PUT_LINE('COL1=' || c1Row.COL1 ||
                             '  COL2=' || c1Row.COL2 ||
                             '  COL3=' || c1Row.COL3);
      END LOOP;
    
      CLOSE c1;
    END;
    

    Reference here

    分享并享受。