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

29 篇文章 0 订阅
28 篇文章 0 订阅

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<br>";
       oci_close($conn);
        exit;
    }

三、访问效果

在这里插入图片描述

四、如何动态调用带有输入输出参数的存储过程呢?

php调用oracle 操作类

<?php
/**
 * Created by RoyeeCai.
 * User: RoyeeCai
 * Date: 2021-03-18
 * Time: 13:09
 */

class OracleTool{

    /**
     * @var  php操作oci类
     * 用于操作oracle数据库
     */

    private  $conn = null;
    private  $stmt = null;
    private static $instance;
    private $message=null;
    private $configs= [
        'username'=>'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\n\n";
        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." ";

        //拼凑字段列表部分
        $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\n\n";

    }


    /**
     * @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']);
             }         

     }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值