ci3 原有的oci8d存储过程调用功能不能用,自己整了一个
假设该文件是 game_model.php
// 下面的功能可以放在继承CI_model的base_moel里面或者 单独的model文件里面
// 按照逻辑 base_moel 是继承CI_model, 被实体model继承的中间件
/**
* 专为oracle 存储过程写的函数, stmt // new_cursor // stored_procedure // fetch_all
* 使用stored_procedure 即可调用存储过程, 如果有游标先要定义游标
*
$curs = $this->game_model->new_cursor(); // 创建 CURSOR
$params = [
['name' =>':page', 'value' => $page, 'length' => -1, 'type' => SQLT_INT],
['name' =>':tblName', 'value' => $tblName, 'length' => -1, 'type' => SQLT_CHR],
['name' =>':wheres', 'value' => $wheres, 'length' => -1, 'type' => SQLT_CHR],
['name' =>':pageSize', 'value' => $pageSize, 'length' => -1, 'type' => SQLT_INT],
['name' =>':totalRows', 'value' => $totalRows,'length' => -1, 'type' => SQLT_INT],
['name' =>':v_cur', 'value' => $curs, 'length' => -1, 'type' => SQLT_RSET ], // OCI_B_CURSO, SQLT_RSET
];
*/
/**
* @return false|resource
*/
public function new_cursor(){
return oci_new_cursor($this->GAME_DB->conn_id);
}
/**
* @param $package
* @param $procedure
* @param $params
* @param array $out
* @return array
*/
public function stored_procedure($package, $procedure, $params, $out=[]){
$sql = 'BEGIN '.$package.'.'.$procedure.'(';
foreach ($params as $param)
{
$sql .= $param['name'].',';
}
$sql = trim($sql, ',').'); END;';
$stmt = oci_parse($this->GAME_DB->conn_id, $sql);
foreach ($params as $key => & $param)
{
oci_bind_by_name($stmt, $param['name'], $params[$key]['value'], $param['length'], $param['type']);
}
oci_execute($stmt);//结果
$res = [];
foreach($params as &$param){
if(!in_array($param['name'], $out)) continue;
if(is_resource($param['value'])){
$res['resource'][$param['name']] = $param['value'];
oci_execute($res['resource'][$param['name']]); // 执行游标资源
$res['data'][$param['name']] = $this->fetch_all($res['resource'][$param['name']]); // 获取游标数据
}else{
$res[$param['name']] = $param['value'];// 非游标资源返回
}
}
return $res;
}
/**
* @param $resource
* @return array
*/
protected function fetch_all($resource){
$data = [];
while ($row = oci_fetch_assoc($resource)){ //var_dump(oci_fetch_assoc($resource) );exit();
$data[] = $row;
}
return $data;
}
/**
* @param $params
* @param $sql
* @return false|resource
*/
private function stmt($params, $sql){
foreach ($params as $param)
{
$sql .= $param['name'].',';
}
$sql = trim($sql, ',').'); END;';
return oci_parse($this->GAME_DB->conn_id, $sql);
}
Controller 中调用
public function weeklyMission(){
$package = 'XXXXX.PKG_PLATFORM';
$procedure = "WEEKLY_MISSION";
$page = 1;
$tblName = 'R2B2_WEEKLY_MISSION';
$wheres = ' and 1=1 ';
$pageSize = 10;
$totalRows = 0;
$curs = $this->game_model->new_cursor(); // 创建 CURSOR 只有在返回游标的时候才创建
$params = [
['name' =>':page', 'value' => $page, 'length' => -1, 'type' => SQLT_INT],
['name' =>':tblName', 'value' => $tblName, 'length' => -1, 'type' => SQLT_CHR],
['name' =>':wheres', 'value' => $wheres, 'length' => -1, 'type' => SQLT_CHR],
['name' =>':pageSize', 'value' => $pageSize, 'length' => -1, 'type' => SQLT_INT],
['name' =>':totalRows', 'value' => $totalRows,'length' => -1, 'type' => SQLT_INT],
['name' =>':v_cur', 'value' => $curs, 'length' => -1, 'type' => SQLT_RSET ], // OCI_B_CURSO, SQLT_RSET
];
$weekly_mission_data = $this->game_model->stored_procedure($package, $procedure, $params,[':totalRows', ':v_cur']);
var_dump($weekly_mission_data);
}
ORACLE 存储过程,这里用的是存储包
// 存储包的 存储过程申明
CREATE OR REPLACE PACKAGE XXDBNAME."PKG_PLATFORM" AS
--new account count
PROCEDURE GET_NRU(
p_starttime VARCHAR2,
p_endtime VARCHAR2,
p_Result OUT NUMBER
);
TYPE type_cur IS REF CURSOR;
PROCEDURE WEEKLY_MISSION
(
page IN NUMBER, -- 当前页
tblName IN varchar2, -- 要查询的吧表名,
wheres varchar2, -- WHERE 查询条件 AND 开头
pageSize IN NUMBER, -- 每页大小
totalRows OUT NUMBER, -- 总数据数量 // totalPage OUT NUMBER
v_cur OUT type_cur -- 返回但钱页数据记录
);
END PKG_PLATFORM;
// 存储包的存储过程主体
CREATE OR REPLACE PACKAGE BODY XXDBNAME.PKG_PLATFORM
AS
PROCEDURE GET_NRU(
p_starttime VARCHAR2,
p_endtime VARCHAR2,
p_Result OUT NUMBER
)
IS
v_count number:=0;
BEGIN
select count(*) into v_count FROM R2B2_ACCOUNT_INFO where REGDATE > p_starttime and REGDATE <= p_endtime;
p_Result := v_count;
END GET_NRU;
PROCEDURE WEEKLY_MISSION
(
page IN NUMBER, -- 当前页
tblName IN varchar2, -- 要查询的吧表名,
wheres varchar2, -- WHERE 查询条件 AND 开头
pageSize IN NUMBER, -- 每页大小
totalRows OUT NUMBER, -- 总数据数量
v_cur OUT type_cur -- 返回但钱页数据记录
)
IS
v_sqls varchar2(500); --完整的分页查询语句
v_count NUMBER; -- 数据总的记录数
v_start_offset NUMBER; -- 分页查询的开始点
v_end_offset NUMBER; -- 分页查询的结束点
v_sql_base varchar2(500); -- 查询对象的sql语句
BEGIN
v_end_offset := page * pageSize + pageSize;
v_start_offset := v_end_offset -pageSize + 1;
-- IF tblName IS NULL then
-- tblName := 'XXDBNAME.XX_WEEKLY_MISSION';
-- END IF;
--
v_sql_base := 'select rownum rn, t.* from ' || tblName || ' t where 1=1'; -- 'select rownum RID, t.* from ' || tblName || ' t where 1=1' || wheres;
v_sqls := 'select count(1) from (' || v_sql_base || ')';
EXECUTE immediate v_sqls INTO v_count; -- totalPage = ceil(v_count/pageSize)
totalRows := v_count;
v_sqls := 'select * from (' || v_sql_base || ') where rn between ' || v_start_offset || ' and ' || v_end_offset;
OPEN v_cur FOR v_sqls;
END WEEKLY_MISSION;
END PKG_PLATFORM;
表结构
CREATE TABLE "XXDBNAME"."XX_WEEKLY_MISSION"
( "USN" NUMBER(10,0) NOT NULL ENABLE,
"WMUPDATETIME" VARCHAR2(14) NOT NULL ENABLE,
"WMID" NUMBER(10,0) NOT NULL ENABLE,
"GRADE" NUMBER(3,0) NOT NULL ENABLE,
"GROUPID" NUMBER(3,0) NOT NULL ENABLE,
"VALUE" NUMBER(10,0) NOT NULL ENABLE,
"STATE" NUMBER(3,0) NOT NULL ENABLE
) SEGMENT CREATION IMMEDIATE
PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255 NOCOMPRESS LOGGING
STORAGE(INITIAL 393216 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)
TABLESPACE "USERS" ;
CREATE INDEX "XXDBNAME"."XX_WEEKLY_MISSION" ON "XXDBNAME"."XX_WEEKLY_MISSION" ("USN")
PCTFREE 10 INITRANS 2 MAXTRANS 255 COMPUTE STATISTICS
STORAGE(INITIAL 262144 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)
TABLESPACE "USERS" ;