SQL - 将信息与类似的主键/ ID组合在一起

时间:2017-02-02 02:46:35

标签: sql oracle plsql

我知道之前曾问过这个问题,但是针对这个问题的解决方案并不适用于我。我无法写一条评论来说明我的问题,因为我需要50点声望。

详细信息:

Oracle版本10g

已提供解决方案:

invoiceLine.product = product

我尝试使用虚假数据创建一个虚拟表来测试逻辑,看它是否适用于我,它确实如此。但是,当我将查询用于真实数据时,会出现错误消息:

  

ORA-22813:操作数值超出系统限制

错误提示

enter image description here

在阅读之后,我发现这是因为我的数据太大了。

我尝试创建表格和查询来从中调用

select book_id,
       'Total Hours of Loan: ' || to_char(sum(hours_of_loan)) || chr(10) || 
       lpad('-', 30, '-')      || chr(10) ||
       xmlagg(xmlelement(x, descr, chr(10) || lpad('-', 30, '-') || chr(10)).extract('//text()')
                         order by date_of_loan)  as book_description
from   (
         select book_id, date_of_loan, hours_of_loan,
                'Written by: '      || checked_by                          || chr(10) ||
                'Date of Loan : '   || to_char(date_of_loan, 'mm/dd/yy')   || chr(10) ||
                'Hour(s) of Loan: ' || to_char(hours_of_loan)              || chr(10) ||
                'Comments: '        || comments                            || chr(10) ||
                'Student: '         || student      as descr
         from   student_book
       )
group by book_id
order by book_id
;

这并没有真正解决我的问题,但它结合了所有"评论"哪个具有特定的BOOK_ID但没有格式

尝试过的解决方案

DECLARE
  sSUM_TEXT  CLOB;
  sBOOK_ID VARCHAR2(10):= '1';
  nCount     NUMBER:=1;
BEGIN
  FOR rRECORDRec IN(SELECT BOOK_ID, CHECKED_BY, DATE_OF_lOAN, HOURS_OF_LOAN, COMMENTS, STUDENT  
                        FROM STUDENT_BOOK
                        WHERE BOOK_ID = '1')
  LOOP
    IF nCount != 1 THEN
      sSUM_TEXT := sSUM_TEXT||chr(10)||
                'Written by: '      || rRECORDRec.checked_by                 || chr(10) ||
                'Date of Loan : '   || rRECORDRec.date_of_loan               || chr(10) ||
                'Hour(s) of Loan: ' || rRECORDRec.hours_of_loan              || chr(10) ||
                'Comments: '        || rRECORDRec.comments                   || chr(10) ||
                'Student: '         || rRECORDRec.student                    || chr(10) ||
                '--------------------------------';
    ELSE
      sSUM_TEXT :=  'Written by: '      || rRECORDRec.checked_by                 || chr(10) ||
                    'Date of Loan : '   || rRECORDRec.date_of_loan               || chr(10) ||
                    'Hour(s) of Loan: ' || rRECORDRec.hours_of_loan              || chr(10) ||
                    'Comments: '        || rRECORDRec.comments                   || chr(10) ||
                    'Student: '         || rRECORDRec.student                    || chr(10) ||
                '--------------------------------';
    END IF;
    nCount := nCount + 1;
  END LOOP;

  INSERT INTO COMMENTS_SUMMARY(BOOK_ID,SUM_TEXT)
  VALUES (sBOOK_ID,sSUM_TEXT);
  COMMIT;
END;

同样的错误提示

第二个SELECT语句

我尝试单独运行查询。我为真实数据运行了第二个SELECT语句,即使没有 TO_CLOB

,也没有提示错误
select book_id,
       'Total Hours of Loan: ' || to_char(sum(hours_of_loan)) || chr(10) || 
       lpad('-', 30, '-')      || chr(10) ||
       xmlagg(xmlelement(x, descr, chr(10) || lpad('-', 30, '-') || chr(10)).extract('//text()')
                         order by date_of_loan) as book_description
from   (
         select book_id, date_of_loan, hours_of_loan,
                to_clob('Written by: '  || checked_by                 || chr(10) ||
                'Date of Loan : '       || date_of_loan               || chr(10) ||
                'Hour(s) of Loan: '     || hours_of_loan              || chr(10) ||
                'Comments: '            || comments                   || chr(10) ||
                'Student: '             || student)      as descr
         from   student_book
       )
group by book_id
order by book_id;

enter image description here

我的问题:

如何克服此问题并将数据基于其ID分组?

1 个答案:

答案 0 :(得分:1)

可能至少有几本书有太多贷款,因此XMLAGG中的字符串长度超过4000个字符。所以你必须处理CLOB。

您需要在此处添加.getclobval()

... order by date_of_loan).getclobval() as book_description

甚至可能是一个"贷款"已经太长了(超过4000个字符)。这是串联的问题 - 如果所有输入都小于4000个字符,Oracle会将它们视为VARCHAR2,并期望结果也是VARCHAR2(不超过4000个字符)。为了强迫"它将所有内容视为CLOB,只需将第一个输入设为CLOB即可。

而不是'Written by: '(在代码中找到它)使用

... to_clob('Written by: ')