我试图创建一个可以接受客户端查询的服务器,找到匹配的记录,并返回相关信息。这里有很多代码,但最相关的部分是方法getProduct(String code)
。我提供了尽可能多的连接信息,但我的测试查询适用于此连接。我的测试查询是:
ResultSet a = statement.executeQuery("SELECT TOP 10 Code, [name in english], NetSalesPrice, PriceList1 FROM [REDACTED]");
class PCServer {
Connection dataConn;
public static void main(String[] args){
new PCServer();
}
public PCServer(){
try{
Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
dataConn = DriverManager.getConnection([REDACTED]);
System.out.println("REPORT: Connected to Database");
ServerSocket ss = new ServerSocket([REDACTED]);
Socket cs = null;
while(true){
cs = ss.accept();
ThreadServer ts = new ThreadServer(cs, this);
ts.start();
}
}catch(SQLException sqle){
sqle.printStackTrace();
}catch(ClassNotFoundException cnfe) {
cnfe.printStackTrace();
}catch(IOException ioe){
ioe.printStackTrace();
}
}
public String getProduct(String code){
System.out.println("REPORT from PCS.getProduct(): code == "+ code);
String query = "SELECT Code, [name in english], NetSalesPrice, PriceList1 FROM [REDACTED] WHERE Code=";
query = query.concat(code);
System.out.println("REPORT from PCS.getProduct(): Query: "+ query);
String productDescription = code+":Not:Found";
try{
Statement s = dataConn.createStatement();
ResultSet rs = s.executeQuery(query);
if(rs.isBeforeFirst()) {
System.out.println("REPORT from PCS.getProduct(): rs.isBeforeFirst == true");
rs.next(); //This is throwing com.microsoft.sqlserver.jdbc.SQLServerException: Conversion Failed...
productDescription = rs.getString(1) + ":" + rs.getString(2) + ":$" + rs.getString(3);
}
}catch (SQLException sqle){
System.out.println("SQL Server Exception in getProduct(String code)");
sqle.printStackTrace();
}
return productDescription;
}
当创建或访问ResultSet时,似乎异常是数据类型错误或NumberFormatException的结果。但是,我尝试将代码转换为int,并且即使在注释掉行productDescription = rs.getString(1) + ":" + rs.getString(2) + ":$" + rs.getString(3);
时错误仍然存在。我相信rs.next()
会引发错误。此外,我们知道rs不是空的,因为我们检查了rs.isBeforeFirst()
,如果ResultSet为空,它将返回false。
以下是完整的消息
com.microsoft.sqlserver.jdbc.SQLServerException: Conversion failed when converting the nvarchar value 'NM21' to data type int.
at com.microsoft.sqlserver.jdbc.SQLServerException.makeFromDatabaseError(SQLServerException.java:216)
at com.microsoft.sqlserver.jdbc.SQLServerResultSet$FetchBuffer.nextRow(SQLServerResultSet.java:4853)
at com.microsoft.sqlserver.jdbc.SQLServerResultSet.fetchBufferNext(SQLServerResultSet.java:1781)
at com.microsoft.sqlserver.jdbc.SQLServerResultSet.next(SQLServerResultSet.java:1034)
at PCServer.getProduct(PCServer.java:83)
at PCServer$ThreadServer.run(PCServer.java:128)
我知道这个问题与其他问题相似。关于此错误还有很多其他帖子,但ResultSet.next()
答案 0 :(得分:0)
我已经弄明白了,结果证明这是一个非常愚蠢的错误。但https://xkcd.com/979/告诉我不要放弃我的问题。
我的查询需要围绕代码的单引号。所以它应该是:
statement.executeQuery("SELECT Code, [name in english], NetSalesPrice, PriceList1 FROM ERPLY_ITEMS WHERE Code='"+code+"'")
而不是:
statement.executeQuery("SELECT Code, [name in english], NetSalesPrice, PriceList1 FROM ERPLY_ITEMS WHERE Code="+code)
我因为尴尬的时间而忽略了这一点。 This answer关于使用WHERE子句进行程序生成的查询的问题,连接是一种非常容易受到攻击的查询生成方法。相反,Isaac建议使用Prepared Statements以编程方式生成查询。
我希望这最终有助于某人。