使用Oracle存储过程与CodeIgniter备份表遇ORA-00922错误求助
解决ORA-00922: missing or invalid option错误的方案
我帮你定位到了问题的根源,主要是Oracle存储过程里的两处语法错误导致的ORA-00922,另外CodeIgniter模型里还有个潜在的连接管理问题,下面一步步给你修正:
1. 修复Oracle存储过程的核心语法问题
你的存储过程有两个关键错误,直接触发了语法报错:
- 存储过程定义语句写错了:
CREATE OR PROCEDURE漏掉了REPLACE关键字,Oracle要求创建或替换存储过程时必须用CREATE OR REPLACE PROCEDURE。 - 动态建表的SQL拼接时,新表名和
AS之间没有空格,导致Oracle解析时把表名和AS当成了一个整体,完全识别不了合法的表名格式。
修正后的存储过程代码:
CREATE OR REPLACE PROCEDURE PROC_BACKUP_DATA1 (p_tablename VARCHAR2, out_message OUT VARCHAR2) AS BEGIN -- 重点:在生成的表名后面加个空格,再拼接AS关键字 EXECUTE IMMEDIATE 'CREATE TABLE ROADMAP_'|| TO_CHAR(SYSDATE,'yyyyMMddHH24miss') || ' AS SELECT * FROM ' || p_tablename; COMMIT; out_message := 'Data berhasil di backup'; EXCEPTION WHEN OTHERS THEN ROLLBACK; out_message := SQLERRM; DBMS_OUTPUT.PUT_LINE(out_message); END; /
提示:结尾的
/是Oracle执行存储过程定义的结束符,执行的时候一定要加上,不然存储过程不会被正确编译。
2. 修正CodeIgniter模型里的连接管理问题
你的CI模型里调用了oci_close($this->db->conn_id),这会手动关闭CodeIgniter框架管理的数据库连接——而CodeIgniter默认用单例模式管理连接,手动关闭后后续的数据库操作会直接失败,建议把这行代码删掉。
修正后的CI模型代码:
public function fbackup(){ $p_tablename="ZZZ_REKAP_ROADMAP"; $stid=oci_parse($this->db->conn_id, 'begin PROC_BACKUP_DATA1(:p_tablename, :out_message); end;'); oci_bind_by_name($stid, ':p_tablename', $p_tablename); oci_bind_by_name($stid, ':out_message', $out_message, 40); oci_execute($stid); print"$out_message\n"; oci_free_statement($stid); // 移除oci_close,让CodeIgniter自己管理连接的生命周期 }
3. 验证修复效果
- 先在Oracle客户端(比如PL/SQL Developer、SQL*Plus)里执行修正后的存储过程,确保存储过程编译通过,没有报错。
- 访问CI的
backup控制器方法,触发备份操作。 - 去Oracle里检查是否生成了类似
ROADMAP_20240520153020格式的备份表,同时查看页面输出的out_message是否为成功提示。
这样就能彻底解决你遇到的ORA-00922错误啦。
内容的提问来源于stack exchange,提问作者Fajar Ardiansyah
相关产品推荐
相关产品推荐

