修復異常“無法使用executeQuery()發出資料操作語句”
一、簡介
在本教學中,我們將探討修復例外: C
annot issue data manipulation statements with executeQuery().
使用 JDBC 與資料庫互動時遇到此問題並不常見,但幸運的是,它很容易解決。
2. 理解異常
錯誤訊息本身告訴我們錯誤可能出在哪裡,但讓我們深入了解問題的本質。
2.1.這是什麼意思?
當我們的程式碼嘗試使用executeQuery()
方法執行INSERT、UPDATE 或DELETE 語句時,會出現錯誤C
annot issue data manipulation statements with executeQuery()
。
Statement
或PreparedStatement
物件中的方法executeQuery()
是專門為處理SELECT 查詢而設計的。如果我們檢查方法簽名,我們會注意到它傳回ResultSet
實例,其中包含從資料庫檢索的行。
使用 Connector/J 連線 MySQL 時會出現此異常,但其他資料庫強制執行相同的規則。在這種情況下,他們會拋出類似的錯誤並顯示不同的錯誤訊息。
值得注意的是,在較新版本的MySQL Connector/J中,此錯誤訊息已略有更新。現在讀作:
java.sql.SQLException: Statement.executeQuery() cannot issue statements that do not produce result sets.
2.2.觸發異常的常見場景
讓我們看一個程式碼範例,以更好地理解觸發異常的原因。如前所述,我們將使用 MySQL 資料庫。
第一步,我們為範例建立一個簡單的表格:
CREATE TABLE IF NOT EXISTS users (
id INT PRIMARY KEY AUTO_INCREMENT,
username VARCHAR(50),
email VARCHAR(50)
)
我們現在可以嘗試執行不是 SELECT 語句的查詢。讓我們在測試中使用一個簡單的 INSERT 語句並確認是否拋出例外:
@Test
void givenInsertSql_whenExecuteQuery_thenAssertSqlExceptionThrown() throws SQLException {
String insertSql = "INSERT INTO users (username, email) VALUES (?, ?)";
PreparedStatement insertStatement = connection.prepareStatement(insertSql);
insertStatement.setString(1, USERNAME);
insertStatement.setString(2, EMAIl);
SQLException exception = assertThrows(SQLException.class, insertStatement::executeQuery);
assertEquals("Statement.executeQuery() cannot issue statements that do not produce result sets.", exception.getMessage());
}
3. 解決問題
解決這個異常的方法很簡單:我們必須針對我們想要執行的 SQL 語句的類型使用正確的方法。
為了說明這一點,讓我們回顧一下先前討論的範例,其中我們嘗試使用executeQuery()
方法執行INSERT 語句。這次,我們將使用executeUpdate()
方法來修正我們的方法。之後,我們將查詢資料庫以確認資料已正確保存。
現在讓我們使用程式碼的更正版本來檢查測試:
@Test
void givenInsertSql_whenExecuteUpdate_thenAssertUserSaved() throws SQLException {
String insertSql = "INSERT INTO users (username, email) VALUES (?, ?)";
PreparedStatement insertStatement = connection.prepareStatement(insertSql);
insertStatement.setString(1, USERNAME);
insertStatement.setString(2, EMAIl);
insertStatement.executeUpdate();
String selectSql = "SELECT * FROM users WHERE username = ?";
PreparedStatement selectStatement = connection.prepareStatement(selectSql);
selectStatement.setString(1, USERNAME);
ResultSet resultSet = selectStatement.executeQuery();
resultSet.next();
assertEquals(USERNAME, resultSet.getString("username"));
assertEquals(EMAIl, resultSet.getString("email"));
}
以下是可用方法及其用途的快速概述:
方法 | 目的 |
---|---|
executeQuery() |
它用於執行從資料庫檢索資料的 SELECT 語句。 |
executeUpdate() |
它用於執行 DML 語句(例如 INSERT、UPDATE、DELETE)和 DDL 語句(例如 CREATE 和 ALTER)。 |
execute() |
它用於執行任何 SQL 語句,通常是在未事先確定類型的情況下。 |
4. 結論
在本文中,我們探討了不常見的錯誤C
annot issue data manipulation statements with executeQuery()
並了解其原因。我們也了解到對特定 SQL 語句使用正確的 JDBC 方法的重要性,因為每種方法都有其獨特的用途。
與往常一樣,完整的程式碼範例可以在 GitHub 上找到。