GENERO BDL基本语法
变量定义(DEFINE)
直接定义变量:DEFINE 变量名 变量类型
定义变量对应数据库字段:DEFINE 变量名 LIKE 数据表.数据字段
# 直接定义 employee_no 变量, 类型是 CHAR(10)
DEFINE employee_no CHAR(10)
# 定义 p_employee_no 和数据库对应
DEFINE p_employee_no LIKE employee_file.employee_no,
p_team_no SMALLINT,
p_join_date, p_birthday DATE
变量集合(RECORD )
直接定义变量集合(Records)
例:直接定义 rec 这个 Records 中的各个变量类型。
DEFINE rec RECORD # 定义rec这个变量,它是个RECORD,是个变量集合
id INTEGER,
name VARCHAR(100),
birth DATE
END RECORD
定义变量集合对应数据库字段
两种方法
1: 直接对应数据库中的字段
DATABASE example_database
MAIN
DEFINE cust01 RECORD LIKE customer.*
END MAIN
2:分别对应数据库中的字段
DATABASE example_database
MAIN
DEFINE cust02 RECORD
id LIKE customer.id,
name LIKE customer.name,
birth LIKE customer.birth,
sales LIKE salesman.name
END RECORD
END MAIN
数据结构(TYPE)
使用数据结构TYPE:[PRIVATE|PUBLIC] TYPE 变量名 变量类型
PUBLIC TYPE rpt_order RECORD
order_num INTEGER,
store_num INTEGER,
order_date DATE,
fac_code CHAR(3)
END RECORD
MAIN
DEFINE o rpt_order #使用数据结构 rpt_order 并取名为 o
DECLARE order_c CURSOR FOR
SELECT order_num, store_num, order_date, fac_code FROM orders
START REPORT order_list
FOREACH order_c INTO o.*
OUTPUT TO REPORT order_list(o.*)
END FOREACH
FINISH REPORT order_list
END MAIN
变量赋值(LET)、初始化(INITIALIZE)
若变量形态为 CHAR 和 VARCHAR 时,指定给予的值有差异
当为char时 字符串末尾带有一个空格
当为varchar时,字符串末尾不带空格
初始化变量集合(INITIALIZE)
用于初始化一组 RECORD 变量为 NULL,或者是初始化为数据库 Table 的默认值:
INITIALIZE 变量串行 { LIKE 字段串行 | TO NULL }
MAIN
DEFINE cr RECORD LIKE customer.*
INITIALIZE cr.cust_name TO NULL #初始化cr的cust_name字段为NULL
INITIALIZE cr.* LIKE customer.* #初始化cr的变量为customer表的值
END MAIN
常数(CONSTANT)
定义常数:CONSTANT constant_id [data_type] = value
CONSTANT c1 = "Drink" -- 自行定义为 STRING
CONSTANT c2 = 4711 -- 自行定义为 INTEGER
CONSTANT c3 SMALLINT = 12000 -- 自行纠正为 INTEGER
CONSTANT c4 CHAR(10) = "abc" -- 按照定义为 CHAR(10)
说明:表达式[start,end]
表示从字符串中取出子字符串,此表示方式仅能用在 CHAR 或
如果要从string中提取子字符串,则要用substring()方法
全局变量(GLOBALS)
语法一:直接写定 GLOBALS 区块
GLOBALS
declaration-statement
[,...]
END GLOBALS
语法二:读入已写好的共同配置文件(外部档案)
GLOBALS "filename"
变数的生命周期(LOCALE、MODULE、GLOBAL)
LOCAL变量(Local Variables)
定义位置:定义在 Module 中的函式里 (MAIN、FUNCTION 等)
生命周期:只属于该定义的函式使用,离开此函式即不能再使用。
MODULE变量(Module Variables)
定义位置:Module 中,但不被任何的函式包围。
生命周期:为该 Module 中的共享变数。
GLOBAL变量(Global Variables)
定义位置:由 GLOBALS 及 END GLOBALS 所包围的变数。
生命周期:使用的所有 MODULE 的共享变量。
变数的举例
SCHEMA ds
GLOBALS
DEFINE g_employee CHAR(10) --GLOBAL
END GLOBALS
DEFINE g_tty CHAR(32) --MODULE
MAIN
DEFINE answer CHAR(1) --LOCAL
END MAIN
FUNCTION ins_employee()
DEFINE flag CHAR(1), --LOCAL
change SMALLINT --LOCAL
END FUNCTION
控制输出格式(USING)
输出格式举例
MAIN
DEFINE i,j SMALLINT
LET i = 12345
LET j = -12345
DISPLAY i
DISPLAY j
DISPLAY i USING"*******"
DISPLAY j USING"*******"
DISPLAY i USING"&&&&&&&"
DISPLAY j USING"&&&&&&&"
DISPLAY i USING"#######"
DISPLAY j USING"#######"
DISPLAY i USING"<<<<<<<"
DISPLAY j USING"<<<<<<<"
DISPLAY i USING"-------"
DISPLAY j USING"-------"
DISPLAY i USING"+++++++"
DISPLAY j USING"+++++++"
DISPLAY i USING"$$$$$$$"
DISPLAY j USING"$$$$$$$"
DISPLAY i USING"(######)"
DISPLAY j USING"(######)"
DISPLAY i USING"###,###.&&"
DISPLAY j USING"###,###.&&"
END MAIN
MAIN
DISPLAY TODAY
DISPLAY TODAY USING "yyyy-mm-dd"
DISPLAY TODAY USING "yy-mm-dd"
DISPLAY TODAY USING "yy-mmm-ddd"
END MAIN
函数、流程控制
引入链接库(跳过)IMPORT
SCHEMA / DATABASE 声明数据库
使用 SCHEMA
声明数据库时,只会在编译过程中使用到声明的功能,执行程序时并不会与数据库进行实质联机。
使用 DATABASE
声明数据库时,编译时功能相同,但执行时即会链接数据库。
MAIN 函数与设定区块
MAIN 函数是程序执行的入口,一个完整可执行的程序只能有一个 MAIN 函数
MAIN
DISPLAY "hello world!"
END MAIN
FUNCTION 函数
语法:[PUBLIC | PRIVATE ] FUNCTION function_name( [arg [ , … ] ] )
CALL
执行指定的函数,若有回传值,以 RETURNING
接回。
MAIN
CALL say_hello_public()
CALL say_hello_private()
END MAIN
FUNCTION say_hello_public()
DISPLAY "Hello, world!"
END FUNCTION
PRIVATE FUNCTION say_hello_private()
DISPLAY "Hello, Private!"
END FUNCTION
试一下这个代码
||符号问题
MAIN
DEFINE var1 CHAR(10)
DEFINE var2 CHAR(2)
LET var1 = foo()
DISPLAY "var1 = " || var1 -- var1 = Hello
CALL foo() RETURNING var2
DISPLAY "var2 = " || var2 -- var2 = He
DISPLAY "foo() = " foo() -- foo() = Hello
END MAIN
FUNCTION foo()
RETURN "Hello"
END FUNCTION
IF
IF condition THEN
statement
[...]
ELSE
statement
[...]
END IF
CASE
语法1格式:适用于判断式比较简单,如只需判断1个数字
MAIN
DEFINE v CHAR(10)
LET v = "C1"
CASE v
WHEN "C1"
DISPLAY "Value is C1"
WHEN "C2"
DISPLAY "Value is C2"
WHEN "C3"
DISPLAY "Value is C3"
OTHERWISE
DISPLAY "Unexpected value"
END CASE
END MAIN
语法2格式:适用于适用于判断式较复杂
MAIN
DEFINE v CHAR(10)
LET v = "C1"
CASE
WHEN ( v="C1" OR v="C2" )
DISPLAY "Value is either C1 or C2"
WHEN ( v="C3" OR v="C4" )
DISPLAY "Value is either C3 or C4"
OTHERWISE
DISPLAY "Unexpected value"
END CASE
END MAIN
FOR
语法:默认情况 STEP = 1
MAIN
DEFINE i, i_min, i_max INTEGER
LET i_min = 1
LET i_max = 10
FOR i = i_min TO i_max # 正序
DISPLAY i
END FOR
FOR i = i_max TO i_min STEP -1 #反序
DISPLAY i
END FOR
END MAIN
WHILE
MAIN
DEFINE a,b INTEGER
LET a = 20
LET b = 1
WHILE a > b
DISPLAY a , " > " , b
LET b = b + 1
END WHILE
END MAIN
CONTINUE
MAIN
DEFINE i INTEGER
LET i = 0
WHILE i < 5
LET i = i + 1
DISPLAY "i = " || i
CONTINUE WHILE
DISPLAY "This will never be displayed !"
END WHILE
END MAIN
EXIT
语法:离开控制段。
MAIN
DEFINE i INTEGER
LET i = 0
WHILE TRUE
DISPLAY "This is an infinite loop. How would you get out of here ?"
LET i = i + 1
IF i = 100 THEN
EXIT WHILE
END IF
END WHILE
DISPLAY "Well done."
END MAIN
TRY…CATCH
针对重要 SQL 指令可以预先设置专用的错误处理指令
TRY
[待侦测是否会发生问题的程序段落]
CATCH
[处理问题或回报讯息的程序段落]
END TRY
SLEEP
语法:程序依指定秒数暂停。
MAIN
DISPLAY "Please wait 5 seconds..."
SLEEP 5 #暂停5秒
DISPLAY "Thank you."
END MAIN