我正在使用JDBC与sql server 2008.我在表中有一个类型为“decimal(18,2)”的列。我想使用“CallableStatement”向此列插入一个空值。我该怎么做?
我试过了callstmt.setNull(14, java.sql.Types.DECIMAL);
。但这不起作用。
HTTP状态404 - /NSBMHCGcom.microsoft.sqlserver.jdbc.SQLServerException:%20Error%20converting%20data%20type%20nvarchar%20to%20numeric./eHRMS_AR_M_display_SetupOTConditions
输入状态报告
消息/NSBMHCGcom.microsoft.sqlserver.jdbc.SQLServerException:%20Error%20converting%20data%20type%20nvarchar%20to%20numeric./eHRMS_AR_M_display_SetupOTConditions
说明请求的资源(/NSBMHCGcom.microsoft.sqlserver.jdbc.SQLServerException:%20Error%20converting%20data%20type%20nvarchar%20to%20numeric./eHRMS_AR_M_display_SetupOTConditions)不可用。
这是代码的一部分。
strSQL = "INSERT INTO " + m_schema_name + ".[AR_M_OTConditions] ([ConditionDescription],[StartHour],[EndHour]"
+ " ,[Day],[IsActive],"
+ "[EntDate],[EntUser],[ModDate],[ModUser],[Rate],[MinOT],[MaxOT],[EmpCategory],[EmpType],[Condition],[MinHour],[MaxHour],[Amount]) VALUES (?,?,?,?,?,getDate(),?,getDate(),?,?,?,?,?,?,?,?,?,?)";
callstmt = conn.prepareCall(strSQL);
callstmt.setString(1, m_con_methods.met_formdata(reqstr, "TXT_LEVELNAME"));
callstmt.setString(2, m_con_methods.met_formdata(reqstr, "TXT_FROM"));
callstmt.setString(3, m_con_methods.met_formdata(reqstr, "TXT_TO"));
callstmt.setString(4, m_con_methods.met_formdata(reqstr, "TXT_FINYEAR"));
callstmt.setBoolean(5, true);
callstmt.setString(6, m_username);
callstmt.setString(7, m_username);
callstmt.setString(8, m_con_methods.met_formdata(reqstr, "TXT_RATE"));
callstmt.setString(9, m_con_methods.met_formdata(reqstr, "TXT_MIN") );
callstmt.setString(10, m_con_methods.met_formdata(reqstr, "TXT_MAX"));
callstmt.setString(11, m_con_methods.met_formdata(reqstr, "TXT_CHARGABLE_STATUS"));
callstmt.setString(12, m_con_methods.met_formdata(reqstr, "TXT_TYPE"));
callstmt.setString(13, m_con_methods.met_formdata(reqstr, "TXT_CONDITIONS"));
callstmt.setNull(14, java.sql.Types.DECIMAL);
callstmt.setString(15, m_con_methods.met_formdata(reqstr, "TXT_MAX_HOUR"));
callstmt.setString(16, m_con_methods.met_formdata(reqstr, "TXT_CONDITIONS_AMOUNT"));
=============================================== ================================================== ===
com.microsoft.sqlserver.jdbc.SQLServerException: Error converting data type nvarchar to numeric.
log4j:ERROR Could not find value for key log4j.appender.warn
log4j:ERROR Could not instantiate appender named "warn".
log4j:ERROR setFile(null,true) call failed.
java.io.FileNotFoundException: C:\Program Files\Apache Software Foundation\Apache Tomcat 6.0.18\logs\NSBM.log (The system cannot find the path specified)
at java.io.FileOutputStream.openAppend(Native Method)
at java.io.FileOutputStream.<init>(FileOutputStream.java:192)
at java.io.FileOutputStream.<init>(FileOutputStream.java:116)
at org.apache.log4j.FileAppender.setFile(FileAppender.java:290)
at org.apache.log4j.FileAppender.activateOptions(FileAppender.java:164)
at org.apache.log4j.config.PropertySetter.activate(PropertySetter.java:257)
at org.apache.log4j.config.PropertySetter.setProperties(PropertySetter.java:133)
at org.apache.log4j.config.PropertySetter.setProperties(PropertySetter.java:97)
at org.apache.log4j.PropertyConfigurator.parseAppender(PropertyConfigurator.java:689)
at org.apache.log4j.PropertyConfigurator.parseCategory(PropertyConfigurator.java:647)
at org.apache.log4j.PropertyConfigurator.configureRootCategory(PropertyConfigurator.java:544)
at org.apache.log4j.PropertyConfigurator.doConfigure(PropertyConfigurator.java:440)
at org.apache.log4j.PropertyConfigurator.doConfigure(PropertyConfigurator.java:476)
at org.apache.log4j.helpers.OptionConverter.selectAndConfigure(OptionConverter.java:471)
at org.apache.log4j.LogManager.<clinit>(LogManager.java:125)
at org.apache.log4j.Logger.getLogger(Logger.java:105)
at pwc.ehrms.common.CommonConnections.LogSystemErrors(CommonConnections.java:633)
at pwc.ehrms.master.eHRMS_AR_M_save_SetupOTConditions.service(eHRMS_AR_M_save_SetupOTConditions.java:165)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.netbeans.modules.web.monitor.server.MonitorFilter.doFilter(MonitorFilter.java:393)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:225)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:169)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:168)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:98)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:927)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:999)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:565)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:309)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
at java.lang.Thread.run(Thread.java:662)
=============================================== ================================================== ===
答案 0 :(得分:0)
假设您有一个包含输入类型对象和输出类型对象的包
CustomInputType customInputType = transform(customView);
final String query = "{?=call SCHEMA_DBA.PRJ_PKG_CUSTOM.FUNC_CUSTOM_X(?)}";
fdb.setUpCallable(query);
final Map<String, Class<?>> typeMap = fdb.getConnection().getTypeMap();
typeMap.put("SCHEMA_DBA.TY_CUSTOM_INPUT", Class.forName("com.myproject.view.CustomInputType"));
typeMap.put("SCHEMA_DBA.FI_TY_CUSTOM_OUTPUT", Class.forName("com.myproject.view.CustomOutputType"));
typeMap.put("TY_CUSTOM_INPUT", Class.forName("com.myproject.view.CustomInputType"));
typeMap.put("FI_TY_CUSTOM_OUTPUT", Class.forName("com.myproject.view.CustomOutputType"));
fdb.getCallableStatement().registerOutParameter(1, Types.STRUCT, "SCHEMA_DBA.FI_TY_CUSTOM_OUTPUT");
fdb.getCallableStatement().setObject(2, customInputType);
fdb.executeCallable();
CustomOutputType customOutputType = (CustomOutputType) callableStatement.getObject(1);
CustomOutput customOutput = valorizzaCaricaLineeDiFido(customOutputType);
在 CustomInputType 中你必须有
import java.sql.Date;
import java.sql.SQLData;
import java.sql.SQLException;
import java.sql.SQLInput;
import java.sql.SQLOutput;
public class CustomInputType implements SQLData {
String sql_type = "SCHEMA_DBA.TY_CUSTOM_INPUT";
String inputStringX;
Long inputLongY;
Date inputDataZ;
Double inputDoubleW;
public String getInputStringX() {
return inputStringX;
}
public void setInputStringX(String inputStringX) {
this.inputStringX = inputStringX;
}
public Long getInputLongY() {
return inputLongY;
}
public void setInputLongY(Long inputLongY) {
this.inputLongY = inputLongY;
}
public Date getInputDataZ() {
return inputDataZ;
}
public void setInputDataZ(Date inputDataZ) {
this.inputDataZ = inputDataZ;
}
public Double getInputDoubleW() {
return inputDoubleW;
}
public void setInputDoubleW(Double inputDoubleW) {
this.inputDoubleW = inputDoubleW;
}
// -- sqlType -- v
@Override
public String getSQLTypeName() throws SQLException {
return sql_type;
}
public String getSqlType() {
return sql_type;
}
// -- sqlType -- ^
// -- read/write Data utility-- v
public Long readDataLong(SQLInput stream) throws SQLException {
Long dataLong = stream.readLong();
if (stream.wasNull()) {
dataLong = null;
}
return dataLong;
}
public Double readDataDouble(SQLInput stream) throws SQLException {
Double dataDouble = stream.readDouble();
if (stream.wasNull()) {
dataDouble = null;
}
return dataDouble;
}
public void writeDataLong(SQLOutput stream, Long dataLong) throws SQLException {
if (dataLong != null) {
stream.writeLong(dataLong);
} else {
stream.writeObject(null);
}
}
public void writeDataDouble(SQLOutput stream, Double dataDouble) throws SQLException {
if (dataDouble != null) {
stream.writeDouble(dataDouble);
} else {
stream.writeObject(null);
}
}
// -- read/write Data utility-- ^
@Override
public void readSQL(SQLInput stream, String typeName) throws SQLException {
this.sql_type = typeName;
this.inputStringX = stream.readString();
this.inputLongY = readDataLong(stream);
this.inputDataZ = stream.readDate();
this.inputDoubleW = readDataDouble(stream);
}
@Override
public void writeSQL(SQLOutput stream) throws SQLException {
stream.writeString(this.inputStringX);
writeDataLong(stream, this.inputLongY);
stream.writeDate(this.inputDataZ);
writeDataDouble(stream, this.inputDoubleW);
}
在我们的 CustomOutputType 中
import java.sql.Date;
import java.sql.SQLData;
import java.sql.SQLException;
import java.sql.SQLInput;
import java.sql.SQLOutput;
public class CustomOutputType implements SQLData {
String sql_type = "SCHEMA_DBA.TY_CUSTOM_OUTPUT";
String inputStringA;
Long inputLongB;
Date inputDataC;
Double inputDoubleD;
public String getInputStringA() {
return inputStringA;
}
public void setInputStringA(String inputStringA) {
this.inputStringA = inputStringA;
}
public Long getInputLongB() {
return inputLongB;
}
public void setInputLongB(Long inputLongB) {
this.inputLongB = inputLongB;
}
public Date getInputDataC() {
return inputDataC;
}
public void setInputDataC(Date inputDataC) {
this.inputDataC = inputDataC;
}
public Double getInputDoubleD() {
return inputDoubleD;
}
public void setInputDoubleD(Double inputDoubleD) {
this.inputDoubleD = inputDoubleD;
}
// -- sqlType -- v
@Override
public String getSQLTypeName() throws SQLException {
return sql_type;
}
public String getSqlType() {
return sql_type;
}
// -- sqlType -- ^
// -- read/write Data utility-- v
public Long readDataLong(SQLInput stream) throws SQLException {
Long dataLong = stream.readLong();
if (stream.wasNull()) {
dataLong = null;
}
return dataLong;
}
public Double readDataDouble(SQLInput stream) throws SQLException {
Double dataDouble = stream.readDouble();
if (stream.wasNull()) {
dataDouble = null;
}
return dataDouble;
}
public void writeDataLong(SQLOutput stream, Long dataLong) throws SQLException {
if (dataLong != null) {
stream.writeLong(dataLong);
} else {
stream.writeObject(null);
}
}
public void writeDataDouble(SQLOutput stream, Double dataDouble) throws SQLException {
if (dataDouble != null) {
stream.writeDouble(dataDouble);
} else {
stream.writeObject(null);
}
}
// -- read/write Data utility-- ^
@Override
public void readSQL(SQLInput stream, String typeName) throws SQLException {
this.sql_type = typeName;
this.inputStringA = stream.readString();
this.inputLongB = readDataLong(stream);
this.inputDataC = stream.readDate();
this.inputDoubleD = readDataDouble(stream);
}
@Override
public void writeSQL(SQLOutput stream) throws SQLException {
stream.writeString(this.inputStringA);
writeDataLong(stream, this.inputLongB);
stream.writeDate(this.inputDataC);
writeDataDouble(stream, this.inputDoubleD);
}
注意事项:
输出对象使用声明
typeMap.put("SCHEMA_DBA.FI_TY_CUSTOM_OUTPUT", Class.forName("com.myproject.view.CustomOutputType"));
了解使用的数据对象是什么 2)输入对象使用声明 公共类 CustomInputType 实现 SQLData {
String sql_type = "SCHEMA_DBA.TY_CUSTOM_INPUT";
了解使用的数据对象是什么 3) 要为 Stream SQLInput 获取 NULL,您可以这样做
Long dataLong = stream.readLong();
if (stream.wasNull()) {
dataLong = null;
}
所以 readLong 返回 0 如果数据库中为 NULL 但在使用 wasNull 之后你可以强制 java 中的值返回 null 如果数据库中实际上是 NULL
要为 Stream SQLOutput 设置 NULL,您可以这样做
if (dataLong != null) { stream.writeLong(dataLong); } 别的 { stream.writeObject(null); }
所以如果值不为空,那么你可以使用带有long的writeLong,但是如果java中的值为空,你必须使用带有空参数的writeObject在数据库中设置NULL
干杯