文章来自:iT 邦幫忙::一起幫忙解決難題,拯救 IT 人的一天 (ithome.com.tw)
[day17] 再探数据库 – 使用 fgldbsch 工具
Genero FGL为一个出自于数据库的语言,但怎么和数据库搭上边的,我们还是需要来做一下理解。
原始从 i4GL开始,既然是数据库的附属查询工具,那应该没话说:从开始执行就应该是搭着数据库一起走,直到结束时才中断与数据库的联机。但Genero已经不走这一套。
与数据库的联机
在前面的章节中,我们谈论 FGLPROFILE 时有提到,FGLPROFILE可以设定数据库的联机字符串,设定后就可使用 DATABASE 这个指令与数据库联机。
- DATABASE 摆在程序4GL code最上方,MAIN段前
DATABASE ds #FGLPROFILE中设定数据库代码为ds
MAIN
DEFINE i INT
SELECT COUNT(*) INTO i FROM table_A
END MAIN
这种写法表示在程序一开始执行就可以连上数据库
- DATABASE 写在程序段落中
MAIN
DEFINE i INT
WHENEVER ERROR CONTINUE
SELECT COUNT(*) INTO i FROM table_A
DISPLAY ‘NO CONNECT:’,i,’ STATUS:’,SQLCA.SQLCODE,”:”,SQLERRMESSAGE
DATABASE ds
SELECT COUNT(*) INTO i FROM table_A
DISPLAY ‘NO CONNECT:’,i,’ STATUS:’,SQLCA.SQLCODE,”:”,SQLERRMESSAGE
这样的写法就表示说,程序一开始是没有链接到数据库的,以致于执行上出错了。后来透过DATABASE才连上数据库,取出正确的笔数
额外说明:
- WHENEVER ERROR STOP/CONTINUE/CALL xx 是遇到SQL的时候该怎么处置? 停止/继续/呼叫个function
- SQL指令执行时的状态代码,写在SQLCA.SQCODE 与 SQLERRMESSAGE 预存变数内
- 使用 CONNECT TO 语法联机数据库:在前面的章节讲解过联机的语法,这编列上就不再讲解
使用数据库的字段型态/变量型态与字段型态进行对应
数据库的字段型态是可以异动 (alter)的。
当数据库型态异动的时候,意味着程序可能需要跟着改。这太麻烦,因此FGL可使用 DEFINE…LIKE 的做法,让变量去参考数据库字段的数据型态(datatype)与长度(length)。此处参考数据库格式,并不是每次要编译的时后才去数据库抓取或理解,而是要事先准备好的,文件格式为『.sch』
透过上图,大概可以理解 .sch 是由 fgldbsch 这个工具连到数据库,读取系统表格分析后产出的纪录文件 (如 ds 数据库,经过 fgldbsch 之后就会产出 ds.sch 的结构文件,提供使用。
程序中使用DATABASE ds 读取表格结构
标题这样下的时候,应该就可以联想到,当 DATABASE 出现在程序 (MAIN) 与GLOBAL设定的前端时,除了启动数据库联机外,还有『在编译时要求读取 sch 文件』的功能
若不欲使用DATABASE 进行开启前联机,则需使用 SCHEMA ds 读取表格结构
当程序中不想开起就连上db,而将 DATABASE 移位到程序中间,甚至是使用 CONNECT TO指令进行联机,此时就需要在程序的最上方宣告处,改用 SCHEMA ds 来让 fglcomp (编译程序) 理解到稍后是需要用 ds.sch 来替换 LIKE 后面的格式
LIKE 的语法
通常的定义是 DEFINE i INT,而若参照的语法,则可以写成 DEFINE i LIKE table_id.column_id
这样的写法可以让该变量(i)在编译时,使用column_id 的型态与长度进行编译。若有更改,怎办?重新编译一次呀。这样的好处在:若有alter时则重编译就可以执行。
怎么用说完了,接下来看一下 ds.sch 怎么生出来的 (ds.4db是衍生品,语法替换出来的产物,故研究 .sch即可)
fgldbsch
我个人认为这是一个非常神奇的工具,它可以协助我们将 db的表格字段型态倒出来,让我们编译程序的时候减少去背诵记忆到底要用哪些型态。甚至透过 sch 的预载,可以很便利的协助我们在 studio 中拉出DML(数据关联图)
sch的数据格式
customer^customer_num^258^4^1^
customer^customer_name^256^50^2^
customer^customer_address^0^100^3^
order^order_num^258^4^1^
order^order_custnum^258^4^2^
order^order_date^263^4^3^
order^order_total^261^1538^4^
上面是 FGL在线文件中列出的范例,使用 ^(hat) 进行分隔,字段分别是 table id / Column id/ 字段型态/ 字段长度 / 顺序 等。
字段型态并不是『真正在数据库中的数据型态』。WHAT? 每种数据库都有不同形态,大家各玩各的未来还有甚么整合的希望,所以这边的数据型态纪录的是『参考INFORMIX转换过的数据型态』。
长度则是经过转换换算的。例如 INT/SMALLINT/CHAR/VARCHAR 这些都有固定的长度,但若 DECIMAL(ORACLE则是NUMBER)就会经过转换转为单一数字。另外,若这个字段具有 KEY (PK)身分的话,会再加上一个数值。详细转换公式可以参考: https://4js.com/online_documentation/fjs-fgl-manual-html/index.html#fgl-topics/c_fgl_DatabaseSchema_018.html
设定转换数据型态
上方提到:这是一种参考 INFORMIX 而来的转换型态,可是不可能两种不同厂牌的数据库具有同样多的数据型态。此时就需要用到 fgldbsch 的密技:对应表
fgldbsch常用指令 (不常用的先滤除)
<topprd:/u1/topprd> fgldbsch -h
Usage: fgldbsch [options]
-ct : Show data type conversion tables. 显示转换表
-cx dbtype : Show data type converstion table for a given db type. 使用转换表
-db name : Database name. 数据库名
-dv name : Database driver. 数据库驱动
-un user : Database User name. 数据库用户
-up password : Database User password. 密码
-ow name : Database schema/tables owner. 数据库/表拥有者
-of name : Output filename prefix. Default is database name. 产出档名
<topprd:/u1/topprd>
其中最需要注意的是 fgldbsch -ct 这个指令
这个指令列出了ORACLE一些与 INFORMIX有差异的数据型态,然后分选项A/ 选项B,就是想问你会怎么要fgldbsch调整?相当于可以让 fgldbsch 来做选择规则。
例如:ORACLE的 DATE是可以存时分秒的,INFORMIX的DATE不行,必须要到 DATETIME YEAR TO SECOND才可以存时分秒。所以,fgldbsch可以让你决定,要转换为 DATE或是DATETIME YEAR TO SECOND
这张表需要在开工前仔细确认好原则,所以在开始撰写联机新的 DB 厂牌时,最重要的就是把型态给决定下来。
这张表格中的序列,从常用的到不常用的依序排列。意思是,如果我要改的是第五项,则我要宣告 1-5 项。(1-4没要改,那也要宣告!!)
所以宣告时 fgldbsch 指令如下
fgldbsch -db ds -ow ds -ie -cv AAAAB
那?我第 7,9 项想改为 B 其他保持默认值 A 岂不是 -cv AAAAAABAB ?是的,这就是正确答案。
透过仔细地阅读新 db 的差异,确认需要使用的数据表对应方式,这是撰写前的起手式。能掌握好这段的配置,在后续的开发可以避免掉许多数据型态不合的错误。
其实这个段落章节,应该是由部门的辉哥来撰写,更为精彩。在此感谢为 Genero开疆辟土的大佬们。
转载请注明:赫非域 » [day17] 再探数据库 – 使用 fgldbsch 工具