Chinaunix首页 | 论坛 | 博客
  • 博客访问: 104573057
  • 博文数量: 19283
  • 博客积分: 9968
  • 博客等级: 上将
  • 技术积分: 196062
  • 用 户 组: 普通用户
  • 注册时间: 2007-02-07 14:28
文章分类

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类: DB2/Informix

2008-03-19 20:55:23

第十二章  报表设计
12-1 报表的架构 
首先建立一个不可卷动的 cursor.再利用循环连接 start report、 output to report、和 finish report 叙述输出数据至报表。 
§例: 

   DEFINE   prt_file         CHAR(14) 

   LET  prt_file = "??????.report" 
   START REPORT report_name TO prt_file 
   FOREACH p_curs INTO p_person.* 

       ... 

     OUTPUT TO REPORT  report_name(p_person.*) 

     IF  INT_FLAG  THEN 

         ERROR  " 列表中断 !!!" 

         LET  INT_FLAG  = FALSE 

         EXIT FOREACH 

     END IF 

   END FOREACH 


   FINISH  REPORT  report_name 

   IF  INT_FLAG  THEN 

       RETURN 

   END IF 


REPORT report_name(r_person) 

   ... 

END REPORT 

12-2 REPORT 叙述 

<语法格式> 

REPORT report_name(argument_list) 

   DEFINE 

   [OUTPUT] 

       [PAGE   LENGTH integer]      default 66 行 

       [TOP    MARGIN integer]      default 上面留 3 行 

       [BOTTOM MARGIN integer]      default 上面留 3 行 

       [LEFT   MARGIN integer]      default 左边边缘留 5 格空白 

   [ORDER BY sort_list|ORDER EXTERNAL BY sort_list] 

   formAT 

       [FIRST PAGE HEADER ...] 

       [PAGE HEADER ...] 

       [PAGE TRAILER ...] 

       [ON EVERY ROW ...] 

       [ON LAST ROW ...] 

       [BEFORE GROUP OF...] 

       [AFTER GROUP OF...] 


END REPORT 


若使用 ORDER BY 则所欲排列的变量必须出现在 REPORT 的argument_list中。 



12-3 报表数据之选择 

欲得到报表中所须之资料,必须使用 SELECT 叙述配合 cursor 和程序循环来选取报表中所须之资料。 

§例: 

DEFINE query_1     CHAR(500) 

DEFINE query_stat  CHAR(500) 

CONSTRUCT BY NAME query_1 ON ssaltab.work_ty, ssaltab.disins_ty, 

                             ssaltab.dept_ty, ssaltab.unit_ty, 

                             ssaltab.pos_ty,  ssaltab.seq_num 


LET query_stat = " SELECT idno,     dept_ty,   pos_ty, "

                 "        emp_name, paypnt,    rank_name,"

                          ... 

                 " FROM ssaltab  WHERE  ", query_1 CLIPPED, 

                 " AND work_ty = ""1"""

                 " ORDER BY dept_ty,pos_ty" 

                 "[ORDER BY 2,3]" 


   PREPARE excutable_stam  FROM query_stat 

   DECLARE p_curs CURSOR FOR excutable_stam 

   ... 


   FOREACH p_curs INTO p_person.* 

       ... 

   END FOREACH 



12-4 执行报表 


<语法格式> 

START REPORT report_name 

   begin loop 

       OUTPUT TO REPORT report_name(variable_list) 

   end   loop 

FINISH REPORT report_name 


.以 start report 来执行所要的报表程序,且须在传送资料至报表的执行循环之 前。 

.output report to 中的 variable_list 必须和 reort 中 argument_list的变量个数和资料型态必须相等。 

.当程序循环完成传送资料至报表后,最后必须加上 finish report 做为结束。 


§例: 

DECLARE p_curs CURSOR FOR 

   ... 

START REPORT report_name TO prt_file 

FOREACH p_curs INTO p_person.* 

   ... 

   OUTPUT TO REPORT  report_name(p_person.*) 

       IF  INT_FLAG  THEN 

           ERROR  " 列表中断 !!!" 

           LET  INT_FLAG  = FALSE 

           EXIT FOREACH 

       END IF 

END FOREACH 

FINISH  REPORT  report_name 

IF  INT_FLAG  THEN 

   RETURN 

END IF 


REPORT report_name(r_person) 

  ... 

END REPORT 



12-5 报表的格式化设计 


在 format 区间设计的报表可以使用达到7种型式的控制区段,这7种型式可以任意的组合次序出现。 


12-5-1 报表页的表头和表尾 


.FIRST PAGE HEADER:若要在报表第一页显示表头或不同文字内容时。 

.PAGE HEADER:若要在报表每一页的顶端显示表头或特定文字内容时。 

.PAGE TRAILER:若要在报表每一页的尾端显示特定文字内容时。 


§例: 

PAGE HEADER 

   PRINT COLUMN 2, "科目别:",r_person.proj_name CLIPPED 

   PRINT COLUMN 10, r_person.dept_name CLIPPED, 

         COLUMN 30, r_persson.emp_name CLIPPED, 

         COLUMN 50, r_persson.stuff_num 

   PRINT COLUMN 02, "制表日期:",YEAR(TODAY)-1911 USING "##"

                    "/",MONTH(TODAY) USING "&#","/"

                    DAY(TODAY) USING "&#",""

         COLUMN 70, PAGENO USING "第###&页" 

   SKIP 5 LINE 


§例: 

PAGE TRAILER 

   PRINT COLUMN 05,"======================================" 

   PRINT COLUMN 05,"** 本页小计 ** "

         COLUMN 39,         r_b       USING "##,###"
 COLUMN 47,         r_m       USING "##,###"

         COLUMN 55,         r_s       USING "##,###"

         COLUMN 39+off_set, s_b       USING "##,###"

         COLUMN 47+off_set, s_m       USING "##,###"

         COLUMN 55+off_set, s_s       USING "##,###" 

   SKIP 1 LINE 

   PRINT COLUMN 05,"** 本页累计 ** "

         COLUMN 38,         r_b + s_b USING "###,###"

         COLUMN 46,         r_m + s_m USING "###,###"

         COLUMN 54,         r_s + s_s USING "###,###" 

   PRINT COLUMN 05,"======================================" 



12-5-2 打印每一列资料值 


<语法格式一> 

[EVERY ROW] 

若使用 every row 叙述时,系统会以内定格式将形式参数字段印出 


§例: 

REPORT report_name(r_person) 


DEFINE r_person  RECORD 

                 emp_name    LIKE ssaltab.emp_name, 

                 idno        LIKE ssaltab.idno, 

                 unit_name   LIKE ssaltab.unit_name 

                END RECORD 

 formAT 

     EVERY ROW 

END REPORT 

结果: 

    r_person.emp_name   大梦 

    r_person.idno       8888888 

    r_person.unit_name  INformIX-4GL开发联盟 

    ... 

<语法格式二> 

[ON EVERY ROW] 

REPORT report_name(r_person) 

DEFINE r_person RECORD 

                 pos_name     LIKE ssaltab.pos_name, 

                 emp_name     LIKE ssaltab.emp_name, 

                 rank_name    LIKE ssaltab.rank_name, 

                 basepay      LIKE ssaltab.basepay, 

                 jobpay       LIKE ssaltab.jobpay, 

                 spepay       LIKE ssaltab.spepay 

               END RECORD 

... 


OUTPUT 

 formAT 

     ON EVERY ROW 

       SKIP 1 LINE 

       PRINT COLUMN  02, r_person.pos_name  CLIPPED, 

             COLUMN  21, r_person.emp_name  CLIPPED, 

             COLUMN  31, r_person.rank_name CLIPPED, 

             COLUMN  51, r_person.basepay   USING "##,###,###"

             COLUMN  61, r_person.jobpay    USING "##,###,###"

             COLUMN  71, r_person.spepay    USING "##,###,###" 

... 

END REPORT 



12-6 资料分类 


当某些数据域位内容相同的归类在一起时(经由 sort),若希望系统在每类资料的开始或结尾分别作那些事时,则必须使用 before group of 或 after group of 叙述。 


<语法格式> 

[BEFORE GROUP OF variable_name] 

[AFTER  GROUP OF variable_name] 


.before group of 或 after group of 只能处理经过排列后的资料。 

.before group of 或 after group of 的变量,仅能使用 report 中的 argument_list ,同时必须和 select 中的 order by 子句里的变量名称或order external by 里的变量名称要相同。 

.假设 order by 变量的顺序为先 a,再排 b,最后排 c.则处理各组变量的顺序如下所示: 


before group of a 

   before group of b 

       before group of c 

           on every row  ... 

       after group of c 

   after group of b 

after group of a 



§例: 

ORDER EXTERNAL BY r_person.disins_ty, r_person.dept_ty 


     BEFORE GROUP OF r_person.disins_ty 

       LET  line_count = 0 

       SKIP TO TOP OF PAGE 


     BEFORE GROUP OF r_person.dept_ty 

       LET  line_count = 0 

       SKIP TO TOP OF PAGE 


     ON EVERY ROW 

       IF  line_count >= 32 THEN 

           LET  line_count = 0 

           SKIP TO TOP OF PAGE 

       END IF 

       LET line_count = line_count + 1 

       SKIP 1 LINE 

       PRINT COLUMN  02, r_person.pos_name  CLIPPED, 

             COLUMN  21, r_person.emp_name  CLIPPED, 

             COLUMN  31, r_person.rank_name CLIPPED, 

             COLUMN  51, r_person.basepay   USING "########"

             COLUMN  61, r_person.jobpay    USING "########"

             COLUMN  71, r_person.spepay    USING "########" 

             ... 

     AFTER GROUP of r_person.dept_ty 

       IF  line_count >= 32 THEN 

           LET  line_count = 0 

           SKIP TO TOP OF PAGE 

       END IF 

       LET line_count = line_count + 1 

       SKIP 1 LINE 

       PRINT COLUMN  22, "部别小计"

             COLUMN  51, GROUP SUM(r_person.basepay)USING "########"

             COLUMN  61, GROUP SUM(r_person.jobpay) USING "########"

             COLUMN  71, GROUP SUM(r_person.spepay) USING "########" 

       ... 

     AFTER GROUP of r_person.disins_ty 

       IF  line_count >= 32 THEN 

  LET  line_count = 0 

           SKIP TO TOP OF PAGE 

       END IF 

       LET line_count = line_count + 1 

       SKIP 1 LINE 

       PRINT COLUMN 22, "计划小计 ", GROUP COUNT(*) USING "####笔"

             COLUMN 51, GROUP SUM(r_person.basepay) USING "########"

             COLUMN 61, GROUP SUM(r_person.jobpay)  USING "########"

             COLUMN 71, GROUP SUM(r_person.spepay)  USING "########"

             ... 



12-7 报表的加总和计算列数 


<语法格式> 

[ON LAST ROW] 


§例: 

   ON LAST ROW 

       IF  line_count >= 32 THEN 

           LET  line_count = 0 

           SKIP TO TOP OF PAGE 

       END IF 

       LET line_count = line_count + 1 

       SKIP 1 LINE 

       PRINT COLUMN  22, " 总  计  "

             COLUMN  51, SUM(r_person.basepay)USING "########"

             COLUMN  61, SUM(r_person.jobpay) USING "########"

             COLUMN  71, SUM(r_person.spepay) USING "########" 

       FOR i = line_count TO 32 

           SKIP 2 LINE 

       END FOR 

       PRINT COLUMN   2, "校长"

             COLUMN  20, "会计主任"

             COLUMN  40, "人事主任"

             COLUMN  60, "总务长"

             COLUMN  80, "出纳主任"

             COLUMN 100, "覆 核"

             COLUMN 120, "制 表" 

       SKIP TO TOP OF PAGE 



12-8 使用于报表的算术数学函数 


.SUM(expression):在报表中计算总值 

.MAX(expression):在报表中印出最大值 

.MIN(expression):在报表中印出最小值 

.AVG(expression):在报表中计算平均值 

.PERCENT(*)     :在一组资料计算所有列的百分比 

.COUNT(*)       :在报表中计算所存在的列数 



12-9 PRINT 叙述 


<语法格式> 

PRINT [COLUMN NUMBER,] variable [,| |;] [WORDWRAP RIGHT MARGIN NUMBER] 

§例: 

PRINT "计划小计 ", GROUP COUNT(*) USING "####笔" 

PRINT COLUMN 22, "计划小计 ", GROUP COUNT(*) USING "####笔" 


§例: 

MAIN 

   CALL test_wordwrap() 

END MAIN 


FUNCTION test_wordwrap() 

   START REPORT report_wordwrap TO "wordwrap.report" 

     OUTPUT TO REPORT  report_wordwrap() 

   FINISH  REPORT  report_wordwrap 

END FUNCTION 


REPORT report_wordwrap() 

define str char(200) 

OUTPUT 

 PAGE LENGTH 66 

 TOP MARGIN 0 

 LEFT MARGIN 0 

 BOTTOM MARGIN 0 


 formAT 

     ON EVERY ROW 

LET str = "12345678901234567890123456789012345678901234567890"

         "12345678901234567890123456789012345678901234567890" 

       PRINT COLUMN  61, str wordwrap right margin 70 

END REPORT 

结果: 

                                                 1234567890 

                                                 1234567890 

                                                 1234567890 

                                                 1234567890 

                                                 1234567890 

                                                 1234567890 

                                                 1234567890 

                                                 1234567890 

                                                 1234567890 

                                                 1234567890 



§例: 

LET salary1 = 123 
LET salary2 = 1234 
LET salary3 = 12345 
LET salary4 = 123456 
PRINT  salary1 USING "#####" 
PRINT  salary2 USING "#####" 
PRINT  salary3 USING "#####" 
PRINT  salary4 USING "#####" 

结果:   123 

       1234 

      12345 

      ***** 
12-10 REPORT 范例 

12-10-1 产生邮局或银行的磁盘文件 
REPORT report_disk(d_person) 
DEFINE d_person  RECORD 
                 account_no  LIKE ssaltab.account_no, 
                 emp_name    LIKE ssaltab.emp_name, 
                 idno        LIKE ssaltab.idno, 
                 unit_name   LIKE ssaltab.unit_name, 
                 salary      LIKE ssaltab.basepay 
               END RECORD 
OUTPUT 
 PAGE LENGTH 1 
 TOP MARGIN 0 
 LEFT MARGIN 0 
 BOTTOM MARGIN 0 
 formAT 
     ON EVERY ROW 
           PRINT COLUMN 2,cnt USING "&&&&&&"
                         " 03"
                         d_person.account_no USING "&&&&&&&"
                         " SA C "
                         d_person.salary     USING "&&&&&&&&" 
END REPORT 

12-10-2 产生一般报表 
REPORT report_name(r_report) 
DEFINE r_report  RECORD LIKE purchasetab.* 
OUTPUT 
 PAGE LENGTH 65 
 TOP MARGIN 0 
 LEFT MARGIN 0 
 BOTTOM MARGIN 0 
 ORDER EXTERNAL BY r_report.yy,r_report.seq_num,r_report.purchase_num 
 formAT 
     PAGE HEADER 
         PRINT COLUMN   1,"~it24fkw2z2x0d0;" 
         PRINT COLUMN   1,"91TALK ",r_report.yy USING "&&","-"
                        r_report.seq_num USING "&&&&"
                         " 计算器用费支用明细表" 
         PRINT COLUMN   1,"~it24fmg2x0d0;" 
         SKIP 1 LINE 
         PRINT COLUMN  46, "打印日期: ",sys_date,"   " 
         PRINT COLUMN   2, "计划编号: ",p_report.plan_no CLIPPED, 
               COLUMN  46, "执行期限: ",p_report.beg_date," 起至 "
                           p_report.end_date 
         SKIP 1 LINE 
         PRINT COLUMN   2, "主持教授: ",p_report.leader, 
               COLUMN  46, "执行系所: ",p_report.unit_name CLIPPED 
          SKIP 2 LINE 
         PRINT COLUMN   1,"╒══════════════════════════════════════╕" 
         PRINT COLUMN   1, ""
               COLUMN   3, "请购单编号"
               COLUMN  17, "科   目"
               COLUMN  30, "异动日期"
               COLUMN  63, "请购金额"
               COLUMN  79, "" 
      BEFORE GROUP OF r_report.seq_num 
         LET  line_count = 0 
         LET  page_no    = 0 
         SKIP TO TOP OF PAGE 
ON EVERY ROW 
   IF  line_count >= 30 THEN 
   PRINT COLUMN   1,"╘══════════════════════════════════════╛" 
       LET  line_count = 0 
       SKIP TO TOP OF PAGE 
   END IF 
   LET line_count = line_count + 1 
   PRINT COLUMN   1,"├──────────────────────────────────────┤" 
   PRINT COLUMN   1,""
         COLUMN   3, r_report.purchase_num  USING "&&&&&&&&"
         COLUMN  17, r_report.itemb_name CLIPPED,   
         COLUMN  30, r_report.upddate USING "yy.mm.dd"
         COLUMN  60, r_report.purchase_fee  USING "$$$,$$$,$$#"
         COLUMN  79,"" 
AFTER GROUP OF r_report.seq_num 
   IF  line_count >= 30 THEN 
       LET  line_count = 0 
       SKIP TO TOP OF PAGE 
   END IF 
   LET line_count = line_count + 1 
   PRINT COLUMN  1,"└──────────────────────────────────────┘" 
   SKIP 2 LINE 
   PRINT COLUMN  1,"*****************************************************************************" 
   PRINT COLUMN  2, "可使用金额:",p_report.net_budget, 
         COLUMN 31, "总计:"
         COLUMN 35,GROUP COUNT(*) USING "####","  项"
         COLUMN 60,GROUP SUM(r_report.purchase_fee) USING "$$$,$$$,$$#" 
END REPORT

第十三章  视窗设计 
13-1 窗口的宣告 
<语法格式> 

OPEN  WINDOW  窗口名称  AT  ROW,COLUMN 

                            WITH {integer ROWS,integer column|  FROM  "form_file"

                            [ATTRIBUTE (attribute_list)] 

CLOSE  WINDOWS 窗口名称 

§例: 

OPEN  WINDOW  w_user  AT 2,3  WITH  3 ROWS, 19  COLUMNS 

... 

CLOSE  WINDOW  w_user 
OPEN  WINDOW  w1  AT  2,2  WITH  1 ROWS, 46  COLUMNS 

                                                                      ATTRIBUTES(BORDER,REVERSE) 

          PROMPT "      请输入还原密码: " FOR  res_word 

CLOSE  WINDOW  w1 


OPEN  WINDOW  pay101f  AT  6,30  WITH  form  "pay101f" 

                                                                      ATTRIBUTES(BORDER) 

... 

CLOSE  WINDOW  pay101f 



DATABASE  payroll 

SCREEN 



  请更正或新增眷属名单 : 

       姓名       身份证字号 
       ====       ========== 
1. [f         ]  [g         ] 
2. [f         ]  [g         ] 
3. [f         ]  [g         ] 
4. [f         ]  [g         ] 
5. [f         ]  [g         ] 
6. [f         ]  [g         ] 
7. [f         ]  [g         ] 



END 

TABLES 
sfamilytab 
ATTRIBUTES 
f  =  formONLY.family_name      , AUTONEXT  
g  =  formONLY.family_idno      , UPSHIFT,AUTONEXT  
END 
INSTRUCTIONS 
SCREEN RECORD s_dispitem[7] 

 ( family_name,family_idno) 

DELIMITERS " " 

END 


13-2 窗口的属性 
┌──────────────────────────┐ 
│    属  性                 内 定 值                 │ 
├──────────────────────────┤ 
│    BORDER              没有边界                    │ 
├──────────────────────────┤ 
│    COLOR               彩色屏幕之下窗口的颜色      │ 
├──────────────────────────┤ 
│    REVERSE             没有反白                    │ 
├──────────────────────────┤ 
│    PROMPT LINE         FIRST                       │ 
├──────────────────────────┤ 
│    MESSAGE LINE        FIRSTR+1                    │ 
├──────────────────────────┤ 
│    form LINE           FIRSTR+2                    │ 
├──────────────────────────┤ 
│    COMMENT LINE        LAST                        │ 
└──────────────────────────┘ 
 
窗口的大小与位置不可超出屏幕范围,且没有 ERROR LINE 这个属性,因 ERROR将显示的地址是针对全屏幕而言。 


13-3 窗口的边界 BORDER 
 
当使用者想要在窗口的四周画下边界,以区别窗口背景的文字内容时,必须使用BORDER 属性,系统会以内定的边界,如-表示水平,|表直线,和以+表四周边界转角。 

§例: 

OPEN  WINDOW  w1  AT  2,2  WITH  1  ROWS,46  COLUMNS  ATTRIBUTES(BORDER,REVERSE) 

CLOSE WINDOW  w1 

13-4 窗口的提示行和讯息行 

§例: 

OPEN   WINDOW w1  AT  4,25  WITH  15  ROWS, 30  COLUMNS 

        ATTRIBUTES(BORDER,PROMPT LINE LAST,MESSAGE LINE LAST-1) 

CLOSE  WINDOW  w1 


提示行会出现在窗口的最后一列,也就是相对应于屏幕的第18列.而讯息行则出现在窗口的倒数最2列,也就是相对应于屏幕的第17列。 



13-5 窗口的画面格式行 


§例: 


OPEN  WINDOW  pay101f  AT  6,30  WITH  form  "pay101f" 

                                                     ATTRIBUTES(BORDER,form LINE 3) 

CLOSE  WINDOW  pay101f 


form pay101f 此时会在窗口的第3列开始显示,也就是相对应于屏幕的第9列。 


13-6 关闭窗口 


<语法格式> 

CLOSE  WINDOW  window_namw 


§例: 

CLOSE WINDOW pay101f 


13-7 在窗口中显示讯息与交谈示输入 


§例: 

OPEN  WINDOW  w1  AT  2,2  WITH  1 ROWS, 46  COLUMNS 

                                                                           ATTRIBUTES(BORDER,REVERSE) 

          PROMPT "      请输入还原密码: " FOR  res_word 

CLOSE  WINDOW  w1 


§例: 

INPUT BY NAME p_ssaltab.* 

   ... 

   BEFORE FIELD unit_name 

       OPEN WINDOW w1 AT 2,2 WITH 5 ROWS, 40 COLUMNS ATTRIBUTES(BORDER) 

           MESSAGE "请输入服务单位名称 " 

           SLEEP 1 

       CLOSE WINDOW w1 

   AFTER  FIELD unit_name 

       ... 

END INPUT 



13-8 在窗口中显示菜单 


§例: 

OPEN  WINDOW  w_user AT 2,3 WITH  3 ROWS, 19 COLUMNS 


   MENU "人事薪资" 

        COMMAND "1.新增" 

            CALL psn_modify(1) 

        COMMAND "2.查询" 

            CALL sub_menu(2) 

        COMMAND "3.更正" 

            CALL sub_menu(3) 

        COMMAND "4.删除" 

            CALL sub_menu(4) 

        COMMAND "0.结束" 

            EXIT MENU 

   END MENU 


CLOSE WINDOW w_user 


13-9 清除窗口的内容 


<语法格式> 

CLEAR WINDOW window_name 


§例: 

CLEAR WINDOW w1 



13-10 多重窗口 


系统欲显示多重窗口时,会以 STACK 来维护所开启的窗口。 

§例: 

INPUT BY NAME curr_ssaltab.proj_ty, 

             curr_ssaltab.dept_ty, 

             ... 

             WITHOUT DEFAULTS 

FROM         ssaltab.proj_ty, 

             ssaltab.dept_ty, 

             ... 

    AFTER FIELD proj_ty 

        SELECT sprojtab.proj_name 

          INTO curr_ssaltab.proj_name 

          FROM sprojtab 

         WHERE sprojtab.proj_ty = curr_ssaltab.proj_ty 

        IF  SQLCA.SQLCODE != 0 THEN 

            CALL pay101_window(1) 

            LET curr_ssaltab.proj_ty = p_sprojtab.proj_ty 

            DISPLAY BY NAME curr_ssaltab.proj_ty 

        END IF 


    AFTER FIELD dept_ty 

        SELECT sdeptab.dept_name 

          INTO curr_ssaltab.dept_name 

          FROM sdeptab 

         WHERE sdeptab.proj_ty = curr_ssaltab.proj_ty 

           AND sdeptab.dept_ty = curr_ssaltab.dept_ty 

        IF  SQLCA.SQLCODE != 0 THEN 

            CALL pay101_window(1) 

            LET curr_ssaltab.proj_ty = p_sprojtab.proj_ty 

            CALL pay101_window(2) 

            LET curr_ssaltab.dept_ty = p_sdeptab.dept_ty 

            DISPLAY BY NAME curr_ssaltab.dept_ty 

            DISPLAY BY NAME curr_ssaltab.proj_ty 

        END IF 


    AFTER FIELD ... 



FUNCTION pay101_window(tab_option) 

   DEFINE tab_option    SMALLINT 

   DEFINE Is_Continue   CHAR(1) 

   DEFINE curr,sa_curr,i,j,p_item  SMALLINT 


   OPEN WINDOW pay101w AT 4,39 WITH form "pay101w" ATTRIBUTE(BORDER) 


   DISPLAY  "CTRL-C:放弃 PF3:下页 PF4:上页 " AT  2,4 


   CASE tab_option 

       WHEN 1 

             LET pay101_clause = " SELECT proj_ty, proj_name "

                                 "   FROM sprojtab "

                                 "  ORDER BY 1 " 

       WHEN 2 

             LET pay101_clause = " SELECT (proj_ty*100+dept_ty), dept_name "

                                 "   FROM sdeptab "

                                 "  WHERE sdeptab.proj_ty = ? "

                                 "  ORDER BY 1 " 

       WHEN 3 

             ... 

   END CASE 


   PREPARE pre_pay101 FROM pay101_clause 

   DECLARE pay101_cursor SCROLL CURSOR FOR pre_pay101 


   IF  tab_option = 2 THEN 

       OPEN pay101_cursor USING curr_ssaltab.proj_ty 

   ELSE IF  tab_option = 3 THEN 

            OPEN pay101_cursor USING curr_ssaltab.proj_ty, 

                                     curr_ssaltab.dept_ty 

        ELSE 

            OPEN pay101_cursor 

        END IF 

   END IF 


   FETCH FIRST pay101_cursor INTO p_101tab.* 


   IF  SQLCA.SQLCODE = NOTFOUND  THEN 

       ERROR "无符合资料" 

       RETURN 

   END IF 


   LET curr = 1 

   LET Is_Continue = TRUE 



   WHILE Is_Continue 

       FOR i = 1 TO 9 

           FETCH ABSOLUTE curr pay101_cursor INTO p_101tab.* 

           IF  SQLCA.SQLCODE <> 0 THEN 

               ERROR "档案终点" 

               EXIT FOR 

           END IF 

           IF  i = 1  THEN 

               FOR j = 1 TO 9 

                   DISPLAY "" TO s_dispitem[j].no 

                   DISPLAY "" TO s_dispitem[j].name 

               END FOR 

               LET sa_curr = 0 

           END IF 

           LET sa_curr = sa_curr + 1 

           DISPLAY p_101tab.no   TO s_dispitem[sa_curr].no 

           DISPLAY p_101tab.name TO s_dispitem[sa_curr].name 

           LET curr = curr + 1 

       END FOR 


       INPUT p_item FROM  item 


       AFTER FIELD item 

           IF  p_item >= 1 AND p_item <= sa_curr THEN 

               LET  j = curr - sa_curr + p_item - 1 

               FETCH ABSOLUTE j pay101_cursor INTO p_101tab.* 

               LET Is_Continue = FALSE 

               EXIT INPUT 

           ELSE 

               LET p_101tab.no = "" 

               ERROR "所选择无资料" 

           END IF 


           ON KEY(INTERRUPT) 

              LET Is_Continue = FALSE 

              LET  p_101tab.no = "" 

              EXIT INPUT 


           # next page 

           ON KEY(F3) 

              EXIT INPUT 

           # up page 

           ON KEY(F4) 

              IF  curr - sa_curr - 9 > 0 THEN 

                  LET curr =  curr - sa_curr - 9 

                  EXIT INPUT 

              ELSE 

                  ERROR "档案终点" 

              END IF 


       END INPUT 


   END WHILE 



   CLOSE pay101_cursor 

   LET INT_FLAG = FALSE 

   CLOSE WINDOW pay101w 

   CASE tab_option 

       WHEN 1 

           LET p_sprojtab.proj_ty   = p_101tab.no[1,1] USING "&" 

           LET p_sprojtab.proj_name = p_101tab.name 

       WHEN 2 

           LET p_sdeptab.proj_ty    = p_101tab.no[1,1]  USING "&" 

           LET p_sdeptab.dept_ty    = p_101tab.no[2,3]  USING "&&" 

           LET p_sdeptab.dept_name  = p_101tab.name 

       WHEN 3 

           ... 

   END CASE 

END FUNCTION 



§例: form  pay101f 


SCREEN 


          选择序号:[a] 

序号  代  号       名        称 

==== ======== ====================== 
 1.  [f01   ] [f02                 ] 
 2.  [f01   ] [f02                 ] 
 3.  [f01   ] [f02                 ] 
 4.  [f01   ] [f02                 ] 
 5.  [f01   ] [f02                 ] 
 6.  [f01   ] [f02                 ] 
 7.  [f01   ] [f02                 ] 
 8.  [f01   ] [f02                 ] 
 9.  [f01   ] [f02                 ] 

END
ATTRIBUTES 
 a   = formONLY.item,AUTONEXT; 
 f01 = formONLY.no,  NOENTRY; 
 f02 = formONLY.name,NOENTRY; 
END 
INSTRUCTIONS 
  DELIMITERS "  " 
SCREEN RECORD s_dispitem[9] (no,name) 
END 
使 用 者:大梦    更正:   2.下一笔  4.最后一笔  5.更正  0.结束 
现在时间:14:44:02 
程序名称:pay101    ★ ★ 人事基本文件作业 ★ ★ 
身分证字号:[Q220610508]教职员工号:[8306001] 姓    名:[张景云    ] 
员工编号  :[2][03][27][770][030]            服务单位:[材料系    ] 
核薪职等  :[A0412 ][荐十二              ]   职    称:[组员                ] 
本    薪  :[245] 功俸:[  0]                 本俸级别:[ 24] 
补助费级别:[27]                             主管级别:[ 0] 
资薪单位  :[1][校本部  ]                    职    别:[5][职员      ] 
异动日期  :[83/06/01]                       到职日期:[83/06/01] 
保险别    :[1][公保      ] 保险号:[       ] 福利互助:[1] 
眷保总人数:[0] 眷保人数 :[0]                扶养人数:[ 0] 
合并眷口数:[0]                              房屋津贴:[0][无] 
研究费    :[0]                              学人房贴:[0][无  ] 
银行帐号  :[71305]                          公教帐号:[     ] 


使 用 者:大梦    更正:   2.下一笔  4.最后一笔  5.更正  0.结束 
现在时间:14:42:31                 +-------------------------------------+ 
程序名称:pay101                   |   ★ ★ 人事基本尝                  | 
                                  |   CTRL-C:放弃 PF3:下页 PF4:上页     | 
                                  |                                     | 
身分证字号:[Q220610508]教职员工号:|           选择序号:                 | 
员工编号  :[2][  ][27][770][030]  |                                     | 
核薪职等  :[A0412 ][荐十二        | 序号  代  号       名        称     | 
本    薪  :[245] 功俸:[  0]       | ==== ======== ======================| 
补助费级别:[27]                   |  1.   1        一般行政管理         | 
资薪单位  :[1][校本部  ]          |  2.   2        各学院教学           | 
异动日期  :[83/06/01]             |  3.   3        各研究所教学         | 
保险别    :[1][公保      ] 保险号:|  4.   4        学生训导及军训       | 
眷保总人数:[0] 眷保人数 :[0]      |  5.   5        图书典藏及阅览       | 
合并眷口数:[0]                    |  6.   6        电算中心             | 
研究费    :[0]                    |  7.   7        夜间部               | 
银行帐号  :[71305]                |  8.   8        空中商专             | 
                                  |  9.                                 | 
                                  |                                     | 
                                  +-------------------------------------+ 

院, 室, 处 

使 用 者:大梦    更正:   2.下一笔  4.最后一笔  5.更正  0.结束 
现在时间:14:42:31                 +-------------------------------------+ 
程序名称:pay101                   |  ★ ★ 人事基本尝                   | 
                                  |   CTRL-C:放弃 PF3:下页 PF4:上页     | 
                                  |                                     | 
身分证字号:[Q220610508]教职员工号:|           选择序号:                 | 
员工编号  :[2][  ][27][770][030]  |                                     | 
核薪职等  :[A0412 ][荐十二]       | 序号  代  号       名        称     |
本    薪  :[245] 功俸:[  0]       | ==== ======== ======================| 
补助费级别:[27]                   |  1.   201      文学院               | 
资薪单位  :[1][校本部  ]          |  2.   202      理学院               | 
异动日期  :[83/06/01]             |  3.   203      工学院               | 
保险别    :[1][公保      ] 保险号:|  4.   204      管理学院             | 
眷保总人数:[0] 眷保人数 :[0]      |  5.   205      医学院               | 
合并眷口数:[0]                    |  6.   206      共同学科             | 
研究费    :[0]                    |  7.   209      技工工友             | 
银行帐号  :[71305]                |  8.                                 | 
                                  |  9.                                 | 
                                  |                                     | 
                                  +-------------------------------------+ 


院, 室, 处 

13-10 设定目前的窗口 

<语法格式> 

CURRENT WINDOW IS window_name 
  

§例: 
   OPEN WINDOW w_user AT 2,3 WITH 3 ROWS, 19 COLUMNS 
   DISPLAY " 使 用 者:",sys_user_name  AT 1,1 
   DISPLAY "现在时间:"                 AT 2,2 
   DISPLAY "程序名称:",sys_program     AT 3,2 
   CALL curr_time("U"
   OPEN WINDOW w_menu AT 2,23 WITH 3 ROWS, 56 COLUMNS 
   DISPLAY "★ ★ ", sys_heading CLIPPED, " ★ ★ " AT 3,1 
   OPEN WINDOW w_form AT 5,3 WITH 19 ROWS, 76 COLUMNS ATTRIBUTE(PROMPT LINE LAST) 
   OPEN form form_option FROM sys_program 
   DISPLAY form form_option 

FUNCTION curr_time(next_window) 
   DEFINE next_window     CHAR(1) 
   DEFINE now_time        DATETIME  HOUR TO SECOND 
   CALL curr_window("U"
   LET now_time = CURRENT 
   DISPLAY now_time AT 2,11 
   CALL curr_window(next_window) 
END FUNCTION 

FUNCTION curr_window(which) 
   DEFINE  which   CHAR(1) 
   CASE which 
       WHEN "U" 
            CURRENT WINDOW IS w_user 
       WHEN "M" 
            CURRENT WINDOW IS w_menu 
       WHEN "F" 
            CURRENT WINDOW IS w_form 
   END CASE 
END FUNCTION 

第十四章  系统记录架构 
14-1SQLCA系统记录架构 
SQLCA(SQL Communication Access) 系由系统提供之系统记录架构,作为 back end 与 front end 之间沟通之用,当发生 I/O 状态时,系统会记录该状态于SQLCA 中,front end 即可依据其其内容得知 I/O 运作是否成功,再决定往后执行的步骤。 
SQLCA 为系统定义之 GLOBAL 变量,以下为其架构并介绍其内容与用途: 
DEFINE SQLCA RECORD 
          SQLCODE    INTEGER, 
          SQLERRM    CHAR(71), 
          SQLERRP    CHAR(8), 
          SQLERRD    ARRAY[6] OF INTEGER, 
          SQLAWARN   CHAR(8) 
END RECORD 
.SQLCODE :表示 I/O 的结果 
 0   表示 I/O 成功 
 100 表示 NOTFOUND 
 < 0 表示 I/O 失败 
.SQLERRM :保留未用 
.SQLERRP :保留未用 
.SQLERRD :为一个含有6个 INTEGER 之数组 
 SQLERRD[1]:保留未用 
 SQLERRD[2]:新增时 SERIAL 字段所传回之值 
 SQLERRD[3]:处理资料的笔数 
 SQLERRD[4]:查询时预估的 CPU COST 
 SQLERRD[5]:SQL指令之错误位移 
 SQLERRD[6]:最后一个 ROWID 值 
.SQLAWARN :为一个含有8个字符的字符串,以记录I/O时产生的警告讯息。若正确无误,则相对应之字符设定为空白,否则会被设定为"W"。 
   SQLAWARN[1]:若第2至第8字符中任意一个被设成"W",则此字符亦为"W",否则为空白。 
   SQLAWARN[2]:若资料太长而被截掉时,会被设成 "W"。 
   SQLAWARN[3]:若 aggregate function(如 SUM,AVG,MAX,MIN) 处理时遇到 NULL 值,则会被设成"W"。 
   SQLAWARN[4]:若查询时,若欲查询的字段数目和 INTO 之变量数目不合 时,会被设成 "W"。 
   SQLAWARN[5]:如转换 float 成 integer 时,则会被设成 "W"。 
   SQLAWARN[6]:保留未用 
   SQLAWARN[7]:保留未用 
   SQLAWARN[8]:保留未用 

14-2 SQLCA.SQLCODE 是否等于 STATUS ? 
因 sqlca.sqlcode 系用以沟通 front end 和 back end ,因此只有 I/O 发生时才会更改 sqlca ,同时 status 也被设定等于 sqlca.sqlcode 值。但若只是纯粹 front end 的动作(如 display),则只有 status 会被设定,而sqlca.sqlcode 则保持不变。为了避免错误,要注意下列两件事: 
.若要以 status 判断 I/O 是否成功,在 I/O 后立即判断 status,中间不可插入任何会更改 status 之指令。 
.若要以 sqlca.sqlcode 判断 I/O 是否成功,在 I/O 后除非有新的 I/O 发生,不然允许先执行其它 frint end 之指令,以后再予以判断。 
CREATE DATABASE dbtest 
CREATE TABLE tab ( 
                   col1      serial(1000), 
                   col2      char(3), 
                   col3      smallint) 
 
假设 TABLE tab 已有3笔资料: 
      col1     col2     col3       (rowid)隐含字段 
      1000     AAA      (null)         1 
      1001     BBB      1000           2 
      1002     CCC      2000           3 

DATABASE dbtest 
MAIN 
   DEFINE io_tab RECORD 
          col1   like  tab.col1, 
          col2   like  tab.col2, 
          col3   like  tab.col3, 
          col4         integer   
   END RECORD 
   DEFINE total_col3   integer 
   DEFINE work_col2    char(2) 
   WHENEVER ERROR CONTINUE 

§例: 
   SELECT * 
     FROM tab 
    WHERE col2 = "BBB" 
  DISPLAY sqlca.sqlcode,sqlca.sqlerrd[6] 

结果:           0               3 

§例: 
   SELECT * 
     FROM tab 
    WHERE col2 = "DDD" 
   DISPLAY sqlca.sqlcode 
结果:          100 

§例: 
   SELECT SUM(col3) 
     INTO total_col3 
     FROM tab 
  DISPLAY total_col3,sqlca.sqlawarn  
结果:          300     W W 

因内含一个 null 值,所以第1,3位设定为 W 

§例: 
   SELECT * 
     INTO io_tab.* 
     FROM tab 
    WHERE col2 = "BBB" 
  DISPLAY sqlca.sqlcode,sqlca.sqlerrd[3],sqlca.sqlawarn  
结果:          0                1           W  W 
select variable_list 数目只有3个,但 io_tab 有4个,所以第1,4位设定为 W 

§例: 
   SELECT col2 
     INTO work_col2 
     FROM tab 
    WHERE col2 = "AAA" 
   DISPLAY sqlca.sqlcode,sqlca.sqlerrd[3],sqlca.sqlawarn  
结果:          0                1           WW 

因第3个字符被截掉,所以第1,2位设定为 W 
§例: 
   UPDATE tab 
      SET col3 = 1000 
   DISPLAY sqlca.sqlerrd[3] 
结果:          3 
因总共更正3笔资料 
§例: 
   INSERT INTO tab valueS(0,"DDD",3000) 
   DISPLAY sqlca.errd[2] 
结果:          103 
因总共更正3笔资料 
§例: 
   SELECT * 
     FROM tab 
    WHERE col1 = 999 
  DISPLAY status,sqlca.sqlcode 
结果:        100        100 

§例: 
   SELECT * 
     FROM tab 
    WHERE col1 = 999 
  DISPLAY "STATUS will be update !!" 
  DISPLAY status,sqlca.sqlcode 
结果:STATUS will be update !! 
              0        100 
此时 status 不再等于 sqlcode 
14-2 如何判断 I/O 是否成功 
┌──────┬───────┬────────┬────────┬─────┐ 
│            │    INSERT    │     UPDATE     │     DELETE     │  SELECT  │ 
├──────┼───────┼────────┼────────┼─────┤ 
│            │  成功  失败  │   成功  失败   │   成功  失败   │ 成功 失败│ 
├──────┼───────┼────────┼────────┼─────┤ 
│SQLCODE     │    0    <0   │    0     0,<0 │    0      <0   │   0   100│ 
├──────┼───────┼────────┼────────┼─────┤ 
│SQLERRD[3]  │    1     0   │   ≧1     0    │   ≧1      0   │   1    0 │ 
└──────┴───────┴────────┴────────┴─────┘ 
在 update 和 delete 时,若符合条件之资料可能不只一笔,因此执行后sqlerrd[3] 值会 ≧1;但失败时则有两种情行发生: 
. sqlcode = 0,表示没有符合资料可供 update/delete,故 sqlcode= 0 
. sqlcode < 0,表示 update/delete 失败,可能资料被 LOCK 住等,必须检查SQLERRD[2] 值才能知道真正原因。

第十五章  4GL与C的关系
15-1 STACK 的处理 
INformIX-4GL 和C之间数据的传送,是利用数据结构中 stack 的技巧来达成两者之间的运作。 
<语法格式> 
CALL function_name(arg1,arg2,...argn) 
15-2 呼叫的协议 
.当 informix-4gl 呼叫C时,会将函数中的参数由左至右压入(PUSH) STACK中 ,并把参数的个数也传给C。而C必须在 STACK 中依相反的次序 POP 所有的参数。 
.当C欲传回变量给 informix-4gl 时,参数的压入顺序必须与 4gl 中 returning参数的顺序相同。也就是说,无论是在个数或资料型态都必须和 returning 参数的顺序一致。 
15-3 4GL与C的界面函数 
┌──────┬─────┬────────┬────────┐ 
│  资料型态  │  定义    │ POPPING 函数   │ PUSHING 函数  │ 
├──────┼─────┼────────┼────────┤ 
│  int       │    i     │ popint(&i)     │  retint(i)     │ 
│  short     │    s     │ popshort(&s)   │  retshort(s)   │ 
│  long      │    l     │ poplong(&l)    │  retlong(l)    │ 
│  float     │    f     │ popflo(&f)     │  retflo(&f)    │ 
│  double    │    d     │ popdub(&d)     │  retdub(&d)    │ 
│  char      │  str[m]  │ popquote(str,m)│  retquote(str) │ 
└──────┴─────┴────────┴────────┘ 
记得在C中的最后一行叙述要加一个 return,而在 return 中唯一的参数是用来传递欲被传回的个数,即使没有传回参数也要 return(0)。 

§例: 

CALL bankopen(account_no,3,salary,"bankdisk.txt"
#include 
FILE *fopen(), *fp; 
static int Is_Open  = 1; 
static int serial_no = 0; 
bankopen(n) 
int n; 

 int net_income,summary_ty,i,j,len; 
 char account_no[8],a[8],bank_file[12],open_file[12]; 
 serial_no++; 
   if    (n != 4) 
         exit(1); 
   popquote(bank_file,12); 
   popint(&net_income); 
   popint(&summary_ty); 
   popquote(account_no,8); 
 len = strlen(bank_file); 
 if  (Is_Open)  { 
     fp = fopen(bank_file,"w"); 
     Is_Open = 0; 
 } 
 fprintf(fp," %06d 03",serial_no); 
 len = strlen(account_no); 
 for (i = 0; i < len; i++) 
     if  (isdigit(account_no)) { 
         a = account_no
     } 
     else { 
         a = '\0'
         break; 
     } 
 len = 7 - strlen(a); 
 for (i = 0; i < len; i++) 
      fprintf(fp,"0"); 
 fprintf(fp,"%s ",a); 
 switch (summary_ty) { 
     case 1 : fprintf(fp,"PM"); 
              break; 
     case 2 : fprintf(fp,"PR"); 
              break; 
     case 3 : fprintf(fp,"TH"); 
              break; 
 } 
 if  (net_income > 0) 
      fprintf(fp," C %08d\n",net_income); 
 else 
      fprintf(fp," D %08d\n",net_income); 
   return 0; 

 
第十六章  资料库的管理与控制 
16-1 数据库和表的存取权利 

.CONNECT 权利:允许其它使用者来存取数据库,但不能建立或修改数据库中的表和索引。 

<语法格式> 

GRANT  CONNECT TO PUBLIC 

REVOKE CONNECT TO PUBLIC 

GRANT  CONNECT TO user_list 

REVOKE CONNECT TO user_list 


.RESOURCE 权利:除了有 CONNECT 权利外,还可建立或修改数据库中的表和索引。 

<语法格式> 

GRANT  RESOURCE TO PUBLIC 

REVOKE RESOURCE TO PUBLIC 

GRANT  RESOURCE TO user_list 

REVOKE RESOURCE TO user_list 


.DBA 权利:当使用者建立数据库时,系统会自动设定 DBA 给使用者,如果给予其它使用者也有此权利时,则其它使用者也具备有RESOURCE 权利并可执行建立、更改、删除数据库中的表和索引,以及去除和激活数据库,和授与和取消CONNECT、RESOURCE,和 DBA权利。 

<语法格式> 

GRANT  DBA TO user_list 

REVOKE DBA TO user_list 


16-2 授与和取消表的权利 


<语法格式> 

GRANT  table_privilege ON table_name TO   PUBLIC 

REVOKE table_privilege ON table_name FROM PUBLIC 

GRANT  table_privilege ON table_name TO   user_list 

REVOKE table_privilege ON table_name FROM user_list 

§例: 

grant select on detailtab to public 

grant update on detailtab to public 

grant insert on detailtab to public 

grant delete on detailtab to public 

grant index  on detailtab to public 



16-3 建立可使用交易的数据库 


<语法格式> 

CREATE DATABASE database_name WITH LOG in "pathname" 


16-4 设定交易处理 


<语法格式> 

BEGIN WORK 

   交易处理 ... 

   IF  OK THEN 

       COMMIT WORK 

   ELSE 

       ROLLBACK WORK 

   END IF 
阅读(1706) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~