在数字化转型的征途上,数据库的每一次迁移都是对企业技术架构的一次深刻革新。当企业从DB2迈向南大通用GBase 8s,不仅是数据的简单搬迁,更是应用逻辑、开发环境和数据库操作的全面适配与升级。本文将深入探讨DB2至南大通用GBase 8s应用迁移的各个关键环节,为您提供一份详尽的迁移指南和实用技巧。
1、SQL迁移的微妙差异
临时表的转换
在GBase
8s中,我们可以创建临时表来处理应用中的临时数据,并且临时表数据存储在临时表空间中。系统表不记录临时表的字典信息,从数据库系统表中查询不到临时表的任何相关信息。可以在临时表上创建索引。临时表的作用域为session,当session结束(应用程序断开数据库)、数据库实例关闭或者系统异常关闭后重新启动时临时表由数据库系统自动进行删除。
可以使用SELECT
INTO TEMP和CREATE
TEMP TABLE两种语法方式创建临时表,较为常用的语法示例为:
Select * from table_name into temp temp_name ;
而DB2的临时表分DGTT和CGTT两种,DGTT和CGTT之间的主要差异在于CGTT的定义是持久存储在DB2目录下的,CGTT在会话中创建并且在会话终止后仍然将持久保存,而DGTT在创建后仅在用户会话期间保存。DGTT可以对应转换到GBase
8s的临时表,但CGTT实际是相当于批量处理数据的工作区。
2、SPL(存储过程语言)的迁移策略
1)SPL概览与迁移
GBase
8s的存储过程和方法都可以看做是UDR(user-defined
routines),一个UDR可以使用SPL或是其他外部语言,例如C或JAVA。存储过程就是一个不返回值的程序。SPL语句只能在存储过程中使用,SPL程序以可执行的格式被解析,优化,存储在系统目录表中。
GBase
8s的存储过程支持输入,输出和输入输出参数,并且可以用在SQL语句中任何可以使用表达式的地方。
变量定义和赋值:DEFINE,
LET
流程控制
分支控制:IF
循环控制:FOR,FOREACH,WHILE
EXIT,
CONTINUE
函数调用与返回:CALL, SYSTEM ,RETURN
错误处理和调试:TRACE,
ON EXCEPTION,
RAISE EXCEPTION
2)存储过程大小及参数的限制
GBase
8s的存储过程大小限制在64K左右。DB2大于64K的存储过程,在移植时,可以改写成多个小的、互相关联的存储过程,通过传递和返回参数值来交互信息。
GBase
8s的存储过程参数上限是341个,使用JAVA编写的UDR也适用这个限制,C语言编写的UDR最多支持102个参数。Java编写的UDR中DECIMAL数据类型的参数不能超过9个。C语言编写的UDR中如果返回不透明数据类型的值,必须在C宿主变量的定义中指定opaque_type。
3)动态SQL的限制
GBase
8s在存储过程中支持动态SQL。
动态SQL是指可以在运行期间根据用户提供的信息动态地构建和执行的SQL语句。许多数据库应用程序在设计和验证阶段需要动态SQL功能来验证不完全确定的SQL。
EXECUTE
IMMEDIATE语句
EXECUTE IMMEDIATE使程序在执行过程中动态执行单个SQL语句变得更加简单。
动态SQL示例:
CREATE PROCEDURE create_tab (table_name CHAR(128), column_list CHAR(512))
DEFINE l_crtstmt CHAR(1024);
LET l_crtstmt = "CREATE TABLE " || table_name ||"("|| column_list || " )";
EXECUTE IMMEDIATE l_crtstmt;
END PROCEDURE;
EXECUTE PROCEDURE create_tab ("tmp_cust","cust_num INTEGER,cust_fname CHAR(30)");
3、函数的迁移与适配
1)数字类、字符类函数的迁移
GBase
8s支持一系列的数字和字符类函数,但在函数行为上与DB2存在差异。
LENGTH,DB2的LENGTH函数GBase
8s的LENGTH函数在CHAR类型的输出上有不同之处。DB2函数返回的数值包括字符末尾的空格,但GBase
8s函数返回值不包括空格。
ltrim(string1
[, string2]) 从前端截断string1。
示例:
SELECT LTRIM(’Hellohello world!’, ’Hello’) FROM mytab;
输出 hello world!
rtrim(string1
[, string2]) 从后端截断string1。
示例:
SELECT RTRIM(’good night... *!#?theend ’, ’ theend!*#?’) AS closing FROM mytab;
输出 good night...
DB2特有函数
一些DB2特有的字符类函数,GBase 8s并不支持,如SOUNDEX, TRANSLATE.
2)日期类函数的适配
日期类函数在两种数据库中的行为也有所不同。GBase 8s提供的round和trunc函数用于日期时间的四舍五入和截断,而add_months、last_day和next_day等函数则用于日期的计算和处理。
Round/Trunc
round(date/datetime [, fmt])
trunc(date/datetime [,fmt])
Fmt:
YEAR
MONTH
DD (day of the month)
DAY (day of the week)
HH (hour)
MI (minute)
extent(‘2014-2’,year to second)+12*interval(1) hour to hour
add_months(date/datetime, integer)返回date/datetime类型
为date或datetime的数据类型以月为单位增加。
示例
select dcol, add_months(dcol, 1)
as add_one_month from date_tab;
dcol add_one_month
02/28/2015 03/28/2015
02/29/2016 03/29/2016
01/29/2015 02/28/2015
03/31/2015 04/30/2015
last_day(date/datetime) 返回date/datetime
返回当月的最后一天相的应值。
next_day(date/datetime,
char(3)) 返回date/datetime
返回从参数1开始,参数2指定的星期x,date/datetime类型。
months_between(date/datetime, date/datetime) 返回两个日期间的月数。
SYSDATE
GBase 8s支持SYSDATE来返回一个系统当前时间,默认格式为YEAR TO FRACTION(5),另一个时间常用关键字CURRENT的默认格式为YEAR TO FRACTION(3),SYSDATE可以看做是CURRENT的一个同义词。
TO_DATE()
3)位操作和特殊函数的迁移
GBase 8s支持的位操作类函数比DB2更为丰富。同时,DBINFO函数在GBase 8s中用于返回数据库相关信息,其使用方式需根据GBase 8s的特点进行适配。
GBase 8s支持以下二进制函数
bitand(arg1, arg2)
bitor(arg1, arg2)
bitxor(arg1, arg2)
bitnot(arg1)
bitandnot(arg1, arg2)
以上函数中DB2仅支持bitand。
arg1, arg2 可以使任意的数字类型值,使用时会被转化成64位整形值。
小数数值在转换时会被自动截断。
bitnot的参数最大值为9,223,372,036,854,775,806。
特殊函数 DBINFO()
DBINFO实际上是一组函数,返回不同类型的数据库的相关信息。在参数位置指定一个特定的选项,就可以调用相应的函数功能。可以在SQL语句和UDR中使用DBINFO选项。
GBase 8s支持的函数列表如下:
4、开发环境的配置与优化
1)语言环境的设置
GBase
8s可以支持许多语言、文化和代码集。所有特定于文化的信息汇集于单个环境中,称为
Global Language
Support(GLS)语言环境。除了
ASCII 美国英语之外,GLS
允许您在其他语言环境中工作并在
SQL 数据和标识中使用非
ASCII 字符。可以使用
GLS
功能来与特定语言环境定制保持一致。语言环境文件包括特定于文化的信息,如货币和日期格式以及整理顺序。
GBase
8s通过
DB_LOCALE 和
CLIENT_LOCALE
来设置数据库的语言本地化支持设置。正确设置GLS语言环境相关变量(DB_LOCALE,
CLIENT_LOCALE),保证GBase
8s数据库服务器、客户端能正确的支持中文字符和支持使用中文的对象名。DB_LOCALE
和
CLIENT_LOCALE
的值由四部分组成(第
4
部分为可选),字符集不区分大小写:
举例说明
:
CLIENT_LOCALE=en_us.8859-1
CLIENT_LOCALE=en_us.819
# 以上两个为同一字符集:819 为 8859-1 的编码
DB_LOCALE=zh_cn.gb
数据库服务端
在创建数据库时(为了统一系统数据库与应用数据库的字符集,在创建数据库实例时),请按如下步骤设置数据库的DB_LOCALE值。
1.设置环境变量DB_LOCALE
set DB_LOCALE=zh_cn.gb
2.创建数据库create database dbname
3.验证当前数据库字符集
SELECT dbs_collate FROM sysmaster:sysdbslocale
WHERE dbs_dbsname = ‘database_name’
客户端
4.当我们使用ODBC/JDBC连接数据库时,我们需要在连接信息中正确设置语言环境变量:
DB_LOCALE和CLIENT_LOCALE。
5.设置语言环境变量
DB_LOCALE=zh_cn.gb
CLIENT_LOCALE=zh_cn.gb
特别注意,在创建数据库前请设置好环境变量DB_LOCALE为规划的字符集,因为数据库一旦创建就不能修改其字符集,除非重新创建。
在默认情况下GBase
8s将使用en_us.8859-1字符集。
支持的中文字符集有:utf8
gb
gb18030-2000
big5(ILS)
Shift-Big-5(ILS)
ccdc(ILS)
2)JDBC的配置
安装配置 JDBC
JDBC Driver 安装软件集成在CSDK软件安装包中,也可以下载单独的JDBC安装包。安装完 JDBC Driver 后,需要将文件 ifxjdbc.jar 添加到环境变量 CLASSPATH 中。
设置 IBM Gbasedbt JDBC Driver 环境变量
CLASSPATH=${CLASSPATH}:${GBASEDBTDIR}/jdbc/lib/ifxjdbc.jar
export CLASSPATH
设置JDBC连接字符串
在Java程序中使用JDBC连接数据库,首先应该加载使用的 JDBC 类,JDBC Driver的类名为com.gbasedbt.jdbc.IfxDriver。
建立Java程序与GBase 8s数据库的连接需要使用 DriverManager.getConnection() 方法,该方法中的URL参数为一个数据库的连接字符串,指定数据库的连接信息。使用不同的 JDBC 所需的 URL 参数也不相同。
使用JDBC Driver 连接数据库,连接字符串的格式如下:
jdbc:gbasedbt-sqli://[{ip-address|host-name}:{port-number|service-name}][/dbname]: GBASEDBTSERVER=servername[{;user=user;password=password] |CSM=(SSO=database_server@realm,ENC=true)} [;name=value[;name=value]...]
其中,“jdbc:gbasedbt-sqli”指定使用的JDBC为JDBC Driver;
“{ip-address|host-name}”为数据库服务器的IP地址主机名;
“{port-number|service-name}”为数据库服务器监听客户端连接的端口号或服务名;
“dbname”为数据库名;
“servername”为数据库实例名。
URL示例:
jdbc:gbasedbt-sqli://10.13.147.9:9088/sysmaster:GBASEDBTSERVER=demoserver
jdbc:gbasedbt-sqli://9.125.66.130:6346/db18030:GBASEDBTSERVER=instance_name; NEWCODESET=gb18030,gb18030-2000,5488;DB_LOCALE=zh_cn.gb18030-2000;CLIENT_LOCALE=zh_cn.gb18030-2000;
-
环境变量
GBase 8s常用环境变量:
数据库应用的迁移不仅仅是技术的转移,更是企业适应新技术、优化业务流程、提升服务质量的契机。DB2至南大通用GBase 8s的迁移过程中,每一个细节都可能影响到最终的应用性能和用户体验。
随着技术的不断演进,数据库应用迁移将成为企业技术升级的常态。我们期待,通过本文的分享,能够帮助更多的企业在迁移的征途上,规避风险,把握机遇,实现技术与业务的双重飞跃。