由于字段大小有限,数据未保存在数据库中

时间:2012-10-23 12:20:57

标签: java sql oracle

架构message的数据库表fsr_system_log中有一列fsr_appl。该表应该存储系统日志消息。列的大小为255,数据类型为varchar2。用于保存大小超过255个字符的消息的逻辑是:

public void saveSystemLog(SystemLogRequest systemLog){
    User user = systemLog.getUser();
    String system = systemLog.getSystem();
    Log log = systemLog.getSystemLog();

    try {
        initializeDelegate();
        delegate.beginTransaction();

        LogEntry[] logEntries = log.getItemArray();
        for (LogEntry logEntry : logEntries) {
            // Save each entry
            ParamVector<Object> params = new ParamVector<Object>();

            //Check if message is greater than 255 characters
            String message = logEntry.getMsg();
            notifier.debug("Log Message is : " + message);
            if(message.length()>255){
                message = message.substring(0,255);
                notifier().debug("Message string greater than 255 characters : " + message);
            }
            params.add(message, 255, false);
}

但是尽管实现了代码,我还是面临以下错误:

  

由于SQL错误而无法保存系统日志:ORA-12899:值对于“FSR_APPL”列而言太大。 “FSR_SYSTEM_LOG”。 “MESSAGE”(实际:257,   最大值:255)

正在使用的示例日志是:

<xbe:systemLogRequest xmlns:xbe="http://tdc.dk/fsr/common/xbean">
<user>
    <userNumber>a62267</userNumber>
</user>
<system>Client</system>
<systemLog>
    <item>
        <timestamp>2011-10-27T17:03:08.404+02:00</timestamp>
        <type>Info</type>
        <msg><![CDATA[<html><center>Din registrering er nu sendt<br><br>Tak for indmeldingen</center></html>]]></msg>
    </item>
    <item>
        <timestamp>2011-10-27T17:03:13.701+02:00</timestamp>
        <type>Info</type>
        <msg><![CDATA[<html><center>Din registrering er nu sendt<br><br>Tak for indmeldingen</center></html>]]></msg>
    </item>
    <item>
        <timestamp>2011-10-28T12:45:47.801+02:00</timestamp>
        <type>Info</type>
        <msg><![CDATA[<html><center>Din registrering er nu sendt<br><br>Tak for indmeldingen</center></html>]]></msg>
    </item>
    <item>
        <timestamp>2011-10-28T12:45:57.926+02:00</timestamp>
        <type>Info</type>
        <msg>Afsluttet uden at gemme fejlregistering</msg>
    </item>
</systemLog>
</xbe:systemLogRequest>

请帮忙!

注意:抛出的错误仅适用于某些系统日志消息。当抛出此错误时,实际值始终为常量257。

3 个答案:

答案 0 :(得分:1)

显然,您有一些用多个字节表示的字符。

在Java中,您可以获得字符中字符串的长度,而Oracle显然会检查字节限制,因为列的定义方式。

查看表的定义,很可能列是使用默认字符语义定义的 - 这是字节(但取决于您的Oracle安装),因此它默认为VARCHAR2(255 Byte)

如果您将列重新定义为VARCHAR2(255 Char),那么一切都应该没问题。

类似的东西:

CREATE TABLE FSR_SYSTEM_LOG
(
   ...
   MESSAGE  VARCHAR2(255 Char),
   ...
);

对我来说,在这样一个(长度)有限列中存储XML似乎很奇怪。您能否确保您的XML 从不超过255个字符?为什么不将邮件存储为CLOB

答案 1 :(得分:0)

乍一看,我怀疑编码问题......

Java使用unicode:unicode中的字符可能会花费一个很多字节... 一个java字符串的长度可能是1但是当在存储上编组时,它可能需要2个字节,4个字节......

要检查字节长度,也许你应该尝试:

if(message.getBytes("US-ASCII").length()>255){ 

Oracle DB的编码是什么?

另一个可能的问题是,写入数据库的类会将一个CR / LF(0D0A)添加到msg参数或其他内容......

答案 2 :(得分:0)

您可以将字段类型更改为CLOB,BLOB或XMLType。查找Oracle数据类型,VARCHAR2似乎也适用于字节。

您可以理解,您可能不想更改字段类型,在这种情况下,请替换

if(message.length()>255){
  message = message.substring(0,255);
  notifier().debug("Message string greater than 255 characters : " + message);
}

pos = 255
while (message.getBytes().size() > 255) {
  message = message.substring(0,pos--);
}