我正在从Java调用plsql package procedure
。此过程的类型参数带有timestamp
。当我将timestamp参数直接设置为过程时,我可以指定Calendar object
来声明使用e的时区。克。
Calendar calendar = new GregorianCalendar(TimeZone.getTimeZone("UTC"));
statement.setTimestamp(1, new Timestamp(calendar.getTimeInMillis()), calendar);
使用oracle.sql.ARRAY
或oracle.sql.STRUCT
时,有没有办法申报时区?
使用的类型声明如下:
CREATE OR REPLACE TYPE "TY_EVENT_OBJECT"
AS
OBJECT
(
timestamp_event date,
state number(15),
parameter_name varchar2(248),
value number(15)
);
CREATE OR REPLACE TYPE "TY_EVENTS"
AS
TABLE OF TY_EVENT_OBJECT;
TY_EVENTS类型是我必须使用的plsql过程的一个参数。
答案 0 :(得分:0)
当您使用用户定义的oracle类型时,无法简单地传递将用于时区转换的日历。当使用oracle.sql.ARRAY和oracle.sql.STRUCT时,ojdbc使用本地日历将java.sql.Date转换为oracle.sql.DATE,因此在您的情况下,存储在数据库中的实际日期是没有时区的本地时间。
因此,如果您希望将日期存储到UTC中的数据库,则必须使用UTC日历手动将java.sql.Date转换为oracle.sql.DATE。
您可以这样做:
实现SQLData接口并覆盖方法。
注意:强>
-getSQLTypeName必须返回数据库中定义的实际类型名称,否则不起作用。
- 我们在下面使用java.sql.Date,这很重要。所以,如果你想在TyEventObject之外的java.util.Date你可以创建一个进行转换的setter / getter
public class TyEventObject implements SQLData {
private String sqlTypeName = "TY_EVENT_OBJECT";
private java.sql.Date timestampEvent;
private long state;
private String parameterName;
private long value;
@Override
public String getSQLTypeName() throws SQLException {
return sqlTypeName;
}
@Override
public void readSQL(SQLInput stream, String typeName) throws SQLException {
sqlTypeName = typeName;
// Reading date in UTC time
OracleJdbc2SQLInput oracleStream = (OracleJdbc2SQLInput) stream;
DATE oracleDate = (DATE)oracleStream.readOracleObject();
if( oracleDate != null) {
timestampEvent = oracleDate.dateValue( Calendar.getInstance(TimeZone.getTimeZone("UTC")));
} else {
timestampEvent = null;
}
state = stream.readLong();
parameterName = stream.readString();
value = stream.readLong();
}
@Override
public void writeSQL(SQLOutput stream) throws SQLException {
// Writing timestamp in UTC time
OracleSQLOutput oracleStream = (OracleSQLOutput) stream;
if( timestampEvent != null) {
DATE oracleDate = new DATE( timestampEvent, Calendar.getInstance(TimeZone.getTimeZone("UTC")));
oracleStream.writeOracleObject( oracleDate);
} else {
stream.writeDate( null);
}
stream.writeLong( state);
stream.writeString( parameterName);
stream.writeLong( value);
}
// add public getters and setters
}
现在你创建一个这些TyEventObject对象的数组,传递给像这样的plsql过程(注意Array是java.sql.Array):
// I assume that your event objects that you want to save are in the list eventObjects
TyEventObject[] entries = new TyEventObject[ eventObjects.size()];
for( int i=0; i < eventObjects.size(); i++) {
entries[i] = new TyEventObject();
// You set the properties here
// entries[i].setTimestampEvent( eventObjects.get( i).getTimestampEvent());
}
Array dataObjectArray = connection.createArrayOf( "TY_EVENTS", entries);
最后你像往常一样叫你plsql程序:
CallableStatement cs = connection.prepareCall("{call ProcedureName( ?)}");
cs.setObject(1, dataObjectArray, Types.ARRAY);
cs.execute();
cs.close();