[FGL] 再探资料库 - 使用 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才连上资料库,取出正确的笔数
额外说明:

  1. WHENEVER ERROR STOP/CONTINUE/CALL xx 是遇到SQL的时候该怎麽处置? 停止/继续/呼叫个function
  2. SQL指令执行时的状态码,写在SQLCA.SQCODE 与 SQLERRMESSAGE 预存变数内
  • 使用 CONNECT TO 语法连线资料库:在前面的章节讲解过连线的语法,这编列上就不再讲解

使用资料库的栏位型态/变数型态与栏位型态进行对应

资料库的栏位型态是可以异动 (alter)的。

当资料库型态异动的时候,意味着程序可能需要跟着改。这太麻烦,因此FGL可使用 DEFINE...LIKE 的做法,让变数去参考资料库栏位的资料型态(datatype)与长度(length)。此处参考资料库格式,并不是每次要编译的时後才去资料库抓取或理解,而是要事先准备好的,档案格式为『.sch』

https://ithelp.ithome.com.tw/upload/images/20210918/20051169azWVTfB3UK.png

透过上图,大概可以理解 .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 这个指令
https://ithelp.ithome.com.tw/upload/images/20210918/20051169ln8JDNnfiz.png

这个指令列出了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开疆辟土的大佬们。


<<:  DAY18 搞样式--CSS Gird 是什麽?

>>:  [Day3] 经典时间序列预测方法盘点

[Day20] 物件的基础概念

今天来简单介绍关於物件的一些基本概念 物件的结构 我们可以利用 {} 中括号 来建立一个物件,物件内...

Day-23 快速面试之考题大公开!(2)

今天来补充一下”快速面试”还要再补充的地方,现在回想还是怕… 有一家厂商满特别的,一开始面试直接问...

D19 第九周 後端基础 PHP 与 MySQL

这周新接触到 PHP 和 MySQL,然後是第一次使用到 session 机制实作登入功能 我自己的...

工程师黑暗撞墙期

打从进CMoney培训的第一天起,我应该怀疑过自己无数次:我真的适合当工程师吗? 而当身边的人提出对...

【Day 10】分类(Classification)(上)

找一个function,其输入为 ,输出为 属於哪一个class。 范例应用 找一个输入是某一只宝...