字符串缓冲区错误太小

时间:2012-12-14 05:47:37

标签: sql oracle11g

我正在尝试使用select语句创建一个表。我想用VIEW中的聚合值填充这个新表。以下是用于创建VIEW的代码,

  create or replace view FINAL_WEB_LOG
 as
 select SESSION_ID, 
        SESSION_DT, 
        C_IP, 
        CS_USER_AGENT,
        tab_to_string(CAST(COLLECT(web_link) AS t_varchar2_tab)) WEBLINKS
 from web_views_tab    
 group by C_IP, CS_USER_AGENT, SESSION_DT;

我想创建一个包含WEBLINKS和SESSION_ID的表,这是来自另一个表的序列。当我尝试从VIEW(没有SESSION_ID的那个)创建表时,我收到以下错误,

SQL错误:ORA-06502:PL / SQL:数字或值错误:字符串缓冲区太小

这与字段,Weblinks有关,它确实有更长的值。我现在可以做些什么来解决这个错误?

有关聚合函数的更多信息,请参阅AskTom

5 个答案:

答案 0 :(得分:1)

您不能使用不属于GROUP BY子句但未被聚合函数覆盖的列。因为在这种情况下不可能知道应该返回哪个值。

如果保证每组都是唯一的 - 你可以用

欺骗数据库
MIN(SESSION_ID) SESSION_ID

但请记住,这样做不是一个好习惯: - )

答案 1 :(得分:1)

您无法选择不按功能分组的字段。您使用不同的session_id对少数字段进行分组。您认为如何选择一个?

答案 2 :(得分:1)

您的陈述现在无效,您可以按以下方式将列C_IPCS_USER_AGENT添加到群组中:

create or replace view FINAL_WEB_LOG
 as
 select SESSION_ID, 
        SESSION_DT, 
        C_IP, 
        CS_USER_AGENT,
        tab_to_string(CAST(COLLECT(web_link) AS t_varchar2_tab)) WEBLINKS
 from web_views_tab    
 group by C_IP, CS_USER_AGENT, SESSION_DT, C_IP, CS_USER_AGENT, WEBLINKS;

或者你改变它们以使用从COUNT(),AVG(),MAX(),MIN()等集合返回一个值的函数,如:

create or replace view FINAL_WEB_LOG
 as
 select SESSION_ID, 
        SESSION_DT, 
        COUNT(C_IP), 
        COUNT(CS_USER_AGENT),
        Count(tab_to_string(CAST(COLLECT(web_link) AS t_varchar2_tab))) WEBLINKS
 from web_views_tab    
 group by C_IP, CS_USER_AGENT, SESSION_DT;

答案 3 :(得分:1)

session_id放在GROUP BY子句中。您应该始终将SELECT子句中的所有非聚合函数列放在GROUP BY子句中。

答案 4 :(得分:1)

如果结果是>则使用CLOB。 4000字节。

SQL> create table web_views_tab(SESSION_ID number, SESSION_DT date, C_IP varchar2(20), CS_USER_AGENT varchar2(10), web_link varchar2(100));

Table created.

SQL> insert into web_views_tab
  2  select rownum, trunc(sysdate), '127.0.0.1', 'Mozilla', 'http://foo.bar.com/asdakjdlkajdlkajsd/asdjaldjklja'
  3  from dual
  4  connect by level <= 3000;

3000 rows created.

SQL> CREATE OR REPLACE TYPE t_varchar2_tab AS TABLE OF VARCHAR2(4000);
  2  /

Type created.

SQL> CREATE OR REPLACE FUNCTION tab_to_string (p_varchar2_tab  IN  t_varchar2_tab,
  2                                            p_delimiter     IN  VARCHAR2 DEFAULT ',') RETURN VARCHAR2 IS
  3    l_string     VARCHAR2(32767);
  4  BEGIN
  5    FOR i IN p_varchar2_tab.FIRST .. p_varchar2_tab.LAST LOOP
  6      IF i != p_varchar2_tab.FIRST THEN
  7        l_string := l_string || p_delimiter;
  8      END IF;
  9      l_string := l_string || p_varchar2_tab(i);
 10    END LOOP;
 11    RETURN l_string;
 12  END tab_to_string;
 13  /

Function created.

SQL> create or replace view FINAL_WEB_LOG
  2   as
  3   select SESSION_DT,
  4          C_IP,
  5          CS_USER_AGENT,
  6          tab_to_string(CAST(COLLECT(web_link) AS t_varchar2_tab)) WEBLINKS
  7   from web_views_tab
  8   group by C_IP, CS_USER_AGENT, SESSION_DT;

View created.

SQL> select * from FINAL_WEB_LOG;
select * from FINAL_WEB_LOG
                          *
ERROR at line 1:
ORA-06502: PL/SQL: numeric or value error: character string buffer too small
ORA-06512: at "TEST.TAB_TO_STRING", line 9
ORA-06512: at line 1

所以我们将函数输出重新定义为clob并改变函数:

SQL> CREATE OR REPLACE FUNCTION tab_to_string (p_varchar2_tab  IN  t_varchar2_tab,
  2                                            p_delimiter     IN  VARCHAR2 DEFAULT ',') RETURN clob IS
  3    l_string     clob;
  4  BEGIN
  5    dbms_lob.createtemporary(l_string, true, dbms_lob.call);
  6     dbms_lob.open(l_string, dbms_lob.lob_readwrite);
  7    FOR i IN p_varchar2_tab.FIRST .. p_varchar2_tab.LAST LOOP
  8      IF i != p_varchar2_tab.FIRST THEN
  9        dbms_lob.writeappend(l_string, length(p_delimiter), p_delimiter);
 10      END IF;
 11        dbms_lob.writeappend(l_string, length(p_varchar2_tab(i)), p_varchar2_tab(i));
 12    END LOOP;
 13     dbms_lob.close(l_string);
 14    RETURN l_string;
 15  END tab_to_string;
 16  /

Function created.

SQL>
SQL> select * from FINAL_WEB_LOG;

SESSION_D C_IP                 CS_USER_AG
--------- -------------------- ----------
WEBLINKS
--------------------------------------------------------------------------------
14-DEC-12 127.0.0.1            Mozilla
http://foo.bar.com/asdakjdlkajdlkajsd/asdjaldjklja,http://foo.bar.com/asdakjdlka