我可以从匿名PL/SQL块返回值到PHP吗?

我可以从匿名PL/SQL块返回值到PHP吗?,php,oracle,plsql,oci8,Php,Oracle,Plsql,Oci8,我使用PHP和OCI8执行匿名Oracle PL/SQL代码块。对于我来说,有什么方法可以绑定一个变量并在块完成时获得它的输出,就像我以类似的方式调用存储过程一样 $SQL = "declare something varchar2 := 'I want this returned'; begin --How can I return the value of 'something' into a bound PHP variable? end;"; 通过在名称和数据类型声明之间使用关键字

我使用PHP和OCI8执行匿名Oracle PL/SQL代码块。对于我来说,有什么方法可以绑定一个变量并在块完成时获得它的输出,就像我以类似的方式调用存储过程一样

$SQL = "declare
something varchar2 := 'I want this returned';
begin
  --How can I return the value of 'something' into a bound PHP variable?
end;";

通过在名称和数据类型声明之间使用关键字
out
,可以定义out参数。即:

CREATE OR REPLACE PROCEDURE blah (OUT_PARAM_EXAMPLE OUT VARCHAR2) IS ...
如果未指定,中的
是默认值。如果要将参数同时用作输入和输出,请使用:

CREATE OR REPLACE PROCEDURE blah (INOUT_PARAM_EXAMPLE IN OUT VARCHAR2) IS ...
下面的示例创建了一个带有IN和OUT参数的过程。然后执行该过程并打印结果

<?php
   // Connect to database...
   $c = oci_connect("hr", "hr_password", "localhost/XE");
   if (!$c) {
      echo "Unable to connect: " . var_dump( oci_error() );
      die();
   }

   // Create database procedure...
   $s = oci_parse($c, "create procedure proc1(p1 IN number, p2 OUT number) as " .
                     "begin" .
                     "  p2 := p1 + 10;" .
                     "end;");
   oci_execute($s, OCI_DEFAULT);

   // Call database procedure...
   $in_var = 10;
   $s = oci_parse($c, "begin proc1(:bind1, :bind2); end;");
   oci_bind_by_name($s, ":bind1", $in_var);
   oci_bind_by_name($s, ":bind2", $out_var, 32); // 32 is the return length
   oci_execute($s, OCI_DEFAULT);
   echo "Procedure returned value: " . $out_var;

   // Logoff from Oracle...
   oci_free_statement($s);
   oci_close($c);
 ?>

参考:

    • 以下是我的决定:

      function execute_procedure($procedure_name, array $params = array(), &$return_value = ''){
          $sql = "
          DECLARE
              ERROR_CODE      VARCHAR2(2000);
              ERROR_MSG       VARCHAR2(2000);
              RETURN_VALUE    VARCHAR2(2000);
          BEGIN ";
      
          $c = $this->get_connection();
      
          $prms = array();
          foreach($params AS $key => $value) $prms[] = ":$key";
          $prms = implode(", ", $prms);
      
          $sql .= ":RETURN_VALUE := ".$procedure_name."($prms);";
          $sql .= " END;";
      
      
          $s = oci_parse($c, $sql);
      
          foreach($params AS $key => $value)
          {
              $type = SQLT_CHR;
              if(is_array($value))
              {
                  if(!isset($value['value'])) continue;
                  if(!empty($value['type'])) $type = $value['type'];
                  $value = $value['value'];
              }
              oci_bind_by_name($s, ":$key", $value, -1, $type);
          }
      
          oci_bind_by_name($s, ":RETURN_VALUE", $return_value, 2000);
      
          try{
              oci_execute($s);
              if(!empty($ERROR_MSG))
              {
                  $data['success'] = FALSE;
                  $this->errors = "Ошибка: $ERROR_CODE $ERROR_MSG";
              }
              return TRUE;
          }
          catch(ErrorException $e)
          {
              $this->errors = $e->getMessage();
              return FALSE;
          }
      }
      
      例如:

          execute_procedure('My_procedure', array('code' => 5454215), $return_value);
          echo $return_value;
      

      存储过程是永久创建的还是仅为此会话创建的?我使用这个方法从数据库中编译的过程中接收参数(看起来这是做同样的事情,除了先创建过程)。我希望在执行此代码时避免在数据库中创建任何永久对象。@Renderlin:是的,orafaq.com中的示例将创建存储过程。您需要将存储过程放在匿名PLSQL块的DECLARE块中,并使
      proc1(…<代码)>在开始/结束部分,以不创建过程。@ OMGPonies是在10G中支持的参数,我正在读取他们支持的代码!抛出一组代码,我几乎不认为是有价值的答案。请解释为什么您的代码解决了OP.问题。