PHP调用存储过程并接收存储过程返回值原创

原创
小哥 3年前 (2022-11-11) 阅读数 114 #PHP
文章标签 PHP

php调用oracle带有输出参数的存储过程

一、创建oracle存储过程

CREATE OR REPLACE PROCEDURE PROC_TEST (
  p_id IN OUT NUMBER,
  p_name OUT VARCHAR2
) AS 
BEGIN
  SELECT NAME INTO p_name
    FROM TEST
    WHERE ID = p_id;
END PROC_TEST;

二、php调用代码

安装oracle扩展 安装方法可参考。 【Centos7 php7.3安装oracle扩展】

 /**
     * php调用存储过程并处理返回值。
     */
    public function testProcedure(){
        //建立数据库连接
        $conn = oci_connect(scott,scott,10.87.234.25/orcl,UTF8);
        if(!$conn){
            echo  oci_error();exit;
        }
        $id = 5;                        //已准备好绑定php变量 id
        $name = "";                     //已准备好绑定php变量 name/** 调用存储过程。sql语句(sql_sp : SQL_StoreProcedure)
        $sql_sp = "BEGIN PROC_TEST(:id, :name); END;";//Parse
        $stmt = OCIParse($conn, $sql_sp);//执行绑定
        OCIBindByName($stmt, ":id", $id, 16);           //参数说明:绑定php变量$id到位置:id并设置装订长度。16位
        OCIBindByName($stmt, ":name", $name, 30);//Execute
        OCIExecute($stmt);//结果
        echo "name is : $name
"; oci_close($conn); exit; }

3.进入效果

4.如何使用输入和输出参数动态调用存储过程?

php调用oracle 操作类

scott,
        password=>scott,
        connstr=>10.87.230.211/orcl,
        charset=>UTF8,
    ];

    /**
     * 建立数据库连接
     * @return null|resource
     */

    public function __construct()
    {

        $this->connect();
    }

    /**
     * @return 获取受影响的行数
     */
    public function getAffectRows(){
        return oci_num_rows($this->stmt);
    }

    /**
     * 获取错误报告提示信息
     * @return
     */
    public function getMessage(){
        return $this->message;
    }

    public function connect(){
        $tmp_config = $this->configs;
        $this->conn = oci_connect($tmp_config[username],$tmp_config[password],$tmp_config[connstr],$tmp_config[charset]);
        if(!$this->conn){
            $this->message = oci_error();
        }
        return $this->conn;
    }

    /**
     * 获取数据库对象
     * @return PhpOci
     */
    public static function getInstance(){

        if(self::$instance == false) {
            self::$instance =new self;
        }
        return self::$instance;
    }

    function create_table($sql)
    {
        $this->stmt = oci_parse($this->conn, $sql);
        oci_execute($this->stmt);
        return true;
    }

    function drop_table($sql)
    {
        $this->stmt = oci_parse($this->conn, $sql);
        oci_execute($this->stmt);
        //echo $this->conn . " dropped table

"; return true; }

    function insert_data($sql)
    {
        $this->stmt = oci_parse($this->conn, $sql);
        oci_execute($this->stmt, OCI_DEFAULT);
    }

    function commit()
    {
        oci_commit($this->conn);
    }

    function rollback()
    {
        oci_rollback($this->conn);
    }
    /**
     * 获取数据库数据
     * 返回一个二维数组...
     * @param $sql
     * @return array
     */
    public function findAll($sql)
    {
        $data =[];
        $this->stmt = oci_parse($this->conn, $sql);
        oci_execute($this->stmt, OCI_DEFAULT);
        while(($row = oci_fetch_assoc($this->stmt)) != false) {
            $data[] = $row;
        }
        return $data;
    }

    /***
     * 查询一条数据 返回一维数组
     * @param $sql
     * @return array|mixed
     */
    public function findOne($sql)
    {
        $data =[];
        $this->stmt = oci_parse($this->conn, $sql);
        oci_execute($this->stmt, OCI_DEFAULT);
        while(($row = oci_fetch_assoc($this->stmt)) != false) {
            $data[] = $row;
        }
        if(!empty($data))
        {
            $data = $data[0];
        }

        return $data;
    }

    /**
     * 自动插入数据库语句 拼凑sql
     * @param $data
     * @param $table
     * @return bool
     */
    public function autoInsert($data,$table) {
//      insert into 表名 (字段1,字段2,字段N) values (值1,值2,值N)
//      $data = array(
//          字段1=>值1,
//          字段2=>值2,
//          字段3=>值3,
//      );
        //拼凑insert表名
        $sql = "insert into ".$table." ";

        //Patchwork字段列表部分
        $fields = array_keys($data);//获取所有密钥
        $fields = array_map(function($v){return $v;}, $fields);//用反引号将字段名括起来
        $fields_str = implode(, , $fields);//使用逗号连接
        $sql .= ( . $fields_str . );

        //修补工作值列表部分
        $values = array_map(function($v) {return "".$v."";}, $data);//获取所有值,增加引号中的值
        $values_str = implode(, , $values);//再次使用逗号连接
        $sql .=  values ( . $values_str . );
        //执行该insert语句
        try{
            $this->stmt = oci_parse($this->conn, $sql);
            oci_execute($this->stmt, OCI_DEFAULT);
            $this->commit();
            return true;
        }catch(Exception $e){
            $this->rollback();
            return false;
        }
        //echo $this->conn . " inserted hallo

";

    }

    /**
     * @param $table   要更新的表
     * @param $data    要更新的数据[fields=>value,...]
     * @param $id      根据哪些字段更新  如 id,rowid   要包括的字段$data中
     * @return string  返回成功执行
     */
    public function autoUpdate($table,$data,$id=id){
        $str = "";
        $pk_value = ;
        if(!empty($data)){
            if(isset($data[$id])){
                $pk_value = $data[$id];
                unset($data[$id]);
            }
            foreach($data as $k=>$v){
                $str .= "$k="."".$v."".",";
            }
            $str = substr($str,0,-1);
        }
        $sql="update {$table} set ".$str." where {$id}=".$pk_value."";
        //执行该insert语句
        try{
            $this->stmt = oci_parse($this->conn, $sql);
            oci_execute($this->stmt, OCI_DEFAULT);
            $this->commit();
            return true;
        }catch(Exception $e){
            $this->rollback();
            return false;
        }
    }

    // 调用存储过程函数

    /**
     * @
     * @param $procName 调用存储过程名称
     * @param array $params 输入参数
     * @param array $bindParams 绑定输出参数
     * @return array  code =1 表示成功  其他人则表示失败
     */
    public function callProcedure($procName,$params=[],$bindParams=[]){
        $result = [
            code=>0, //0 表示失败 1 表示成功
            message=>失败,
            output=>[]
        ];
        if($procName == ""){return $result;}
        try{
            $sql = "BEGIN ".$procName."(";
            if(!empty($params))
            {
                foreach ($params as $k=>$v)
                {
                    //拼凑 入参
                    $sql.="{$k}=>{$v},";
                }
            }
            if(!empty($bindParams))
            {
                foreach ($bindParams as $v)
                {
                    //$$v[key] = "";
                    $sql .= "{$v[value]}=>:".$v[value].",";
                }
            }
            $sql = substr($sql,0,strlen($sql)-1)."); END;";
            //var_dump($sql);//exit;
            $this->stmt = OCIParse($this->conn, $sql);//执行绑定
            if(!empty($bindParams))
            {
                foreach ($bindParams as $v)
                {
                    $_key=ex_.$v[key]; //定义输出参数变量 为了避免变量冲突 增加变量前缀
                    $$_key = ;
                    OCIBindByName($this->stmt, ":".$v[value], $$_key ,$v[length]);
                }
            }
            OCIExecute($this->stmt); //结果执行
            if(!empty($bindParams))
            {
                foreach ($bindParams as $v)
                {
                    //获取输出参数结果
                    $_key=ex_.$v[key];
                    $result[output][$v[key]]=$$_key;
                }
            }
            $result[code]=1;
            $result[message]="成功了!";
        }catch(Exception $ex){
            $result[message] = "失败了!".$ex->getMessage();
            $result[code] = 0;
        }
        return $result;
    }

    //释放连接
    public function __destruct(){
        oci_free_statement($this->stmt);
        oci_close($this->conn);
    }

}
  • 调用方法

    public function test_auto_pro() { // 实例化数据库类。 单例模式 $db = OracleTool::getInstance(); // 存储过程条目
    $params = [ Vi机构序号=>1, Vi终端序号=>16568, Vi操作员编号=>1, vs业务类型=>充值, Vs充值方式=>现金, Vi充值金额=>33, Vi赠送金额=>0, vi赠送积分=>0, Vi会员类型=>-1, Vs充值金额验证 =>, Vi健康序号i=>58831, Vi业务序号I=>, vi支付序号=>, vi原卡号=>, vi新卡号=>, vi套餐序号=>, vi套餐支付=>0, vs备注=>, vi挂账限额=>0 ]; // 参数之外的存储过程。 $bindParams = [ Pb输出状态=>[ key=>status, value=>Pb输出状态, length=>30 ], PS输出描述=>[ key=>desc, value=>PS输出描述, length=>300 ], ];

            // 入境和出境 参考类 OracleTool 中的callProcedure 方法
             $rest = $db->callProcedure(FIN_PD会员充值,$params,$bindParams);
             // var_dump($rest);exit;
             if($rest[code]==1){
                 $this->success("充值成功!",$rest[output]);
             }else{
                 $this->error("充值失败",$rest[message]);
             }         
    
     }
版权声明

所有资源都来源于爬虫采集,如有侵权请联系我们,我们将立即删除

热门