将 PreparedStatement 用于 SQL 查询 (DB2) SQLCODE=-206 SQLSTATE=42703
Using a PreparedStatement for a SQL query (DB2) SQLCODE=-206 SQLSTATE=42703
您好,我的 SQL 查询使用准备好的语句有问题。我得到的错误如下:
com.ibm.db2.jcc.am.ro: DB2 SQL Error: SQLCODE=-206, SQLSTATE=42703, SQLERRMC=NAME, DRIVER=3.58.82
很明显,使用我的变量 name
存在问题,其中包含用户输入的 JTsextField 的内容,或者内容未保存在所述变量中。以下是我的 SQL 查询的以下重要 classes。我正在使用 MVC 模型和 DAO 模式。
我的控制器class(只显示重要部分):
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;
}
}
我的 BtrDao class:
public interface BtrDao {
Collection<BTRBean> getBTR() throws SQLException, IOException;
}
我的 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;
}
}
我的 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();
}
}
我的 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;
}
}
占位符必须以 :
开头,因此您的查询必须如下所示:
String result = "SELECT BBSTBBNR, BBSTNABEG, BBSTPLZ FROM BP.TBBBST WHERE BBSTNABEG = :name AND BBSTPLZ = :plz";
并且你必须在准备语句后设置参数。
您需要在查询中指明要使用哪些参数,并且需要明确设置值。 JDBC API 本身只支持位置参数,所以你需要把你的代码改成:
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);
正如评论中的 mustaccio 所指出的,IBM DB2 JDBC 驱动程序支持命名参数,请参阅 Using named parameter markers with PreparedStatement objects。您的示例将如下所示:
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);
转换到 DB2PreparedStatement
可能并不总是可行的(例如,当使用第三方连接池时)。您可能需要改用 unwrap
(但这并不总是可行)。
您好,我的 SQL 查询使用准备好的语句有问题。我得到的错误如下:
com.ibm.db2.jcc.am.ro: DB2 SQL Error: SQLCODE=-206, SQLSTATE=42703, SQLERRMC=NAME, DRIVER=3.58.82
很明显,使用我的变量 name
存在问题,其中包含用户输入的 JTsextField 的内容,或者内容未保存在所述变量中。以下是我的 SQL 查询的以下重要 classes。我正在使用 MVC 模型和 DAO 模式。
我的控制器class(只显示重要部分):
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;
}
}
我的 BtrDao class:
public interface BtrDao {
Collection<BTRBean> getBTR() throws SQLException, IOException;
}
我的 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;
}
}
我的 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();
}
}
我的 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;
}
}
占位符必须以 :
开头,因此您的查询必须如下所示:
String result = "SELECT BBSTBBNR, BBSTNABEG, BBSTPLZ FROM BP.TBBBST WHERE BBSTNABEG = :name AND BBSTPLZ = :plz";
并且你必须在准备语句后设置参数。
您需要在查询中指明要使用哪些参数,并且需要明确设置值。 JDBC API 本身只支持位置参数,所以你需要把你的代码改成:
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);
正如评论中的 mustaccio 所指出的,IBM DB2 JDBC 驱动程序支持命名参数,请参阅 Using named parameter markers with PreparedStatement objects。您的示例将如下所示:
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);
转换到 DB2PreparedStatement
可能并不总是可行的(例如,当使用第三方连接池时)。您可能需要改用 unwrap
(但这并不总是可行)。