【问题标题】:How to print the cursor values in oracle?如何在 oracle 中打印光标值?
【发布时间】:2020-01-29 01:45:59
【问题描述】:

我是 oracle 新手,我正在学习游标。我的表 City 有两列 city_id,city_name。所以,这就是我尝试过的:

DECLARE
  CURSOR city_list is
  SELECT * from OT.City;

  v_list SYS_REFCURSOR;
BEGIN
  OPEN city_list FOR
   v_list := city_list;
   DBMS_OUTPUT.PUT_LINE(v_list.city_id);
   EXIT WHEN city_list%NOTFOUND;
  CLOSE city_list;
END;
/

我正在尝试将游标的数据分配给新声明的值v_list SYS_REFCURSOR;。但输出在v_list := city_list; 处出现错误。如何将游标的所有值直接分配给另一个游标或是否存在还有其他方法吗?

【问题讨论】:

  • 附带说明:使用隐式游标要容易得多,例如:for rec in (select * from ot.city) loop dbms_output.put_line(rec.city_id); end loop;

标签: sql oracle stored-procedures plsql oracle11g


【解决方案1】:

在 11g 中,从光标打印值的最简单方法是传递光标变量:

var rc refcursor
begin
    open :rc for
    select City.* from (
        select rownum id, trim (column_value) name 
        from xmlTable ('"New York","Paris"')) City;
end;
/
print rc

        ID NAME            
---------- ----------------
         1 New York        
         2 Paris     

【讨论】:

  • set autoprint on 或在 PL/SQL 块之后使用 print rc;
【解决方案2】:

这个问题是用 oracle 11g 标记的,但是让我提供在 oracle 12c 中引入的返回结果的新方法。

DBMS_SQL.RETURN_RESULT(l_cursor) 可用于在 oracle 12c 中打印结果。

DECLARE
 v_list SYS_REFCURSOR
BEGIN
 Open v_list for
 SELECT * from OT.City;

 DBMS_SQL.RETURN_RESULT(v_list);
END;
/

干杯!!

【讨论】:

  • 但是 11g 呢?
  • @Tejash,DBMS_SQL.RETURN_RESULT 是循环内 DBMS_OUTPUT.PUT_LINE 打印游标结果的唯一选择吗?或者这也可以在其他任何地方使用?
  • 据我所知,这是唯一的选择。其他的要写在文件里。
【解决方案3】:

您仍然可以使用SYS_REFCURSOR,方法是在OPENFOR 子句之间定位,然后是光标,然后

需要在当前代码后添加LOOP FETCH INTO... END LOOP 模板并关闭打开的光标:

DECLARE
  v_list SYS_REFCURSOR;
  v_city_id   city.city_id%TYPE;
  v_city_name city.city_name%TYPE;
BEGIN 
  OPEN v_list FOR
    SELECT city_id, city_name FROM City;

  LOOP 
    FETCH v_list
    INTO  v_city_id, v_city_name;
    EXIT WHEN v_list%NOTFOUND;
    DBMS_OUTPUT.PUT_LINE(v_city_id || ' - ' || v_city_name);
  END LOOP;
  CLOSE v_list;  
END;
/

Demo

【讨论】:

    【解决方案4】:

    你的代码有很多问题,例如:

    • v_list 应声明为 city_list%ROWTYPE
    • 你需要OPEN光标然后LOOP
    • 要将当前记录分配给city_list,您想使用FETCH INTO

    考虑一下你的代码的这个新版本:

    DECLARE
        CURSOR city_list IS SELECT * from city ORDER BY city_id;
        v_list city_list%ROWTYPE;
    BEGIN
        OPEN city_list;
        LOOP
            FETCH city_list INTO v_list;
            EXIT when city_list%notfound;
            DBMS_OUTPUT.PUT_LINE(v_list.city_id);
        END LOOP;
        CLOSE city_list;
    
    END;
    /
    

    this demo on DB Fiddle中,给定city表的以下内容:

    CITY_ID | CITY_NAME  
    ------: | :----------
          1 | New York   
          2 | Los Angeles
    

    代码输出:

    1 行受影响 dbms_输出: 1 2

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-08-19
      • 1970-01-01
      • 1970-01-01
      • 2018-05-29
      • 1970-01-01
      相关资源
      最近更新 更多