当我尝试使用Java,Spring和Oracle的oci驱动程序执行SQL查询来连接Rdb数据库时,我目前正在获得以下堆栈跟踪。列ORGANIZATION_NAME
列在数据库中定义为CHAR(26)
,数据库中ORGANIZATION_NAME
的值为商业地板解决方案,值为I' m LIKE
子句是%Commercial Flooring Solutitions%
。我已经确认第一个参数的最大值是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
答案 0 :(得分:0)
对于NCHAR
或NVARCHAR2
类型的列,但CHAR
或VARCHAR2
请参阅Why am I getting ORA-01401: inserted value too large for column - when I'm not inserting?,其中用户面临与NVARCHAR2
查看您的查询,您似乎是通过数据库链接查询数据(direct_update_header @ d)
您可以尝试在数据库中使用CHAR
语义。强烈建议通过数据库链接共享数据。请参阅this page
答案 1 :(得分:0)
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);
}
}
答案 2 :(得分:0)
在包含
的视图上运行SELECT时,我已经看到此错误cast(foo as VARCHAR2(20))
其中foo
的基础类型实际上是NVARCHAR2(255)
。通过更改为
cast(foo as VARCHAR2(255 char))
但是在最小示例中不会发生错误-该值将被静默截断。我现在还没有时间进一步缩小范围,但这可能会帮助其他访客解决这个问题。