验证Oracle非SELECT查询

时间:2011-04-13 19:40:09

标签: php sql oracle oci

有没有办法检查Oracle的SQL查询是否会成功运行(成功的意思是查询语法正确,所有表/列名称都存在,用户具有适当的权限等)而无需实际运行它?查询可能不是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);
}

但是如果$ query中有一些DDL,我知道Oracle会立即提交它。那么有没有办法检查查询而不进行任何修改?

2 个答案:

答案 0 :(得分:1)

您可以在Package中创建查询。如果创建的包没有错误,则查询必须正确。

基于角色的权限,可能导致任何语法检查问题。在runtil之前不会检查基于角色的权限,因此查询在设计时可能是正确的(因为开发人员已被授予对表的直接权限)但在运行时失败(因为用户已被授予相同的权限)一个角色)。

答案 1 :(得分:1)

第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;                                     "

第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') " 

第3步:

将字符串内容“{MY_QUERY}”替换为您要验证的SQL语句的内容:

Dim myValidationStringToExecute as string

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

第4步:

执行验证查询:

DB.EXECUTE(myValidationStringToExecute)

第5步:

验证最后一次调用(DB.EXECUTE .....)是否引发错误。  如果是,则查询无效  如果不是,则查询有效