INFORMIX-4GL实用手册(四)(1)

更新时间:2024-06-16 02:01:01 阅读量: 综合文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

?

Informix-SPL(过程)语法详解

Informix数据库用户一般都熟悉的使用SQL语句进行简单的查询和统计,而在Informix-Online的数据库服务器中提供了用结构化查询语言SQL语句和流程控制存储语言SPL创建存储例程,以减少Informix的处理。存储例程是SQL语句和SPL的集合。它们存放在数据库中,SQL语句会被分析.优化,在例程的执行中,高速缓存中会有一执行规划,使后续操作的执行速度很快。而单独的SQL语句只有在执行时才会被优化,并且存储例程可以被不同的开发工具调用(4GL、ESQL/C、POWERBUILDER.DELPHI),在SELECT语句中也调用过程。例程调试简单,不必重新编译应有软件包。在例程创建时Informix查询处理器会分析它,并产生一执行规划,永久存放于SPROCEDURES.SYSPROBODY.和SYSPROPLAN中,其后例程按此规划执行,由于大部分查询处理已经完成,存储例程可以在瞬间执行完毕。由于存储例程所具有的优越性,它已成为进行Informix数据库核心开发的有力工具,掌握它对Informix的开发人员有积极意义,现将我在实际工作中使用的语法和例子详解于下,疏漏和错误请来信指教。

1.创建和执行例程

①.创建例程语法:

CRAETEPROCEDURE[OWNER.]PROCEDURE_NAME(参数1参数类型=[DEFAULT],参数2参数类型=[DEFAULT],参数n参数类型=[DEFAULT])

RETURNING值1类型,值2类型,值n类型;

<......>语句体;ENDRPOCEDURE

例程大小不可超过64K,这包括所有的SQL.SPL.空格.跳格符,例程名最多18个字符,并在数据库中唯一存在,语句间用\分隔,例程只能在当前数据库中创建,例程创建后是一标准

执行模板块,可在不同的应有中对其调用,这对开发不同版本的应用将更为便利。例:

createprocedure\

definerev_rev_item_codevarchar(2,0);

definerev_p_rev_datedate;

defineacc_rec_prem_nodecimal(8,2);definerev_p_rev_amtdecimal(10,2);definerev_I_info_branchvarchar(6,0);definerev_I_info_appl_nodecimal(8,0);definerev_I_info_datedate;definerev_o_rev_datedate;

definerev_o_rev_amtdecimal(10,2);

defineacc_ac_rev_amntdecimal(10,2);

defineacc_rec_prem_datedate;

beginwork;

foreachcur_revforselectI_info_appl_branch,I_info_appl_no,I_info_date,

o_rev_date,o_rev_amtintorev_I_info_branch,

rev_I_info_appl_no,rev_I_info_date,rev_o_rev_date,rev_o_rev_amtfromrev_rec_tblwhere

(rev_item_code=\

p_rev_amt=0and(I_info_appl_noisnotnullor

I_info_dateisnotnull);

selectmax(rec_prem_acc_no)intoacc_rec_prem_nofromrec_prem_accwhereI_info_appl_branch=rev_I_info_branch

andI_info_appl_no=rev_I_info_appl_no

andI_info_date=rev_I_info_date

ando_rev_date=rev_o_rev_date

andrev_item_code=\

ac_rev_amnt=rev_o_rev_amt;

selectdate(rec_prem_date)intoacc_rec_prem_date

fromrec_prem_accwhereI_info_appl_branch=rev_I_info_branch

andI_info_appl_no=rev_I_info_appl_no

andI_info_date=rev_I_info_date

ando_rev_date=rev_o_rev_date

andrev_item_code=\

ac_rev_amnt=rev_o_rev_amtand

rec_prem_acc_no=acc_rec_prem_no;

selectac_rev_amntintoacc_ac_rev_amnt

fromrec_prem_acc

whereI_info_appl_branch=rev_I_info_branch

andI_info_appl_no=rev_I_info_appl_no

andI_info_date=rev_I_info_date

ando_rev_date=rev_o_rev_date

andrev_item_code=\

andrec_prem_acc_no=acc_rec_prem_no

andac_rev_amnt=rev_o_rev_amt;

ifacc_ac_rev_amntisnulloracc_rec_prem_dateisnullthen

continueforeach; endif;

updaterev_rec_tbl

setp_rev_date=acc_rec_prem_date,

p_rev_amt=acc_ac_rev_amnt

whereI_info_appl_branch=rev_I_info_branch

andI_info_date=rev_I_info_date

andI_info_appl_no=rev_I_info_appl_no

ando_rev_date=rev_o_rev_date;

endforeach;

commitwork;

endprocedure;

②.执行例程语法:

A):在dbaccess中

EXECUTEPROCEDUREDBNAME@SERVER_NAME:例程名(参数1,参数2,.....)用这种方法可对例程进行调试。

B):在Informix-4GL中

PREPAREPREPSTATTEMENTFROM\例程名

(?,?,?,...)

DECLAREP_CURSSURSORFORPREPSTMT

OPENP_CURSUSING参数1,参数2,....

FETCHP_CURSINTO返回值1,返回值2,...

CLOSEP_CURS

当应用程序不支持EXECUTPROCEDURE语法,则需使用PREPARE命令,如INFORMIX-4GL中,而使用INFORMIX-NEWEAR则无此限制,需注意的是PREPARE语句中变量用?号代替,其个数要与例程的参数个数和类型一致,返回值也是一样。

C):在Informix-ESQL/C中

EXECSQLEXECUTEPROCEDURE例程名(参数1,参数2,...)INTO(返回值1,返回值2,...)在EC5.0或更高版本可使用EXECUTEPROCEDURE语法,在ESQL/C中宿主变量用于想存储例程传递值,同时也接收返回值.

D):在POWERBUILDER中

DECLARE逻辑名PROCEDUREFOR例程名(:参数1,:参数2:...)INTO:返回值1,:返回值2,..USING事物名

EXEC例程名(:参数1,:参数2,.....)

PB要求为例程制定逻辑名,以后的SQL语句将以逻辑名为准指向后台数据库例程,当例程即便没有参数也必须有小扩号.

2.流程控制语言

在过程中也提供了其他语言具备的流程控制语言,完成循环判断和分类处理的能力,主要有:①.IF....ELIF.....ELSE.....ENDIF例:

CRAETEPROCEDURESTR_COM(STR1CHAR(20),STR2CHAR(20))

RETURNINGINT;

DEFINERELINT;

IFSTR1>STR2THEN--当STR1>STR2REL=1

LETREL=1;

ELIFSTR2>STR1THEN--当STR2>STR1REL=-1

LETREL=-1; ELSE

LETREL=0;--当STR1=STR2REL=0 ENDIF

RETUENREL;

ENDPROCEDURE

当IF的条件为一个SQL语句如SELECT时需用扩号,并且返回值为单值。

②.FOR.....ENDFOR

例:FORINDEXIN(20TO30STEP2,100TO200STEP10)

--执行代码

ENDFOR

FOR的条件可以是变量,常量或一个SQL语句的返回值

③.WHILE.......ENDWHILE

当WHILE的条件为TRUE时执行WHILE后的语句,为FALSE退出循环。

例:WHILEI<10

INSERTINTOTBB_1VALUES(I);

LETI=I+1;

ENDWHILE;

④.FOREACH........ENDFOREACH

该语句较为特别FOREACH循环能够声明并打开游标,读取记录行,并关闭游标.其完整语法:

FOREACH游标名[WITHHOLD]SELECT字段名INTO变量FROM

TABLEWHERE条件;

ENDFOREACH

FOREACHEXECUTEPROCEDURE例程名(参数1,参数2,..)INTO 变量

ENDFOREACH

该循环中语句的执行次数与SELECT和EXECUTEPROCEDURE语句返回的行数一样多。如果FOREACH语句中包含一条EXECUTEPROCEDURE,则循环停止的条件为:

.执行了不带任何参数的RETURN语句

.执行了ENDPROCEDURE

如果没有返回行数据,则不再执行循环中的语句。存储例程中不允许使用滚动游标。

当使用WITHHOLD时,更新游标将放置更新锁,使其他过程无法更新该行,直至事物完成,当在FOREACH循环的语句块中的UPDATE或DELETE有

WHERECURRENTOF短语,则存储例程会自动使用更新游标

例1:BEGINWORK;

FOREACHCUR_1FORSELECTDATEINTOV_DATEFROMTABLE

IFV_DATEISNULLTHEN

DELETEFROMTABLEWHERECURRENTOFCUR_1; ENDIF;

ENDFOREACH;

COMMITWORK;

例2:FOREACHEXECUTEPROCEDUREBAR(10,20)INTOI

INSERTINTOTABLE1VALUES(I)

ENDPROCEDURE

⑤.CONTINUE适用语句(FORWHILEFOREACH)将执行传递给下一次循环⑥.EXIT

适用语句(FORWHILEFOREACH)

从循环中退出

例:FORJ=1TO20

IFJ>10THEN

CONTINUEFOR; ENDIF

LETI,S=J,0;

WHILEI>0

LETI=I-1;

IFI=5THEN

EXITFOR; ENDIF

ENDWHILE

ENDFOR

3.变量的定义与赋值

存储例程中使用的变量必须在例程开始处用DEFINE语句定义,变量的数据类型为除SERIAL以外的任意类型,如果定义一个TEXT或BYTE类型的变量,则该变量为指向数据的指针。传递给程序的变量必须在CRAETEPROCEDURE语句中定义。DEFINE也可使用LIKE语句。变量类型缺省为局部变量,也可引用GLOBAL定义全局变量,全局变量在例程间保持它的值,直至会话结束。用户必须为每一个定义的全局变量赋缺省值,缺省值仅在例程第一次引用该全局变量时使用,以后的例程将会忽略其缺省值。

例:CREATEPROCEDURESP1()

RETURNINGINT;

DEFINEGLOBALIINTDEFAULT1;

LETI=I+1;

RETURNI;

ENDPROCEDURE

CRAETEPROCEDURESP2()

RETURNINGINT;

DEFINEGLOBALIINTDEFAULT4;

LETI=I+1;

RETURNI;

ENDPROCEDURE

当执行顺序为SP1,SP2返回值3,当执

本文来源:https://www.bwwdw.com/article/8nz3.html

Top