2015-11-17 222 views
-1

您好,我的SQL查詢使用Prepared Statement存在問題。我得到的錯誤是:對SQL查詢使用PreparedStatement(DB2)SQLCODE = -206 SQLSTATE = 42703

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

因此很明顯,有或者是用我的變量name,其中包括由用戶或內容不被保存在進入JTsextField的所述可變的內容問題。以下是我的SQL查詢的以下重要類。我正在使用MVC模型和DAO模式。

我的控制器類(僅示出了重要的部分):

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類:

public interface BtrDao { 

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

我DaoImpl類:

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的類:

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類:

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; 
    } 

} 

回答

0

您需要在查詢中指出要使用的參數,並且需要明確設置值。在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(但這並非總是可行)。

+0

謝謝。現在它正在工作。現在我只剩下一些改進。 – APL

+0

IBM JDBC驅動程序確實支持[命名參數標記](http://www-01.ibm.com/support/knowledgecenter/SSEPGG_10.5.0/com.ibm.db2.luw.apdv.java.doc/src/tpc /imjcc_t0054762.html?lang=en),就像@jens提到的那樣。 – mustaccio

+0

@mustaccio我更新了我的答案,謝謝。 –

2

佔位符必須先從:所以你的查詢必須是這樣的:

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

而且你必須準備語句後設置的參數。

+0

如何設置該參數? – APL

+0

JDBC僅支持位置佔位符('?')。 –

+0

@APL使用'setString'函數:http://www.javaworld.com/article/2077706/core-java/named-parameters-for-preparedstatement.html與NamedParameterStatement – Jens

相關問題