2009-03-04 49 views
3

我正在嘗試引用列名來命令在與Oracle數據庫進行通信的應用程序中進行查詢。我想使用一個綁定變量,這樣我就可以動態地改變什麼來排序查詢。是否可以通過Oracle中的綁定變量引用列名稱?

我遇到的問題是數據庫似乎忽略了列的順序。

有誰知道是否有一種特定的方式通過綁定變量引用數據庫列,或者甚至有可能嗎?

如我的查詢是

SELECT * FROM PERSON ORDER BY :1 

(其中:1將被綁定到PERSON.NAME) 按字母順序查詢沒有返回結果,我擔心的是,數據庫爲解釋這一點: -

SELECT * FROM PERSON ORDER BY 'PERSON.NAME' 

這顯然不起作用。

任何建議,非常感謝。

回答

6

不能。對錶名或列名不能使用綁定變量。

創建執行計劃需要此信息。例如,如果不知道你想要命令什麼,就不可能找出使用哪個索引。

而不是綁定變量,當您的程序創建它時,您必須直接插入列名到SQL語句中。假設你採取了預防SQL注入的措施,這沒有任何不利之處。

更新:如果你真的想跳火圈,你很可能這樣做

order by decode(?, 'colA', colA, 'colB', colB) 

但這僅僅是愚蠢的。而且很慢。別。

+0

+1 btw我不知道Oracle是否屬於這種情況,但在其他數據庫(如DB2)中肯定存在不利因素 - 如果您修改查詢命令文本時,數據庫緩存查詢會更加困難時間(而不僅僅是參數的值) – 2009-03-04 10:54:18

+0

這也發生在oracle中。但是你並不是一直在改變命令文本。列名只有幾個選項,所以只有五個緩存條目左右。 – Thilo 2009-03-04 10:55:38

+0

非常感謝,這對我很有意義。我會盡量讓代碼明白它在查看order by子句的時候,如果它包含一個綁定變量,我會用它的值替換它。 – Scottm 2009-03-04 11:02:13

2

正如您使用的是JDBC。你可以重寫你的代碼,沒有綁定變量的東西。這樣,您還可以通過動態訂單例如: -

String query = "SELECT * FROM PERS "; 
    if (condition1){ 
     query = query+ " order by name "; 
    // insert more if/else or case statements 
    } else { 
     query = query+ " order by other_column "; 
    } 
    Statement select = conn.createStatement(); 
    ResultSet result = select.executeQuery(query); 

甚至

String columnName = getColumnName(input); 
    Statement select = conn.createStatement(); 
    ResultSet result = select.executeQuery("SELECT * FROM PERS ORDER BY "+columnName); 
0

的ResultSet結果= select.executeQuery改變( 「SELECT * FROM PERS ORDER BY」 + COLUMNNAME);

將永遠是數據庫的一條新語句。這意味着,就像Thilo已經解釋的那樣,不可能「重新排序」一個已經綁定,計算,準備好,解析的語句。在應用程序中反覆使用此結果集時,唯一隨時間變化的是演示文稿的順序,請嘗試在您的客戶端代碼中對該集合進行排序。否則,動態SQL很好,但佔用空間很大。

相關問題