第十二章 报表设计 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
| | |