最近手头有个活儿,需要处理一批Oracle里的数据,不是简单查一下就行,得弄点计算,还得把结果存回去。这种时候就免不要写点PL/SQL代码块。
一开始想得挺简单,不就是处理数据嘛但马上就发现,中间过程得存好几个值,比如算出来的平均数,或者某个状态标识。这时候就得用上DECLARE
,这玩意儿就是用来在代码块里头临时声明变量用的。
我记得以前用过,就凭着记忆开始写。先来个DECLARE
,然后想着要个存数字的变量,叫v_count
,类型是NUMBER
。还要个存处理结果说明的,叫v_msg
,类型是VARCHAR2
,给它个长度200应该够。
开始动手写
我就这么写:
DECLARE
v_count NUMBER;
v_msg VARCHAR2(200);
BEGIN
-- 这里准备开始干活儿
SELECT COUNT() INTO v_count FROM my_table WHERE some_condition = 'Y';
IF v_count > 0 THEN
v_msg := '找到' v_count '条记录,准备处理。';
-- 下面是处理逻辑...
ELSE
v_msg := '没找到符合条件的记录。';
END IF;
-- 可能还得把v_msg记到日志表里
-- INSERT INTO log_table (log_message) VALUES (v_msg);
END;
写完感觉还行,逻辑挺顺的。然后就拿到SQLPlus或者PL/SQL Developer里面去跑。
遇到麻烦
结果,啪,报错! 屏幕上跳出来一堆红字,看着就头大。报的错好像是啥“符号遇到文件结尾”之类的,具体错误号记不清,反正就是语法不对。
我当时就纳闷,这结构不是很标准吗?DECLARE
开头,BEGIN
和END;
包着代码体,还有个斜杠表示结束。来来回回检查好几遍。
后来我把代码粘到文本编辑器里,一个字母一个标点地看。搞半天,发现问题出在哪儿么?
- 有时候是
END
后面那个分号忘写。这玩意儿特别容易漏。 - 还有一次,是声明变量的时候,比如
VARCHAR2(200)
,括号或者长度写错,或者干脆忘指定长度。 - 最坑的一次,是我在
DECLARE
和BEGIN
之间,不小心多个空行或者写个注释,结果也可能导致它解析出错。虽然注释一般没事,但格式稍微一乱就可能出问题。 - 还有就是变量赋值,PL/SQL里头赋值用的是,我有时候习惯性写成,这在
IF
判断里是对的,但在赋值语句里就不行。
解决和反思
这回遇到的具体问题,排查下来,真就是END
后面那个分号丢。加上之后,再跑,成!看着屏幕上显示“PL/SQL procedure successfully completed”,心里那叫一个舒坦。
通过这回折腾,我又体会一把写代码这事儿,真是细心活儿。尤其像Oracle的PL/SQL,语法要求挺严格的,一个标点符号,一个关键字顺序,都不能马虎。DECLARE
本身不难,就是用来声明接下来要用的“篮子”(变量)的,告诉数据库你要用多大的篮子(类型和大小),装啥东西(数据)。
但就这么个简单的开头动作,要是搞错,后面的活儿就全没法干。写这种代码块的时候,结构一定要清晰,标点符号千万看仔细。特别是从网上拷代码或者用代码生成工具的时候,更得留神检查一遍,别被坑。
现在弄完,记录一下这个过程,也算是给自己提个醒,以后再用DECLARE
的时候,多加小心!