[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条件到取出资料

https://ithelp.ithome.com.tw/upload/images/20210922/20051169rkOgfAwRPs.png

我们设计完一张表格画面後,自然是希望用户能够在里面看到想查询的资料。透过让用户挑选栏位进行资料指定 (如果不输入的话就是资料全选,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档案内不可重复

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


<<:  Day 07:测试

>>:  [Day 17] 有人提到股利吗?

【JavaScript】用debugger进行除错

【前言】 本系列为个人前端学习之路的学习笔记,在过往的学习过程中累积了很多笔记,如今想藉着IT邦帮忙...

新需求与架构设计的演进

在前面的二十天中我们完成了基本需求,但是这样的进度在真实的专案中只是刚开始而已,有可能到目前为止做的...

Day 05 : 资料处理 Pandas (1)

excel 是很多人常用来处理报表与数据的工具,同样地在 python 也有一个套件常常在处理这件事...

Day15 第十五天才介绍学习路径是否搞错什麽

本次预期会写一下的题目介绍 渗透测试基础 关於渗透测试/过程 工作和职业机会 练习 基本环境安装 V...

请教docker如何映射目录至挂载的Block Storage?

在buyvm上买了一台vps及一个Block Storage 将Block Storage挂载後在...