簡體   English   中英

准備好的語句-使用函數作為where子句的一部分

[英]Prepared statement - using a function as part of the where clause

我正在使用從Oracle數據庫獲取數據的Java准備語句。 由於某些性能問題,該查詢使用“虛擬列”作為索引。

查詢如下所示:

String status = "processed";
String customerId = 123;
String query = "SELECT DISTINCT trans_id FROM trans WHERE status = " + status + " AND FN_GET_CUST_ID(trans.trans_id) = " + customerId;

Connection conn = getConnection();
PreparedStatement ps = null;
ResultSet rs = null;

try {
  ps = conn.prepareStatement(query);
  ps.execute();
  ...
} catch (...)

這是行不通的。 將函數作為where子句的一部分會導致SQLException。 我知道CallableStatement,並且知道可以先使用它,然后再連接結果。 但是,此表使用FN_GET_CUST_ID(trans_id)作為其索引的一部分。 有沒有辦法使用帶有數據庫功能的預備語句作為查詢參數?

  1. 切勿將SQL的參數連接到字符串中。 始終使用占位符( ? )和setXxx(column, value);

  2. 如果您在自己喜歡的數據庫工具中運行SQL,則會遇到相同的錯誤。 問題是Oracle由於某些原因無法使用該功能。 您得到什么錯誤代碼?

如果客戶ID是數字,請保持int而不是String。 然后嘗試執行以下操作:

String query = "SELECT DISTINCT trans_id FROM trans WHERE status = ? AND FN_GET_CUST_ID(trans.trans_id) = ?"; 

ps = conn.prepareStatement(query); 
ps.setString(1, status);
ps.setInt(2, customerId);
ps.execute();

除了准備好的語句的其他好處之外,您不必記住字符串引號(這很可能導致您的錯誤)和特殊字符的轉義。

乍一看,查詢似乎是不正確的。 在使用status變量前后,您都缺少撇號(假設狀態為varchar列)。

String query = "SELECT DISTINCT trans_id FROM trans 
WHERE status = '" + status + "' AND FN_GET_CUST_ID(trans.trans_id) = " + customerId;

編輯:我不是來自Java背景。 但是,正如@Aron所說,最好使用占位符,然后使用某種方法設置參數值,以避免SQL Injection

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM