2008-10-02 16 views
4

我有一個Web應用程序,用戶可以在其中輸入任意的sql查詢以便以後進行批處理。我們希望驗證查詢的語法而不實際執行它。一些查詢需要很長時間,這就是爲什麼我們不想執行它們。我正在使用Oracle的dbms_sql.parse來執行此操作。有沒有辦法獲得未知的數據庫查詢的類型/名稱而不執行它?

但是,我現在有一種情況,我需要知道結果集列的數量和類型。有沒有辦法做到這一點,而不實際執行查詢?也就是說,要讓Oracle解析查詢並告訴我在查詢實際執行時返回的結果數據類型/名稱是什麼?我使用的是Oracle 10g,它是一個Java 1.5/Servlet 2.4應用程序。

編輯:輸入查詢的用戶已經是數據庫上的用戶。他們使用他們的數據庫憑據向我的應用程序進行身份驗證,並使用這些憑據執行查詢。因此,他們不能通過連接sqlplus來輸入任何無法運行的查詢。

+0

你讓用戶輸入查詢?這聽起來很危險。 – GEOCHET 2008-10-02 16:48:02

+0

我第二! 「刪除*從...」! – 2008-10-02 16:50:08

回答

7

您應該能夠準備一個SQL查詢來驗證語法並獲取結果集元數據。準備一個查詢不應該執行它。

import java.sql.*; 
. . . 
Connection conn; 
. . . 
PreparedStatement ps = conn.prepareStatement("SELECT * FROM foo"); 
ResultSetMetadata rsmd = ps.getMetaData(); 
int numberOfColumns = rsmd.getColumnCount(); 

然後你可以得到關於結果集的每一列的元數據。

4

如果你想嚴格通過PL/SQL要做到這一點,那麼你可以做到以下幾點:

DECLARE 
    lv_stat varchar2(100) := 'select blah blah blah'; 
    lv_cur INTEGER; 
    lv_col_cnt INTEGER; 
    lv_desc DBMS_SQL.desc_tab; 
BEGIN 
    DBMS_SQL.parse(lv_cur,lv_stat,DBMS_SQL.NATIVE); 
    DBMS_SQL.describe_columns(lv_cur,lv_col_cnt,lv_desc); 
    FOR ndx in lv_desc.FIRST .. lv_desc.LAST LOOP 
    DBMS_OUTPUT.PUT_LINE(lv_desc(ndx).col_name ||' '||lv_desc(ndx).col_type); 
    END LOOP; 
END; 

的DBMS_SQL.desc_tab包含了幾乎所有你需要知道的列。

相關問題