2011-04-13 46 views
2

是否有任何方法來檢查Oracle的SQL查詢是否可以成功運行(通過成功我的意思是查詢在語法上是正確的,所有表/列名都存在,用戶具有適當的權限,等等)而不實際運行它?該查詢可能不是SELECT,但我不希望更改實際發生,如果它會修改任何數據。驗證Oracle非SELECT查詢

我想過是這樣的:

$valid = false; 
$stmt = oci_parse($db, $query); 
if(!empty($stmt)) { 
    $res = oci_execute($stmt, OCI_DESCRIBE_ONLY|OCI_NO_AUTO_COMMIT); 
    if(!empty($res)) { 
    $name = oci_field_name($res, 1); 
    if(!empty($name)) { 
     $valid = true; 
    } 
    } 
    oci_rollback($db); 
} 

但是如果$查詢有一定的DDL中,我瞭解到,甲骨文將立即提交。那麼是否有任何方法可以在不做任何修改的情況下檢查查詢?

+0

oci_parse過程中會發生什麼? – 2011-04-13 20:56:49

+1

@Shannon - 來自oci_parse手冊頁:「該函數不驗證sql_text。找出sql_text是否是有效的SQL或PL/SQL語句的唯一方法就是執行它。」看到http://php.net/manual/en/function.oci-parse.php – DCookie 2011-04-13 21:44:19

+0

我打算建議研究dbms_sql包的解析過程,直到我閱讀文檔「所有語句都立即被解析爲 」。另外,DDL語句在解析時立即運行。「所以沒關係。 – 2011-04-13 22:12:41

回答

1

您可以在包中創建查詢。如果包創建時沒有錯誤,那麼查詢必須是正確的。

基於角色的權利可能會導致任何語法檢查問題。直到runtil纔會檢查基於角色的權限,因此在設計時查詢是可能正確的(因爲開發人員已被授予對錶的直接權限),但在運行時失敗(因爲用戶已被授予相同的權限)一名角色)。

+0

我只在運行時需要它 - 例如,應用程序生成一組查詢並希望在運行它們之前確保它們一切正常。 – StasM 2011-04-13 21:18:47

+1

您不能直接將DDL放在PL/SQL包中。您可以使用'EXECUTE IMMEDIATE'從PL/SQL執行DDL,但是這並不會給您任何OP正在查找的編譯時檢查。 – 2011-04-13 22:00:18

+0

我在想你會在運行時創建包,而不是在設計時。包中沒有DDL是正確的。您可以創建一個包含空表的陰影模式,這些模式看起來就像您的真實模式。然後你可以對這個空數據模式執行命令。你甚至可以運行DDL命令。 – 2011-04-13 22:55:30

1

STEP 1:

在你的PHP代碼

,創建一個包含文本的字符串:

Dim myValidationString as string 

myValidationString = " create or replace procedure PROC_TEST_QUERY is " & 
        "  begin         " & 
        "   for i in (       " & 
        "     {MY_QUERY}     " & 
        "     ) loop      " & 
        "    null;        " & 
        "   end loop;        " & 
        "  end;          " 

STEP 2:

創建包含要在SqlQuery類變量驗證:

Dim mySQLstring as string 

mySQLstring = " SELECT *        " & 
       " from all_objects      " & 
       " where owner <> 'SYS'     " & 
       " and created > sysdate -30   " & 
       " UNION ALL        " & 
       " Select *        " & 
       " from all_objects      " & 
       " where owner = 'SYS'     " & 
       " and object_name like 'T%'   " & 
       " and object_type in ('TABLE','VIEW') " 

STEP 3:

與SQL語句的內容替換字符串的內容 「{MY_QUERY}」 要驗證:

Dim myValidationStringToExecute as string 

myValidationStringToExecute = replace(myValidationString, "{MY_QUERY}" , mySQLstring) 

STEP 4:

執行驗證查詢:

DB.EXECUTE(myValidationStringToExecute) 

步驟5:

驗證上次調用(DB.EXECUTE .....)是否引發錯誤。 如果是,則查詢無效 如果不是,則查詢有效

+0

這不適用於DDL。 – 2012-10-11 04:27:54