最新消息:本站持续更新中,请注意添加收藏夹。搜索关键词时,多换一个同义词。比如要搜索界面,可以尝试页面,画面,PER档等词汇。善于搜索,将大大提高你的查找效率。

[day21] FGL 程序开发(4) – 查询条件输入(QBE: Query By Example)

后端代码 bron1984 2205浏览

文章来自:iT 邦幫忙::一起幫忙解決難題,拯救 IT 人的一天 (ithome.com.tw)

[day21] FGL 程序开发(4) – 查询条件输入(QBE: Query By Example)

这个章节中,我们探讨四类查询指令中剩下的 QBE 条件输入指令 CONSTRUCT。做完条件的输入后自然就是将查询语句组装好,传到数据库内开始搜寻,这个动作上也有一些需要注意的,将会在此段同时进行提醒。

CONSTRUCT 查询条件输入

因为 INPUT 区分两种指令方式:输入用的画面字段与变量元素可以对应的(INPUT BY NAME) 与不可对应的 (INPUT…FROM…),因此 CONSTRUCT 一样可以区分成两种:

  1. 可以对应元素的 CONSTRUCT BY NAME str_where ON column1, column2, column3…
  2. 不可以对应元素的 CONSTRUCT str_where ON column1, column2, column3… WHERE scr1, scr2, scr3…

这两种指令,最后得到的都会是经过 FGL 协助组装后的 WHERE 字符串。

为什么不用 INPUT 来做一样的事情?如果能控制到特殊符号的使用 (例如 :转换为 BETWEEN 等),或是全部没输入时自动改为 1=1 输出;若做得来这件事,可以自行改用 INPUT。

控制区块(Conteol Block)

CONSTRUCT指令并不理会是否为 ARRAY 的数据,因为他的目的只是在询问用户『要查询哪些字段的哪些数据』,因此碰到 TABLE 的时候,只需要指定一排 (通常是第一排,应该不会指定第 4518排吧?) 让用户进行查询数据的指定就可以。
所以整体的控制区块,与 INPUT 指令相同,基本的控制 ON ACTION/ ON IDLE/ ON TIMER 与字段控制 BEFORE FIELD a / AFTER FIELD a / ON CHANGE a 之类的区块。

取得 WHERE条件到取出资料

卡通人物 描述已自动生成

我们设计完一张表格画面后,自然是希望用户能够在里面看到想查询的数据。透过让用户挑选字段进行数据指定 (如果不输入的话就是数据全选,WHERE条件则是 1=1),接下来要做的就是组合条件、执行SQL、抓取数据三步骤。

PREPARE

依照需求进行 SQL指令的撰写,这道基本题就让各位自行研究。我们透过

LET ls_sql=”SELECT ….WHERE “,where_condiction

的方式可以将字符串组装起来。当然,并不限定说只能将 CONSTRUCT 的结果放在此处,而是有需要的都可以拿来这里进行组装。组装后,请记得拿到的是『** SQL字符串 **』而不是 SQL指令。此时就要透过 PREPARE 协助转换为 PREPARE ID,这才是可以交付执行的部分。

PREPARE query_prepare FROM ls_sql

DECLARE

宣告,也就是告知数据库要执行的指令为何。以数据库的角度来说,即是通知数据库将要执行的SQL指令,让数据库开始进行『语法检查、硬解析hard parse』。在 CURSOR 中,必须告诉数据库,稍后是一笔一笔输出还是连续不断的输出。

DECLARE query_declare CURSOR [WITH HOLD] FOR query_declare

上述范例,如果加上 WITH HOLD就会是一笔一笔的输出。
退回到上一段 PREPARE,如果整个 SQL指令并没有一堆变量组装,而是一个直接撰写的 SQL 指令,可以省略 PREPARE直接做 DECLARE 吗?可以的,将 FOR prepare id 改为 FROM sql_statement 就可以了。

FETCH/FOREACH

最终透过 FETCH/FOREACH 就可以取得数据。对了,若有参数是在 SQL指令订定时所不知道的,可以使用 ? 传递。

其实最该用 ? 传递的是『日期/时间』,因为如果用组字符串的方式传入,必须保证在执行当下取得的变量呈现格式与 db 需求格式是相符的,这并不容易且不好除错,因此日期数据的传入,多建议使用 ? 进行

完整的 QBE转查询范例
https://4js.com/online_documentation/fjs-fgl-manual-html/#fgl-topics/c_fgl_result_sets_DECLARE.html

SQL BLOCK

在 DECLARE 段落中,有谈到使用DECLARE 时,会将 『SQL字符串』传入数据库内做硬解析。所以,这个字符串想必『需要符合数据库能看懂的语法』 !!

举例来说,Genero默认使用INFORMIX语法时,而又我们环境链接的是 ORACLE数据库,那在做 DECLARE 的时候,就要用 ORACLE的语法写、用ORACLE的 function、变量等。否则 ORACLE 看到 INFORMIX专用的语法,一定会因为认不得而出错。

又,除了 DECLARE 之外,另外在 FGL中,为了和 i4GL 兼容,还支持下列语法

SQL

SELECT COUNT(1) INTO $变数 FROM test

END SQL

中间的变量就是 FGL的变量。透过这样的方式,会比到处要做 DECLARE 来的方便些。

特别注记

  1. DECLARE-FETCH/FOREACH 可以分散在不同function中,但是『物理上』编译到FETCH/FOREACH 段落时,一定要先『编译过DECLARE』 (也就是说 DECLARE 所在行号要小于 FETCH/FOREACH的行号!!!)
  2. PREPARE id / DECLARE id 都属于『模块变量』,单一4GL档案内不可重复

希望透过本段的讲解,能让大家更理解抓取数据的方法。也完成四项交谈指令的介绍。

转载请注明:赫非域 » [day21] FGL 程序开发(4) – 查询条件输入(QBE: Query By Example)