开发规范说明书V10.doc_第1页
开发规范说明书V10.doc_第2页
开发规范说明书V10.doc_第3页
开发规范说明书V10.doc_第4页
开发规范说明书V10.doc_第5页
已阅读5页,还剩17页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1. 数据库开发规范1.1. 数据库表命名数据库的表名采用以下规则进行编排:(1) 表的命名规则前缀2位_类别3位_自定义部分。前缀第一位说明(h 大额,b 小额,e 网银,m 信息管理,f 备付金)前缀第二位说明 (x 外联,w web,c 核心)(2) 为了移植方便,适应其他多种数据库的环境,要求表名长度=16个英文字符。(3) 自定义部分不允许用拼音进行编排。 类别划分类别说明类别码控制类ctl流水类jnl明细类dtl登录簿rgt标准数据std统计类cnt日终day举例说明:操作员表:hc_ctl_teller1.2. 日期类型的问题Oracle数据库和informix数据库不同,不支持自1899-12-31以来的long型日期处理。但oracle和informix均支持字符串型的日期处理。因此要求,对应于数据库表中日期型字段的定义,全部定义为STRING类型。即:char变量名9 ;处理日期的函数(包括年月日转换、计算前后N天的日期、日期之间的天数等通过包装函数进行统一处理)。 格式为:YYYYMMDD1.3. 数据库错误宏定义对于数据库操作出现的错误号,除了系统统一定义的宏以外,其他错误号禁止直接用数字描述。以下均是错误的写法:if ( SQLCODE = -1 )if ( SQLCODE = 1403 ) 正确的写法应该为:if ( SQLCODE = SQLDUPDATA )if ( SQLCODE = SQLNOTFOUND ) 应用中常用的数据库错误编号的规范:#defineSQLNOTFOUND1403/* 记录未找到 */#defineSQLDUPDATA-1/* 记录重复 */#defineSQLNOTABLE-942/* 表不存在 */#defineSQLNOINDEX-1418/* 索引不存在 */#defineSQLNULLDATA-1405/* 数据有空值 */这些宏定义将定义在系统公用的头文件(db_oracle.h)中。1.4. 字符串的使用问题SQL语句中的字符串全部采用 作为标识符,禁止使用 “”等作为标识符。取字符串的第M位到第N位,禁止使用 field_nameM,N,请使用SUBSTR()函数。SUBSTR(字段名,起始位,长度)多个字符串链接请用“ | ”。例如:取帐号的第1位到第3位,第5位到第6位拼成串SUBSTR(ACCT_NO,1,3) | SUBSTR(ACCT_NO,5,2)禁止使用VARCHAR类型的字段作为数据库表结构的索引字段。规定只能如果是字符串类型的字段要求作为索引的话,只能使用 CHAR 类型。数据库表中为CHAR和VARCHAR的字段,在用SELECT或FETCH取出值后,一定要去掉尾部的空格。原则上谁取出谁去掉空格。1.5. Proc语句规范1.5.1. SELECT语句EXEC SQL SELECT field_name1, field_name2 ,field_nameNFROMtable_name_list , WHERE cond1ANDcond2GROUPBY field_nameX, field_nameYORDERBY grouplist ;建议一行不超过5个字段1.5.2. DECLARE语句EXEC SQL DECLARE cursor_name FOR SELECTfield_name1, field_name2 , field_nameNFROMtable_name_list , WHERE cond1ANDcond2GROUPBY field_nameX, field_nameYORDERBY grouplist ;1.5.3. UPDATE语句EXEC SQL UPDATE table_name SETfield_name1 = :val1 ,field_name2 = :val2 , field_nameN = :valN WHEREcond1ANDcond2 ;1.5.4. INSERT语句简单的INSERT语句:EXEC SQL INSERT INTO table_name VALUES (:stru_var) ;复杂的INSERT语句:EXEC SQL INSERT INTO table_name VALUES (:val1, :val2, valN, :valX, . :valY) ;1.5.5. FETCH语句简单的FETCH语句:EXEC SQL FETCH curs_name INTO :stru_var ;复杂的FETCH语句:EXEC SQL FETCH curs_name INTO:val1 , ., :valN ,:valX, , :valY ;EXEC SQL fetch 必须遵循 EXEC SQL fetch curs_name into .的格式规范。游标使用完毕后要用EXEC SQL close 关闭。informix释放游标EXEC SQL free 在Oracle中不需要。1.5.6. Update语句标准的update语句格式:EXEC SQL update table_name setfield_name1 = :val1 ,field_name2 = :val2 , field_nameN = :valNwhere 以下格式严禁使用:EXEC SQL update table_name set * = :struct_valwhere 即使Oracle支持该种语法,也会存在效率的问题! Oracle不支持以下语法:EXEC SQL update table_name set( field_name1, field_name2, field_nameN ) =( :val1 , :val2 , :valN )where. 请使用以下语法进行update操作:EXEC SQL UPDATE table_name SETfield_name1 = :val1 , field_name2 = :val2 , field_nameN = :valN WHERE cond1ANDcond2 ;1.5.7. prepare 语句prepare 动态语句在应用中会大量使用到,因为有些语句不能事先嵌入到PRO*C程序中,要根据程序运行情况或用户从输入设备上的输入,来确定执行的SQL语句。动态SQL1: 不能是查询(SELECT)语句,并且没有宿主变量. 用法:拼一句动态SQL语句,并用EXECUTE IMMEDIATE执行,如: strcpy(str_sql,“DELETE FROM test001 WHERE name=username”); EXEC SQL EXECUTE IMMEDIATE :str_sql; 动态SQL2: 不能是查询(SELECT)语句,并且输入的宿主变量数目是知道的, 用法:拼一句动态SQL语句,用PREPARE,EXECUTE语句执行. strcpy(sqlstring, DELETE FROM test WHERE test_col = :K1 ); EXEC SQL PREPARE sqlproc FROM :sqlstring; EXEC SQL EXECUTE sqlproc USING :emp_number ; 动态SQL3: 用于创建动态查询, 并且要查询的字段以及输入的宿主变量数目是知道的 用法: 拼一句动态SQL语句,用PREPARE分析该语句,定义一个CURSOR进行取值 strcpy(sql,select user_name from test WHERE test_col :K1 ); EXEC SQL PREPARE sqlproc FROM :sql; EXEC SQL DECLARE cur_user_name CURSOR FOR sqlproc; EXEC SQL OPEN cur_user_name USING : AA; while(1) EXEC SQL FETCH cur_user_name into :ora_id; if (sqlca.sqlcode 与.除外,其前后不用放置任何空格)。一元操作符与操作数之间不用放置任何空格。如下所示:A=B + C ;(错误!)A = B + C ;(正确)A+ ;2.2.6.3. if语句一个简单的if语句:if () . 另外,条件很长的情况下,需要分行进行处理,并通过适当的()来避免条件的二义性。例如:if ( sPack-flag = 2 & ( acct_attr = 40 | acct_attr = 44 | acct_attr = 46 ) )2.2.6.4. if-else语句在一个简单的if-else组合中,关键字else应当新起一行,并与if保持同一缩进层次。if () . else .else-if链接形式:if () . else if () .else if () .2.2.6.5. for语句for语句书写按照以下格式:for ( I=0 ; IMAX_NUMBER ; I+ ) ; ;如果for语句内容太多,要分为多行进行处理:for ( i=0 ; strcmp(funcname,MID_FUNC_TABi.funcname) & strcmp(XXXXXXXXXX,MID_FUNC_TABi.funcname) ; i+ );禁止写成一行。2.2.6.6. while语句一个while语句块必须用花括号括起来(即使该块仅含单独一个语句):例如:while ( ) ;2.2.6.7. do-while语句(本项目不使用此模式)一个do/while语句块必须用花括号括起来(即使该块仅含单独一个语句):格式:do ; while ( ) ;2.2.6.8. switch语句switch语句书写遵循以下原则:(1) 保留字case与default应当与保留字switch保持一个缩进层次,并且后跟一空格(并非一制表符),然后才是常量表达式。与某种情况(case)相对应的代码块应当再缩进一个层次。(2) 每种情况(case)单独成一行。(3) 对应于一个代码块的多种情况(case)不要用空行分隔开。(4) 如果在某个代码块中省略了break语句,使得程序的执行继续到下一个代码块,则必须在该代码块之后放置一块注释以指明这一点,参见下例。(5) 必须用break语句明确表示某个代码块结束后,程序的执行转移到整个switch语句之后。即便是一个switch语句的最后一种情况(case或default),也应如此。(6) 如果一个case语句的最后一条语句是return,为了增加程序的可阅读性,后面也必须写上break语句。以下是switch语句的模板程序:switch ( iHitKey )case UP :case LEFT :. .break ;case DOWN :. ./* 此处没有break,参照ENTER选项继续执行 */case ENTER :. .break ;default :. .break ;2.2.7. makefile书写规范2.2.7.1. 总体原则原则上按照开发目录划分,每个组的库文件目录(libsrc)全集中在一个目录下。(1) 全系统采用统一的名称:“ makefile”。不允许再出现 make_lib、make_test、make_server 等各种各样的makefile文件名。(2) 增加了部分proc选项,对其功能说明如下:【unsafe_null=yes dbms=v8】:在数据库记录有空值的情况下,select语句会将SQLCODE置成1405,此选项是屏蔽掉oracle的该功能。【lines=yes】:编译时增加_LINE_的处理,否则运行时_LINE_指的是预编译后的(.c)程序的行数。【def_sqlcode=yes】:编译时会自动增加以下宏定义:#define SQLCODE sqlca.sqlcode可以在程序中直接使用宏SQLCODE来判断数据库出错号。2.2.7.2. 编译库文件书写规范在OracleTUXEDO环境下,编译库文件,makefile规范如下:.SUFFIXES:.pcAPPINCLUDE=$(PUBDIR)/includeOBJLIB = PLTpublib.o PLTerrlog.o PLTpubtran.o PLTsecure.o PLTshmopt.o PLTsemopt.o PLTmsgopt.o PLTmsglock.o PLTstddata.o PLTtrslib.o PLTtrschk.o PLTdynlib.o PLTdbaction.o PLTmsgtran.o PLTpackmsg.o PLTunpackmsg.o PLTselftran.o PLTmidtran.o .c.o:cc -c -g -DDEBUG -I$(APPINCLUDE) -I$(TUXDIR)/include $.pc.o:proc unsafe_null=yes dbms=v8 def_sqlcode=yes lines=yes include=$(APPINCLUDE) include=$(TUXDIR)/include ltype=NONE $cc -c -g -DDEBUG -I$(APPINCLUDE) -I$(TUXDIR)/include $*.crm -f $*.call: libplatform.alibplatform.a : $(OBJLIB)echo Compile $ . .ar -rv $ $?mv $ $(PUBDIR)/lib2.2.7.3. 编译TUXEDO-SERVER书写规范在OracleTUXEDO环境下,编译TUXEDO的SERVER,makefile书写模板如下:.SUFFIXES:.pc .oAPPINCLUDE=$(PUBDIR)/includeLINKLIB=-L$(PUBDIR)/lib -lplatform.c.o:cc -c -g -DDEBUG -I$(APPINCLUDE) -I$(TUXDIR)/include $.pc.o:proc unsafe_null=yes dbms=v8 def_sqlcode=yes lines=yes include=$(APPINCLUDE) include=$(TUXDIR)/include ltype=NONE $cc -c -g -DDEBUG -I$(APPINCLUDE) -I$(TUXDIR)/include $*.crm -f $*.cOBJSERV = PLTservmain.o PLTtrsmain.o PLTtrsinit.o PLTdynapi.o PLTtrspack.o PLTtrsunpack.o PLTtrsctl.o PLTtrscomm.o PLTtrslog.o PLTtrssave.o PLTverictl.o PLTpkginit.o PLTtuxmain.oall: pltserverpltserver:$(OBJSERV)buildserver -s PLATFORM -o $ -f $? $(LINKLIB)mv $ $(PUBDIR)/binecho t$ load success .n3. Tuxedo开发规范3.1. Service的命名在Tuxedo系统中会有数量很多的service,为了便于监控及后期维护因此请参照以下命名原则:服务名单一,不要出现以下命名ServAB , ServABC. 3.2. Service的注释(1) 版本号码(2) 该Service的名称(3) 该Service实现的功能(4) 入口参数(5) 出口参数(6) 其它需要列出来的说明例子:3.3. Server与Service划分原则上一个server对应一个service,每个Service负责一个独立的业务流程(1) Server的分组Tuxedo连接资源是以GROUPS组来划分,当应用需要连接不同数据库时,应将Server划分为不同的组。(2) Request/Response类型的Service要和会话Service分开在不同的Server中会话方式和Request/Response方式是两种互斥的通讯方式,通过*SERVER节点中CONV=Y或者N来决定使用的类型,所以这两种类型的Service要分开放在不同的Server里面。(3) 执行时间相近的Service放在同一个Server里面首先每个Service的执行时间是不同的。对于单线程的Server,Service的执行是串行的。例如有两个Service,A和B, A的执行速度是B的十倍的话,那么当一个B在执行时就会有10个A在排队,因此考虑到执行效率,是需要把执行时间相似的Service放在同一个Server里面的。(4) 避免死锁的情况发生死锁情况一:一个Server中的Service A去调用同在一个Server中的Service B。例如Service A去调用Service B的时候,Service A还没有执行完,它会等待Service B的返回结果。 但是Service B不能执行,因为Server还处于执行Service A的状态。最终Service A超时而出错。死锁情况二:两个Server中的Service互相调用。例如有Server1和Server2,Server1中的Service A去调用Server2中的Service X。同时Server2中的Service Y去调用Server1中的Service B。这种情况发生的死锁和第一种情况相识,都是因为进程只能串行实行Service导致的。第一种情况是比较容易察觉的,但是第二种情况就不大容易察觉。1.1. Tuxedo程序书写规范1.1.1. Client端例子1.1.1.1. 基本处理流程1.连接应用程序:调用tpinit连接应用程序; int tpinit( TPINIT tpinfo );2.分配发送包、返回包缓冲区:调用tpalloc给发送包、返回包分配缓冲区; char* tpalloc( char* type, char* subtype, long size );3. 填写发送包数据:4.调用服务请求:tpcall调用服务请求; ret = tpcall( TOUPPER, sendbuf, NULL, &rcvbuf, &rcvlen, 0 );5. 处理返回包数据: 6.释放已申请的发送包、返回包缓冲区:调用tpfree释放已申请的缓冲区; void tpfree( char *ptr );7.断开与应用程序的连接:调用tpterm断开与应用程序的连接。 int tpterm( void );1.1.2. Server端例子服务名(TPSVCINFO *rqst)int i;for(i = 0; i len-1; i+) rqst-datai = toupper(rqst-datai);tpreturn(TPSUCCESS, 0, rqst-data, 0L, 0);1.1.3. FML操作函数1.1.3.1. 向FML中加入数据/* 功能概述 向FML中加入数据 * 入口参数 f 待处理的FML * fldid FML域标识 * . 数据,一般为一个参数,仅当域类型为CARRAY时需要两个 * 出口参数 f 处理后FML * 返回值 0 成功 * -1 失败 */int FmlAdd(FBFR32 *f,FLDID32 fldid,.)1.1.3.2. 拼接两个FML/* 功能概述 连接FML * 入口参数 src源FML * 出口参数 dest目的FML(原数据保留,新增重复域往后编号) * 返回值 0成功 * -1失败 */int FmlCat(FBFR32 *dest,FBFR32 *src)1.1.3.3. 复制FML缓冲区数据/* 功能概述 复制FML * 入口参数 src源FML * 出口参数 dest目的FML(原数据被覆盖) * 返回值 0成功 * -1失败 */int FmlCpy(FBFR32 *dest,FBFR32 *src)1.1.3.4. 在FML中修改数据/* 功能概述 在FML中修改数据 * 入口参数 f 待处理的FML * fldid FML域标识 * fldocc

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论