2011-12-08 39 views
1

我的情況是,我需要在特定時間動態創建數據庫分區。我使用的是Statement類似如下:使用準備好的語句設置LONG數據類型

alter table table_name split partition default_partition values (' + 
id + ') into ( partition " + partitionName + ", partition 
default_partition) update indexes 

這工作正常,不正是我所期望的。但是,id的值來自未授權人員可能訪問的輸入。所以,上述說法是容易受到SQL注入攻擊。我想用PreparedStatement,但我無法弄清楚。

問題是,oracle中的分區表將「id」值放入LONG的HIGH_VALUE列中。我沒有看到適當的setter來做到這一點(因爲字符串不能工作)。我嘗試過使用各種流消息,其中StringReaderByteArrayInputStream作爲值無效。我知道LONGs不應該再被使用,但這是Oracle擁有它的方式,所以我無法真正解決它。

當我試着使用任何這些方面,這就是我得到:

ORA-14308: partition bound element must be one of: string, datetime or interval literal, number, or NULL 

甲骨文的文檔對如何獲得好的長信息(Oracle數據類型,它就像一個LOB)但不是如何設置它。任何人都可以幫助我嗎?我還研究了JDBC驅動程序的Oracle實現,但它似乎也沒有setLONG類型的方法。有什麼辦法可以做到這一點?

+0

也許我錯過了一些東西,但我認爲PreparedStatement上有一個名爲'setLong(int,long)'的方法: http://docs.oracle.com/javase/6/docs/api/java /sql/PreparedStatement.html 這不行嗎? – hooknc

+0

是的,LONG oracle類型基本上是一個LOB。所以,它不像Java那麼長。 – AHungerArtist

+0

由於Oracle的LONG是字符數據(傻瓜),你嘗試過'setString(int,id.toString())'嗎?你嘗試過哪些方法? – Gray

回答

5

您不能在DDL中使用綁定變量。您無法在DDL語句中使用PreparedStatement並調用任何setXXXX方法。

基於用戶輸入來動態分割分區至少是非常不尋常的設計。我傾向於懷疑你會更好地使用類似interval partitioning的東西,其中Oracle需要在需要時創建新的分區,或者使用散列分區而不是範圍分區。假設手動創建新分區確實很有意義,但是,您必須編寫代碼來驗證「id」和「partitionName」值是否有效,以防止SQL注入。

+0

嗯,我只是想簡化一些東西。這不像任何用戶可以做到這一點。這將是非常有限的,但我們仍然希望確保我們受到保護,以防萬一這些少數用戶變得腐爛或有人以另一種方式獲得訪問權限。我將使用驗證路線,儘管它不是PS的保證。謝謝。 – AHungerArtist

0

是一個字符串,如果是的話,爲什麼你不驗證它之前?

try { 
     id = Long.valueOf(unsafeId); 
     //do more validations here 
    } catch (NumberFormatException e) { 
     throw new RuntimeException("Not a valid input."); 
    } 
+0

這實際上並不長。數據庫中的類型很長,實際上只是char數據。此外,有效的id可以採取的形式是多種多樣的(和id是一個壞名字,我用這個例子替換了實際的名字)。 – AHungerArtist