2011-03-30 49 views
4

繼我之前關於method design的一個問題之後,我建議我將SQL查詢作爲參數化查詢來實現,而不是簡單的字符串。簡單參數化查詢出錯-Java/SQL

我從來沒有使用參數化查詢之前,所以我決定用一些簡單的入手,採取以下選擇聲明:

String select = "SELECT * FROM ? "; 

PreparedStatement ps = connection.prepareStatement(select); 
ps.setString(1, "person"); 

這給了我下面的錯誤:「[SQLITE_ERROR] SQL錯誤或缺少數據庫(接近「?」:語法錯誤)「

然後我嘗試了一個修改後的版本,它有其他標準;

String select = "SELECT id FROM person WHERE name = ? "; 

PreparedStatement ps = connection.prepareStatement(select); 
ps.setString(1, "Yui"); 

這個版本工作得很好,在我的第一個例子我失去了參數化查詢點還是我錯誤地建設呢?

謝謝!

回答

9

簡而言之,SQL綁定無法綁定表,只有where子句的值。這裏有一些與「編譯」準備好的SQL語句有關的技術上的原因。一般來說,參數化查詢的目的是通過防止SQL注入來提高SQL的安全性,並且它具有使查詢更「模塊化」的優勢,但不能動態設置表名稱(因爲它假定你已經知道表將會是什麼)。

+0

因此,如果我想返回一個包含來自表(SELECT * FROM person)的所有結果的ResultSet,那麼不能將它作爲一個字符串進行隱式輸入來完成。 – 2011-03-30 19:24:02

+0

如果你問你是否可以通過參數化查詢概括select * from

,答案是否定的。你需要有一個專用的SQL或者構建你自己的select *的通用版本。 – 2011-03-30 19:31:12

+0

是的,這就是我的意思:),這是一個恥辱。我想這樣做,所以我可以使用自上次執行命令以來所做的更改來更新我的JTable,您知道刷新表的更好方法嗎? – 2011-03-30 19:33:45

1

準備好的語句仍然是SQL,需要使用適當的where子句構造;即其中x = y。他們的優點之一是,它們在第一次被看到時被RDMS解析,而不是每次被髮送時都被加以解析,這加快了後續執行具有不同綁定值的相同查詢的速度。

2

如果你想從PERSON表中的所有行,這裏是你應該做的:

String select = "SELECT * FROM person"; 

PreparedStatement ps = connection.prepareStatement(select); 

變量綁定不能動態綁定表名稱爲他人如上所述。 如果你有表名即將到您的方法作爲變量,您可以構建整個查詢如下:

String select = "SELECT * FROM " + varTableName; 
PreparedStatement ps = connection.prepareStatement(select); 

參數化查詢是用於查詢的字段名稱 - 而不是表名!

+0

感謝您的詳細示例,讓事情變得更清晰:) – 2011-03-30 19:39:43