在ORACLE中,CHAR類型的字段值會自動補足空格。所以當(dāng)其作為條件時,就有可能查不出想要的數(shù)據(jù)。
如果不允許改DB設(shè)計的話,那就用RTRIM來解決吧。例:
DB:
CREATE TABLE TEST
(
TEST_ID VARCHAR2(64) NOT NULL,
TEST_CHAR CHAR(10),
CONSTRAINT TEST_ID PRIMARY KEY (TEST_ID)
);
INSERT INTO TEST VALUES('1','a');
測試代碼:
Session session = factory.getCurrentSession();
session.beginTransaction();
List list = session.createQuery("FROM Test WHERE RTRIM(TEST_CHAR) = 'a'").list();
session.close();
assertTrue(list.size() > 0);
輸出結(jié)果(ORACLE):
Hibernate:
select
test0_.TEST_ID as TEST1_0_,
test0_.TEST_CHAR as TEST4_0_
from
TEST test0_
where
rtrim(TEST_CHAR)='a'
14:09:53,171DEBUG StringType:172 - returning '1' as column: TEST1_0_
14:09:53,187DEBUG StringType:172 - returning 'a ' as column: TEST4_0_
而MySQL不會自動補足空格,同樣的代碼也是可以適用的:
輸出結(jié)果(MySQL):
Hibernate:
select
test0_.TEST_ID as TEST1_0_,
test0_.TEST_CHAR as TEST4_0_
from
TEST test0_
where
rtrim(TEST_CHAR)='a'
14:09:01,828DEBUG StringType:172 - returning '1' as column: TEST1_0_
14:09:01,828DEBUG StringType:172 - returning 'a' as column: TEST4_0_
------------------------------------------------------------
08/11/26更新
事實上用以下方法加不加RTRIM都能取出數(shù)據(jù):
List list = session.createQuery("FROM Test WHERE TEST_CHAR = 'a'").list();
我建了一個表:create table test(name char(7));內(nèi)有N條值為hello的記錄
第一種:不用占位符,
java.sql.PreparedStatement ps = connection().prepareStatement("select * from test where name='hello'");
java.sql.ResultSet rs = ps.executeQuery();
記錄集rs有數(shù)據(jù);
第二種:使用占位符,
java.sql.PreparedStatement ps = connection().prepareStatement("select * from test where name=?");
ps.setString(1,"hello");
java.sql.ResultSet rs = ps.executeQuery();
記錄集rs中無任何數(shù)據(jù)。
引用http://www.javaeye.com/post/152778
看來如果用PrepareStatement的話就有可能發(fā)生問題。另外,由于RTRIM可能帶來索引失效,使用RPAD(expr,n[,pad])也是一種不錯的選擇。