简体   繁体   中英

Using a PreparedStatement for a SQL query (DB2) SQLCODE=-206 SQLSTATE=42703

Hello I have a problem with my SQL query using a Prepared Statement. The error I get is the following:

com.ibm.db2.jcc.am.ro: DB2 SQL Error: SQLCODE=-206, SQLSTATE=42703, SQLERRMC=NAME, DRIVER=3.58.82

So apparently there's either a problem with using my variable name which includes the content of a JTsextField entered by the user or the content isn't saved in said variable. Here are the following important classes for my SQL query. I'm using the MVC model and DAO pattern.

My Controller class (only showing the important parts):

public class Controller implements Observer, ActionListener{

Connection dbConnection = null;
public static PreparedStatement preparedStatement = null;

@Override
public void actionPerformed(ActionEvent e) {
    switch (e.getActionCommand()) {
    case View.SEARCH:
        try {

            String name = View.searchname.getText();
            String plz = View.searchplz.getText();
            String result = "SELECT BBSTBBNR, BBSTNABEG, BBSTPLZ FROM BP.TBBBST WHERE BBSTNABEG = name AND BBSTPLZ = plz";

            dbConnection = ConnectionManager.getConnection();
            preparedStatement = dbConnection.prepareStatement(result);


            model.search();
        } catch (SQLException e1) {
            System.out.println("An SQL-Error occured: ");
            e1.printStackTrace();
        } catch (IOException e1) {
            System.out.println("An error occured: ");
            e1.printStackTrace();
        }
        break;

    default:
        System.out.println("Search error: " + e.getActionCommand());
        break;
    }

}

My BtrDao class:

public interface BtrDao {

Collection<BTRBean> getBTR() throws SQLException, IOException;
}

My DaoImpl class:

public class BtrDaoImpl extends AbstractDao implements BtrDao {

public Collection<BTRBean> getBTR() throws SQLException,
        IOException {
    final Collection<BTRBean> result = new ArrayList<BTRBean>();

    ResultSet resultset = null;
    try {
        //This is where the Nullpointerexception happens!
        resultset = Controller.preparedStatement.executeQuery();

        // while loop for finding all results
        while (resultset.next()) {
            BTRBean btr = new BTRBean();
            int btrid = resultset.getInt(1);
            String btrplz = resultset.getString(2);
            String btrname = resultset.getString(3);
            result.add(btr);
            System.out.println(btrid + " " + btrplz + " " + btrname);
        }

    } catch (SQLException e) {
        e.printStackTrace();
        System.out.println("There was an SQL processing error: (getBTR)");
        e.printStackTrace();
    } catch (NullPointerException npe) {
        System.out.println("NullPointerException");
        npe.printStackTrace();
    } finally {

        closeConnection(resultset);

    }

    return result;
}

}

My AbstractDao class:

public class AbstractDao {

    public static Connection getConnection() throws SQLException {
        return ConnectionManager.getInstance().getConnection();
    }

    public ResultSet getResultset(final String statement) throws SQLException {
        final Statement stmnt = getConnection().createStatement();
        return stmnt.executeQuery(statement);
    }

    public void closeConnection(final ResultSet resultset) throws SQLException {
        if(resultset != null)
        resultset.close();
        getConnection().close();
    }
}

My ConnectionManager Class:

public class ConnectionManager {

    public Connection getConnection() throws SQLException {

        try {
        Properties props = new Properties();
        FileInputStream in = new FileInputStream(".//required.\\dbprop.\\DBConn.properties");
        props.load(in);
        in.close();
        String drivers = props.getProperty("jdbc.drivers");
        if (drivers !=null) 
            System.setProperty("jdbc.drivers", drivers);

        String url = props.getProperty("jdbc.url");
        if (url !=null)
            System.setProperty("jdbc.url", url);

        String username = props.getProperty("jdbc.username");
        if (username !=null)
            System.setProperty("jdbc.username", username);
        String password = props.getProperty("jdbc.password");
        if (password !=null)
            System.setProperty("jdbc.password", password);

        return DriverManager.getConnection(url, username, password);
        } catch (IOException e) {
            throw new SQLException(e.getMessage(), e.getCause());
        }

    }


    //Close connection
    public void closeConnection(Connection con) throws SQLException {
        if (con != null)
            con.close();
    }

    // Making sure that there's only one instance of the class
    private static ConnectionManager singleton_Instance;

    // default constructor
    private ConnectionManager() {
    }

    // returns the single instance of the class
    public static ConnectionManager getInstance() {
        if (singleton_Instance == null) {
            singleton_Instance = new ConnectionManager();
        }
        return singleton_Instance;
    }

}

placeholder has to start with : so your query must look like:

String result = "SELECT BBSTBBNR, BBSTNABEG, BBSTPLZ FROM BP.TBBBST WHERE BBSTNABEG = :name AND BBSTPLZ = :plz";

And you have to set the parameter after preparing the statement.

You need to indicate in the query which parameters you want to use and you need to explicitly set the values. The JDBC API itself only supports positional parameters, so you need to change your code to:

String name = View.searchname.getText();
String plz = View.searchplz.getText();

// Use ? for parameters
String result = "SELECT BBSTBBNR, BBSTNABEG, BBSTPLZ FROM BP.TBBBST " + 
        " WHERE BBSTNABEG = ? AND BBSTPLZ = ?";

preparedStatement = dbConnection.prepareStatement(result);

// Set values for parameters
preparedStatement.setString(1, name);
preparedStatement.setString(2, plz);

As indicated by mustaccio in the comments, the IBM DB2 JDBC driver supports named parameters, see Using named parameter markers with PreparedStatement objects . Your example would then look like:

String name = View.searchname.getText();
String plz = View.searchplz.getText();

// Use :<name> for parameters
String result = "SELECT BBSTBBNR, BBSTNABEG, BBSTPLZ FROM BP.TBBBST " + 
        " WHERE BBSTNABEG = :name AND BBSTPLZ = :plz";

DB2PreparedStatement preparedStatement = (DB2PreparedStatement) dbConnection.prepareStatement(result);

// Set values for parameters
preparedStatement.setJccStringAtName("name", name);
preparedStatement.setJccStringAtName("plz", plz);

Casting to DB2PreparedStatement might not always be possible (eg when using third party connection pools). You might need to use unwrap instead (but that is also not always possible).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM