ResultSet.next()导致SQLServerException:转换nvarchar值时转换失败' NM21'到数据类型int

时间:2017-01-10 15:09:07

标签: java mysql sql-server jdbc

我试图创建一个可以接受客户端查询的服务器,找到匹配的记录,并返回相关信息。这里有很多代码,但最相关的部分是方法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()

都没有抛出这些错误

1 个答案:

答案 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以编程方式生成查询。

我希望这最终有助于某人。