【发布时间】:2015-07-15 11:02:27
【问题描述】:
我遇到了一个奇怪的情况,我无法解释原因。我需要你的帮助才能理解。 这是我的故事。我创建了两个相同的表,一个用于个人的最新信息,另一个用于历史信息。第一个表中每个人只有一条记录,历史表将保留所有请求,例如:
----------------
|Name|Phone|Dob| (all columns are varchar2(255) type)
----------------
--------------------------
|Name|Phone|Dob|InsertTime (inserttime is date format defaults to now())
--------------------------
我创建了一个 java 对象,比如带有私有变量的 Person,用于 Name、Phone 和 Dob 的 getter 和 setter。
public class Person {
private String name;
private String phone;
private String dob;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public String getDob() {
return dob;
}
public void setDob(String dob) {
this.dob = dob;
}
public String getInsertSQL(){
return "INSERT INTO TABLE (NAME,PHONE,DOB) VALUES (?,?,?)";
}
}
数据库插入端的java代码,我有这样的东西(数据库是Oracle 10g)
public int insertProfile(Person p){
int ret = 0;
String sql = p.getInsertSQL();
Connection conn = getConnection();
PreparedStatement ps = null;
try {
ps = conn.prepareStatement(sql);
ps.setString(1, p.getName());
ps.setString(2, p.getPhone());
ps.setString(3, p.getDob());
ret = ps.executeUpdate();
} catch (Exception e) {
log error;
} finally {
try {
closeConnection(ps, conn);
} catch (SQLException e) {
log error;
}
}
return ret;
}
所以我使用相同的 java 对象插入两个表,因为它们非常相似,除了 insertTime 列,它是 NOW() 的默认值。正如预期的那样,这里一切正常。
注意:我的确切表和 java 对象非常庞大,因此我尝试简化,但场景仍然相同。
现在,出于某种原因,我决定仅将第一个表而不是第二个表的 dob 列更改为 DATE 类型。所以我希望我的代码在这里中断,因为在 java 端,输入仍然是 DOB 的字符串格式,我还没有在我的查询中真正进行任何日期转换。话虽如此,我对两个表插入使用相同的 Java 对象,因此其中一个表肯定会由于相同的原因而失败。
但我的代码工作正常。两个表都正确更新。第一个表是日期类型,第二个表是 varchar2(255) 类型。
我试图通过在 DOB 输入中故意添加一个字符来破坏代码,但它失败了。但是当我以 DDMMYYYY 格式输入正确的日期时,它以某种方式接受并在两个表上都可以正常工作。 我尝试输入“99990101”之类的内容,但我收到错误消息说第一个表插入的“月份无效”,但是第二个表已正确更新。所以肯定有一些日期转换正在进行。如果我在某处放置了一些日期转换代码,那么我希望我在第二个表上的插入会失败。但事实并非如此。我什至尝试在我的数据库编辑器中手动插入语句,
insert into table (NAME,PHONE ,DOB) values ('Vimal','90837745','01019999');
它失败了,表的“文字与格式字符串不匹配”,第二个没有问题。只是为了消除我是否真的将列转换为 DATE 格式的疑问。
我的意图实际上是将对象 Person.getInsertStmt 更改为
public String getInsertSQL(){
return "INSERT INTO TABLE (NAME,PHONE,DOB) VALUES (?,?,to_date(?,'DDMMYYYY'))";
}
但我无法解释为什么代码在没有任何更改的情况下仍然有效! 有人可以帮助解释到底发生了什么吗?是否与某些数据库默认日期格式有关?
提前谢谢各位。
【问题讨论】:
-
您的问题已标记为 Oracle。但是您反复引用了
now函数,该函数在 Oracle 中不存在,但在 MySQL 等其他数据库中却存在。不同的数据库处理隐式转换的方式不同,因此这是一个重要因素。也许您使用的是 Oracle,但您编写了自己的now函数而不是出于某种原因调用sysdate?