如何编写INFORMIX的存储过程Word文档格式.docx
- 文档编号:19900984
- 上传时间:2023-01-12
- 格式:DOCX
- 页数:23
- 大小:29.67KB
如何编写INFORMIX的存储过程Word文档格式.docx
《如何编写INFORMIX的存储过程Word文档格式.docx》由会员分享,可在线阅读,更多相关《如何编写INFORMIX的存储过程Word文档格式.docx(23页珍藏版)》请在冰豆网上搜索。
prc_servernameoncq97data
prc_dbnamedev_data
prc_ownernamedevelop
prc_namewd_proc1
当修改wd_proc1,再次创建后,SYSPRC表中查不到此存贮过程的记录;
当执行存贮过程后,SYSPRC表中又出现该记录;
?
二、存贮过程的总体结构
存贮过程的输入、输出参数都必须显式给出;
--******创建TS表INSERT触发器的存贮过程******/
--功能:
根据TS表中处理单位的信息,在CL表中向相关单位
--生成一条或多条处理记录(每个单位一条记录,最多三个单位);
--传入参数:
dw,id,status,sign
DROPPROCEDUREti_ts_proc;
CREATEPROCEDUREti_ts_proc
(idchar(12),dwchar(9),statuschar
(1),signchar
(1))
DEFINEdddate;
DEFINEfirst_dwchar(3);
DEFINEsecond_dwchar(3);
DEFINEsql_err,isam_errINT;
DEFINEerrorchar(80);
--------出错处理----------------------
ONEXCEPTIONSETsql_err,isam_err,error
TRACE'
SQLerrno:
'
||sql_err;
ISAMerrno:
||isam_err;
errormessage:
||error;
ENDEXCEPTION
SETDEBUGFILETO'
/export/home/app180/debug_wd'
;
begintrace:
'
||current;
-------------------------------------
LETdd=TODAY;
DD='
||dd;
IFstatus>
2'
orsign='
1'
THEN
RETURN;
ENDIF;
lengthofdwis'
||length(dw);
Length(trim(dw))='
||length(trim(dw));
TRACEON;
LETdw=TRIM(dw);
IFlength(dw)>
1THEN
BEGIN
IFlength(trim(dw))=3THEN
insertintocl(id,dw,clsign)values(id,dw,'
);
ELIFlength(trim(dw))=6THEN
BEGIN
LETfirst_dw=substring(dwFROM1FOR3);
LETsecond_dw=substring(dwFROM4FOR3);
--变量,起始位,位长;
insertintocl(id,dw,clsign)values(id,first_dw,'
insertintocl(id,dw,clsign)values(id,second_dw,'
end
ELIFlength(trim(dw))=9THEN
begin
LETfirst_dw=dw[1,3];
--substring(dwFROM1FOR3);
LETsecond_dw=substring(dwfrom4for3);
LETfirst_dw=substring(dwfrom7for3);
ENDIF
TRACEOFF;
ENDPROCEDUREWITHLISTINGIN'
/export/home/app180/wd_listing'
--------------------------------------------------------------
--创建TS表INFORMIXTI-TSTRIGGER
把当前记录的值传递给存贮过程处理
DROPTRIGGERti_ts;
CREATETRIGGERti_tsINSERTONts
REFERENCINGNEWASpost
FOREACHROW
(EXECUTEPROCEDUREti_ts_proc(post.id,post.dw,post.status,post.sign)
);
三、存贮过程的语法
完整的语句:
存贮过程中(SQL或SPL语句)没有专门的续行符,一条完整的语句可放在连续(甚至不连续)的多行中,最后以分号结束。
对于SPL语句要特别注意语句完整性的概念。
如‘ONEXCEPTION…….ENDEXCEPTION;
’这些成对出现的语句,从表面上看它们是分开的,但实际上是一条完整的语句,因此只能有一个分号。
类似情形还有‘IF..…ELIF.…ELSE…ENDIF;
’、‘WHILE…..ENDWHILE;
’等。
存贮过程的流程控制语句
条件转移:
IF条件THEN
ELIF条件THEN
ELSE
ENDIF;
语句块:
BENIN与END封装了一系列语句,并指明在流程控制结构如IF……ELSE中作为整体来处理。
可以定义仅用于该语句块的变量;
语句块
END
变量:
通过DEFINE关键字声明、命名,并由SELECT命令或LET语句赋值。
变量的初值为NULL。
变量名可与数据字段名重复,
INFORMIX存贮过程中无显式游标操作:
DECLARECURSOR游标名FOR条件:
定义游标;
游标的类型有:
SELECT、INSERT、UPDATE、DELETE;
OPEN游标名:
按定义的条件打开游标工作区;
FETCH游标名INTO变量:
记录指针移向下一行,并将新行的数据赋给变量;
适用于SELECT类游标;
PUT游标名WITH:
工作区中加入新记录,适用于INSERT类游标;
CLOSE游标名:
关闭工作区,提交数据;
隐式游标操作:
FOREACHcursor_nameForSELECT..INTO..FROM..WHERE..
ENDFOREACH;
当要对记录集中的数据进行更改处理时,FOREACH后必须要加上游标名,然后使用UPDATE……WHERECURRENTOFcursor_name,则更改游标当前记录的值。
事务处理:
BEGINWORK;
COMMITWORK;
ROLLBACKWORK;
循环语句:
WHILE条件
ENDWHILE;
FOR变量=初值TO终值STEP步长|变量IN(,,)
ENDFOR;
EXITFOR/WHILE/FOREACH:
退出最近的一层循环,并使程序从循环外的下一语句继续运行;
CONTINUEFOR/WHILE/FOREACH:
跳出当前循环的的剩余部分,从下一循环的开始处继续执行;
定义时间类型,必须给出范围,如:
DEFINEbeg_timeDATETIMEyeartosecond;
调用远程表(在另外一个库中):
“库名:
表名”
ifnotexists(select*fromsysmaster:
systabnameswheretabname='
getpwd'
)then
trace'
视图getpwd不存在,应用程序不能正常运行!
return;
endif;
四、存贮过程的的异常处理和跟踪调试
存贮过程在运行中可能产生两类出错信息,一是由数据库服务器返回的语句异常,如执行删除操作不成功时要报错;
另外一种是用户在存贮过程中根据业务需求自定义的出错信息。
INFORMIX通过使用ONEXCEPTION语句来捕获存贮过程在运行中所产生的各种异常,并根据用户所编写的错误处理代码执行相应的操作。
具体来说,当出现错误时在SQL通讯区(SQLCA)将产生一个对应的错误代号,SPL解释程序从当前出错行由后向前查找ONEXCEPTION说明(如有多个ONEXCEPTION的嵌套情况),直至捕获到与此对应的错误号。
捕获错误后,首先复位错误号(经实际测试:
如果未捕获到对应的错误号,则中断本过程运行,将错误号带到上级程序进行处理),然后执行该错误号下的错误处理代码。
当代码执行完毕并且ENDEXCEPTION使用WITHRESUME关键字,自动重新执行出错语句之后的语句;
如果没有WITHRESUME,则退出当前的存贮过程;
EXCEPTION后的程序执行点:
●如果ONEXCEPTION语句在一个BEGIN…END块中,则错误处理完后,程序跳到END后的下一语句开始执行;
●如果ONEXCEPTION语句在一个循环中,如FOR,WHILE,FOREACH,则错误处理完后,程序直接从下一个循环开始执行;
●Ifnostatementorblock,butonlytheprocedure,containstheONEXCEPTIONstatement,theprocedureexecutesaRETURNstatementwithnoargumentstoterminate.Thatis,theprocedurereturnsasuccessfulstatusandnovalues.
--------测试EXCEPTION的嵌套--------------------------
createprocedurewd_test_multi_exce()returningvarchar(100);
definetmpvarchar(100);
begin
onexception
returntmp||"
returnoutside."
endexception;
lettmp="
raiseinside."
raiseexception-9997;
end;
iftmpisnullthen
raiseoutside."
end;
endprocedure;
运行结果:
(expression)raiseinside.returnoutside.
ContinuingExecutionAfteranExceptionOccurs
IfyoudonotincludetheWITHRESUMEkeywordinyourONEXCEPTION
statement,thenextstatementthatexecutesafteranexceptionoccursdepends
ontheplacementoftheONEXCEPTIONstatement,asthefollowingscenarios
describe:
nIftheONEXCEPTIONstatementisinsideastatementblockwitha
BEGINandanENDkeyword,executionresumeswiththefirst
statement(ifany)afterthatBEGIN...ENDblock.Thatis,itresumes
afterthescopeoftheONEXCEPTIONstatement.
nIftheONEXCEPTIONstatementisinsidealoop(FOR,WHILE,
FOREACH),therestoftheloopisskipped,andexecutionresumes
withthenextiterationoftheloop.
nIfnostatementorblock,butonlytheprocedure,containstheON
EXCEPTIONstatement,theprocedureexecutesaRETURNstatement
withnoargumentstoterminate.Thatis,theprocedurereturnsa
successfulstatusandnovalues.
ErrorsWithintheONEXCEPTIONStatementBlock
SQLCA的数据结构:
不管SQL语句执行情况如何,它总能返回一个结果代码,它反映数据库操作的执行情况以及对数据库的影响。
返回的结果在结构SQLCA(SQLCommunicationsArea)中,SQLCODE,SQLERRD,SQLWARN,SQLERRM;
使用DBINFO函数,判断查询是否成功,更改的记录数;
dbinfo(sqlerrd1),dbinfo(sqlerrd2)
出错处理的代码包含在ONEXCEPTION……….ENDEXCEPTION之中;
ONEXCEPTIONIN(-206,-300)SETSQL-ERR,ISAM-ERR,ERROR-DATA
SQL-ERR:
每条SQL语句执行后数据库均要返回一个系统号来说明执行的情况,<
0:
错误信息;
=0:
执行成功;
=100:
查询没有结果返回(NOTFOUND);
SET关键字的作用是把SQL的错误号赋给变量SQL-ERR,即把SQL通讯区(SQLCA:
SQLCOMMUNICATEAREA)中的SQLCODE数据域的值赋给变量,该变量必须是整型。
ISAM-ERR:
把数据库的故障号传给变量;
ERROR-DATA:
出错的详细信息,变量必须是字符类型(长度为75?
);
用户自定义的出错信息:
RAISEEXCEPTIONSQL-ERR,ISAM-ERR,ERROR-TEXT;
如:
RAISEEXCEPTION–9999,0,‘Youbroketherules。
’;
INFORMIX的系统出错号:
-239:
违反UNIQUE约束(如主键重等);
存贮过程的跟踪调试
INFORMIX对存贮过程的运行没有动态、实时的跟踪调试工具,也不能设置断点,只提供简单的输出信息的功能:
用TRACE指令把需要了解的信息写到用‘SETDEBUGFILETO文件名’所指定的文件中。
待程序运行后,打开该文件,就可了解到程序运行的情况。
如在存贮过程中加入如下语句,则一旦错误发生,错误信息就可写入文件,方便调试。
--------标准出错处理----------------------
ONEXCEPTIONSETsql_err,isam_err,error
SQLerrno'
ISAMerrno'
errormessageis“'
||error||’”’;
TRACE‘endrunningwitherror.’;
注意:
文件的权限,
存放目录必须是(启动DBACCESS目录下?
)登录用户的主目录下,否则报错:
-687:
Setdebugfilebeforetracingstoredprocedures.;
调试信息文件的格式:
$moredebug_wd
traceexpression:
1997-11-0316:
22:
09.000
DD=11/03/1997
lengthofdwis3
Length(trim(dw))=3
-206;
此三条记录是在ONEXCEPTION中给出的出错信息;
-111
cl_test
$
五、特殊类型存贮过程—-触发器
触发器是一种特殊类型的存贮过程,在用户插入、删除或更新数据时,发挥作用。
触发器的优点是它的自动性能,无论造成数据变化的原因是什么,都可触发存贮过程的执行。
注意,INFORMIX在任何触发器操作之前,检查相对完整性限制(主、外键约束条件)。
数据库相对完整性约束提供了维护数据完整性的简单方法。
触发器是一种数据库机制,在特殊事件发生时,自动执行一条SQL语句(不能执行较复杂语句,如SPL语句,必须用存贮过程的方法实现?
),以实现一定的功能。
触发器存贮于两个系统目录表:
SYSTRIGGERS和SYSTRIBODY中,其它字典表格存放在数据库服务器内存中。
在数据库服务器执行一条INSERT、UPDATE或DELETE语句之前,系统检查数据库服务器内存中的字典,查找该表的触发器及正在执行SQL语句类型。
如果触发器存在,则将其检索出来,优化,并由数据库服务器在恰当的时候执行。
INFORMIX三类触发:
指定事件发生之前(BEFORE)、指定事件触发每行数据后(FOREACHROW)、指定事件完成后(AFTER)。
创建一个触发器,需要注意以下几点:
触发器命名(CREATETRIGGERtrigger_name);
定义触发器事件,即表名和启动触发器操作的施加于表上的动作类型(UPDATE、INSERT、DELETEON表名);
定义触发时间点:
before,after,foreachrow
定义触发执行的SQL语句;
--droptriggerti_ts;
CREATETRIGGERti_tsINSERTONts
referencingnewaspost
foreachrow
在TRIGGER中可把当前记录的数据传给存贮过程,也可由存贮过程返回数据给当前记录中的部分字段(NontriggeringColumns)。
CREATETRIGGERupd_totpr
UPDATEOFquantityONitems
REFERNCINGOLDASpre_updNEWASpost_upd
FOREACHROW
(EXECUTEPROCEDUREcalc_totpr
(pre_upd.quantity,Post_upd.quantity,pre_upd.total
)INTOtotal_price
Thetotal_pricecolumnisupdatedforeachrowthatthetriggeringstatementaffects.
USINGtheWHENCondition
UPDATEOFqu
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 如何 编写 INFORMIX 存储 过程