暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

Oracle 12c-PL/SQL中的列表

askTom 2017-12-13
413

问题描述

我正在玩Oracle 12,并尝试一些新功能。新功能之一是LISTAGG现在可以处理溢出。它在SQL中可以正常工作,但是当我在PL/SQL中尝试它时,它似乎不起作用。

我尝试了以下几点:
DECLARE
    query_result        varchar2(1000);
BEGIN
    SELECT LISTAGG(first_name || ' ' || last_name, ', ' ON OVERFLOW TRUNCATE) WITHIN GROUP (ORDER BY employee_id)
    INTO query_result
    FROM hr.employees;
    
    dbms_output.put_line('Result = ' || query_result);
END;


这导致了以下错误:

ORA-06502: PL/SQL: numeric or value error: character string buffer too small ORA-06512: at line 5
ORA-06512: at "SYS.DBMS_SQL", line 1721



专家解答

listagg的扩展是为了避免 * datatype * 溢出错误。所以 (取决于你的init.ora) 设置这将是4000或32767字节

SQL> DECLARE
  2      query_result        varchar2(1000);
  3  BEGIN
  4      SELECT LISTAGG(first_name || ' ' || last_name, ', ' ON OVERFLOW TRUNCATE) WITHIN GROUP (ORDER BY employee_id)
  5      INTO query_result
  6      FROM hr.employees;
  7
  8      dbms_output.put_line('Result = ' || query_result);
  9  END;
 10  /
DECLARE
*
ERROR at line 1:
ORA-06502: PL/SQL: numeric or value error: character string buffer too small
ORA-06512: at line 4


SQL> DECLARE
  2      query_result        varchar2(4000);
  3  BEGIN
  4      SELECT LISTAGG(first_name || ' ' || last_name, ', ' ON OVERFLOW TRUNCATE) WITHIN GROUP (ORDER BY employee_id)
  5      INTO query_result
  6      FROM hr.employees;
  7
  8      dbms_output.put_line('Result = ' || query_result);
  9  END;
 10  /

PL/SQL procedure successfully completed.

SQL> SELECT length(LISTAGG(first_name || ' ' || last_name, ', ' ON OVERFLOW TRUNCATE) WITHIN GROUP (ORDER BY employee_id))
  2  FROM hr.employees;

LENGTH(LISTAGG(FIRST_NAME||''||LAST_NAME,','ONOVERFLOWTRUNCATE)WITHINGROUP(ORDERBYEMPLOYEE_ID))
-----------------------------------------------------------------------------------------------
                                                                                           1587

1 row selected.



例如,在我的数据库中,varchar2的长度上限为32k,因此listagg将截断到

SQL> select sum(length(owner)) from all_objects;

SUM(LENGTH(OWNER))
------------------
            312922

1 row selected.

SQL>
SQL> SELECT length(LISTAGG(owner, ', ' ON OVERFLOW TRUNCATE) WITHIN GROUP (ORDER BY object_id))
  2  FROM all_objects;

LENGTH(LISTAGG(OWNER,','ONOVERFLOWTRUNCATE)WITHINGROUP(ORDERBYOBJECT_ID))
-------------------------------------------------------------------------
                                                                    32742


「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论