PostgreSQL创建存储过程提示WITH附近语法错误如何解决
PostgreSQL存储过程创建报错原因定位
直接报错原因
你写的存储过程完全不符合PostgreSQL PL/pgSQL的语法结构:
$body$标记的存储过程体开头直接写WITH RECURSIVE,没有按照规则先写DECLARE块(声明游标、变量),再写BEGIN块(存放执行逻辑),同时你错误地把DECLARE、游标声明语句塞到了CTE的语法结构中,导致SQL解析器在第二行碰到WITH时无法识别,直接抛出语法错误。
其他核心语法错误
- 缺少存储过程语言声明:
CREATE PROCEDURE语句末尾没有加LANGUAGE plpgsql指定存储过程使用的语言 - WITH RECURSIVE语法完全错误:CTE结构内只能写查询语句,不能放游标声明、DECLARE关键字,且你写的递归逻辑缺失初始查询、JOIN条件为空,同时使用了Oracle专属的
LEVEL关键字,PostgreSQL无此内置变量 - 游标声明位置错误:游标必须统一放在
DECLARE块中声明,不能放在业务逻辑、CTE语句内部 - 游标重复声明:
c01/c02/c03游标均被重复定义 - 查询语句语法残缺:你写的游标查询中
IS NOT NULL条件没有对应的WHERE关键字,语句结构断裂 - 存储过程无结束标记:整个过程体没有
END关键字闭合逻辑块
修正思路
1. 先补全存储过程基础结构
CREATE OR REPLACE PROCEDURE dpk_mc_tr.dpr_mc_tr_cmo_med_form_arc_inf ( in_usercode text, in_usersess text, in_compcode text, in_stardate text, in_stopdate text, in_sericate text, in_matccate text, in_seritycd text, in_matycode text, in_venucode text, in_teamcode text, in_drsmflag text, in_daynight text, in_telecast text, in_progname text, out_code INOUT numeric ) AS $body$ DECLARE -- 所有游标、变量统一在此处声明 -- 示例拆分逗号包裹[]的入参,不需要写复杂的递归+正则,直接用内置函数即可 CURSOR c01 FOR SELECT DISTINCT trim('[]' FROM unnest(string_to_array(in_sericate, ','))) AS sericate; CURSOR m01 FOR SELECT sysofcde sericate FROM sycodmas WHERE compcode = '001' AND modlcode = 'MM' AND syhrdcde = 'SRC' UNION ALL SELECT 'X' sericate; -- 剩下的c02、m02、c03按照相同规则声明即可 BEGIN -- 此处写你的业务逻辑,包括游标遍历、数据处理、结果返回等 -- 示例:成功执行后给返回参数赋值 out_code := 0; END; $body$ LANGUAGE plpgsql;
2. 优化入参拆分逻辑
你原来拆分逗号分隔带[]的入参逻辑过于冗余,PostgreSQL可以直接用string_to_array拆分数组、unnest转成行、trim去掉[]符号,完全不需要写递归CTE+正则。
内容的提问来源于stack exchange,提问作者unknown
相关产品推荐
相关产品推荐

