【问题标题】:ORA-01401: inserted value too large for column when doing SELECT query containing LIKEORA-01401: 在执行包含 LIKE 的 SELECT 查询时,插入的值对于列来说太大
【发布时间】:2015-11-05 21:44:03
【问题描述】:

当我尝试使用 Java、Spring 和 Oracle 的 oci 驱动程序连接 Rdb 数据库执行 SQL 查询时,我目前正在获取以下堆栈跟踪。 ORGANIZATION_NAME 列在数据库中定义为CHAR(26),数据库中ORGANIZATION_NAME 的值是Commercial Flooring Soluti,而我用于LIKE 子句的值是@ 987654326@。我已经确认第一个参数的最大值是 26,它来自数据库。我的问题是有人知道为什么SELECT 声明会发生这种情况吗?我本来希望数据库/驱动程序截断并处理这个。它与CHAR(26) 的列类型有关吗?将日期列设置为 2000 是不寻常的(请参阅跟踪日志)。

13:03:25,073 SEVERE [au.com.blah.http.logging.HttpLoggingFilter] (http- org.springframework.dao.DataIntegrityViolationException: PreparedStatementCallback; SQL [SELECT
    header_record_uid,
    organization_name,
    organization_number
FROM
    direct_update_header@d
WHERE
    UPPER(organization_name) LIKE UPPER(?)
AND
    posting_date BETWEEN TO_TIMESTAMP(?) AND TO_TIMESTAMP(?)
ORDER BY
    posting_date DESC
]; ORA-01401: inserted value too large for column; nested exception is java.sql.SQLDataException: ORA-01401: inserted value too large for column
at org.springframework.jdbc.support.SQLExceptionSubclassTranslator.doTranslate(SQLExceptionSubclassTranslator.java:82) [spring-jdbc-4.1.4.RELEASE.jar:4.1.4.RELEASE]
at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:73) [spring-jdbc-4.1.4.RELEASE.jar:4.1.4.RELEASE]
at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:81) [spring-jdbc-4.1.4.RELEASE.jar:4.1.4.RELEASE]
at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:660) [spring-jdbc-4.1.4.RELEASE.jar:4.1.4.RELEASE]
at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:695) [spring-jdbc-4.1.4.RELEASE.jar:4.1.4.RELEASE]
at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:722) [spring-jdbc-4.1.4.RELEASE.jar:4.1.4.RELEASE]
at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:772) [spring-jdbc-4.1.4.RELEASE.jar:4.1.4.RELEASE]
at org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate.query(NamedParameterJdbcTemplate.java:192) [spring-jdbc-4.1.4.RELEASE.jar:4.1.4.RELEASE]

跟踪日志:

FROM
    direct_update_header@d
WHERE
    UPPER(organization_name) LIKE UPPER(:1 )
AND
    posting_date BETWEEN TO_TIMESTAMP(:2 ) AND TO_TIMESTAMP(:3 )
ORDER BY
    posting_date DESC
statement id: 036E70F0
2015-08-13 13:50:50.459::gta.gtachecksqlcode: Rdb returned SQLCODE: 0 for PREPARE
2015-08-13 13:50:50.459::gta.sequence_check: entry
2015-08-13 13:50:50.459::gta.sequence_check: exit status=0
2015-08-13 13:50:50.459::gta.gtapars: exit status=0
2015-08-13 13:50:50.459::*** GTAISDDL ***
2015-08-13 13:50:50.460::gtoosq.gtoosq: exit status=0
2015-08-13 13:50:50.460::gtoall.gtoopr: exit status = 0
2015-08-13 13:50:50.460::gtoall.gtopbnd: entry
2015-08-13 13:50:50.460::gtobr.gtobrp: entry
gtobr.gtobrp: BRPDEF:.....cursor : 1
gtobr.gtobrp:        ........pos : 1
gtobr.gtobrp:        .....oacdef : 7acb1818
gtobr.gtobrp:        .# oacdef's : 3
gtobr.gtobrp:        ........uac : 0
gtobr.gtobrp:        ...uac lnth : 0
2015-08-13 13:50:50.460::*** GTGBNDONE ***
2015-08-13 13:50:50.461::gta.gtadbnd: entry
statement id: 036E70F0
2015-08-13 13:50:50.461::gta.gtachecksqlcode: Rdb returned SQLCODE: 0 for DESCRIBE INPUT
gta.gtadbnd: SQLDA2 for (1): Describe Input
Cursor number 1, number of items 3
SQLVAR Item 0, Bindnam 1, Bindcol 1
type 449, octet_len 30, sqllen 26
data NULL
SQLVAR Item 1, Bindnam 2, Bindcol INSTR
type 449, octet_len 2004, sqllen 2000
data NULL
SQLVAR Item 2, Bindnam 3, Bindcol INSTR
type 449, octet_len 2004, sqllen 2000
data NULL

【问题讨论】:

标签: java spring oracle


【解决方案1】:

NCHARNVARCHAR2 类型的列似乎可能出现此问题,但 CHARVARCHAR2 类型的列则不然

请参考Why am I getting ORA-01401: inserted value too large for column - when I'm not inserting?,用户面临与NVARCHAR2类似的问题

查看您的查询,您似乎正在通过 DB 链接 (direct_update_header@d) 查询数据

您可以尝试在数据库中使用CHAR 语义。强烈建议在通过数据库链接共享数据时。参考this page

【讨论】:

  • 感谢您的洞察力。这最好地解释了为什么我会看到此错误。我没有更改数据库,而是想出了一个适合我的问题的快速解决方案的解决方法。
【解决方案2】:

更新:

我想出了一个解决方法,显示在下面的测试中。我没有将LIKE 子句的“%”作为MapSqlParameterSource 中参数绑定的一部分包含在内,而是将其移至SQL 本身。
public class JdbcNamedTemplate_Select_WithBindVariableWithoutLikeWildcard_ExecutesSuccessfully_IT extends AbstractIntegrationTest {

private String query;
private NamedParameterJdbcTemplate jdbcTemplate;
private MapSqlParameterSource params;
private List<Map<String, Object>> result;
private Exception exception;

@Override
public void given() {
    query = "SELECT * FROM direct_update_header@d WHERE UPPER(organization_name) LIKE '%' || UPPER(:organisationName) || '%' " +
            "AND posting_date BETWEEN TO_TIMESTAMP(:fromDate) AND TO_TIMESTAMP(:toDate)";
    jdbcTemplate = new NamedParameterJdbcTemplate(dataSource);

    params = new MapSqlParameterSource();
    params.addValue("organisationName", String.format("%26s", "X"));
    params.addValue("fromDate", new Timestamp(DateUtils.now().toDate().getTime()));
    params.addValue("toDate", new Timestamp(DateUtils.now().toDate().getTime()));

}

@Override
public void when() {
    try {
        result = jdbcTemplate.queryForList(query, params);
    } catch(Exception e) {
        exception = e;
    }
}

@Override
public void then() {
    assertNull(exception);
}
}

【讨论】:

    【解决方案3】:

    在包含

    cast(foo as VARCHAR2(20))
    

    foo 的基础类型实际上是NVARCHAR2(255)。它已通过更改为修复

    cast(foo as VARCHAR2(255 char))
    

    但是,在最小示例中不会发生错误 - 值会被静默截断。我现在没有时间进一步缩小范围,但它可能会帮助其他访问者解决这个问题。

    【讨论】:

      猜你喜欢
      • 2015-05-27
      • 2016-08-10
      • 2016-07-24
      • 2011-08-18
      • 1970-01-01
      • 2015-02-19
      • 1970-01-01
      • 2021-05-09
      相关资源
      最近更新 更多