引言

我国的地震前兆数据库是指除地震学以外的地磁、地电、地下流体、重力和定点形变等多学科固定台站观测数据的管理及共享平台(周克昌等,2007)。前兆观测系统所获得的观测数据通过台站、区域中心、学科中心及国家中心的四级体系进行汇集、管理、交换及应用。目前,我国的地震前兆数据库采用ORACLE数据库系统(周克昌等,2010)。

MATLAB是Mathworks公司开发的大型数学计算应用软件系统。它提供了强大的矩阵计算和可视化功能,是科学研究及工程应用方面的主流软件(Mathworks,2011)。目前的最新版本是2011年9月发布的2011b。MATLAB包含了一系列丰富的称为工具箱(Toolbox)的专用函数库,是针对不同学科和不同专业应用的得力工具。本文重点应用的是数据库工具箱(Database Toolbox)。中国地震局地球物理研究所已经购买了MATLAB的行业专用版本。

通过前兆数据库获取观测数据是进行科学研究或日常管理必须要掌握的一项技术。尽管现有的前兆台网数据管理系统可以进行手工下载,也可以采用行业专用软件或第三方开发语言编程获取。但使用MATLAB访问数据库可以以灵活多样的方式获取高度定制化的观测数据来开展包括研究在内的各项工作,并且使得这些数据处理及研究流程能够在同一平台下无缝整合。但是,由于数据库工具箱在处理ORACLE数据库上的某些局限性以及涉及到对数据库访问机制缺少了解,导致使用MATLAB访问前兆数据库在地震前兆科研管理领域并不普及,台站工作人员及科研人员缺少一条可以快速、方便的通过MATLAB获取前兆数据库中的相关数据信息进行科研及日常管理工作的捷径。

本文首先介绍包括ODBC、JDBC以及OLE-DB等主流的数据库访问机制以及在MATLAB中如何实现以这些机制对前兆数据库进行访问,并指出其应用在基于ORACLE前兆数据库中的局限性;然后给出通过组件对象模型(COM)的访问方式获取前兆观测数据的方法;最后给出对该方法进行函数封装后在实际应用中的实例。通过本文提供的方法,可以为从事地震前兆数据研究及管理工作的科研及台网工作人员提供更多、更好的数据访问方式,使得利用地震前兆数据进行后续分析更加方便快捷,同时也为地震前兆数据库在防震减灾工作中发挥更好的作用提供了参考。

1 主流的数据库访问机制

目前通常使用的数据库访问机制有以下三种:
(1)ODBC(Open DataBase Connectivity)1
(2)JDBC (Java Data Base Connectivity)2
(3)OLE-DB (Object Linking and Embedding DataBase)3

除了上述三种主流的数据库访问机制外,还有DAO(Data Access Object)以及RDO(Remote Data Object)等数据库访问机制。

ODBC是一种底层的访问技术,因此ODBC API可以使客户应用程序能从底层设置和控制数据库,用来完成一些高级数据库技术无法完成的功能。但不足之处在于ODBC只能用于关系型数据库,使得利用ODBC很难访问对象数据库及其它非关系数据库。

JDBC是一种用于执行SQL语句的Java API,可以为多种关系数据库提供统一访问,它由一组用Java语言编写的类与接口组成。JDBC提供了一种基准,据此可以构建更高级的工具和接口,使数据库开发人员能够编写数据库应用程序。

OLE-DB是一种底层数据访问界面接口,其依赖于组件对象模型(COM)。它不仅包括微软资助的标准数据接口开放数据库连通性(ODBC)的结构化问题语言(SQL)能力,同时还具有面向其他非SQL数据类型的能力。OLE-DB是ADO的基础技术,同时还是ADO.NET的数据源。

2 MATLAB中的数据库访问机制

在开始这部分之前,请确认已经在操作系统中安装了相应的数据库驱动程序。针对地震前兆数据库系统采用的ORACLE数据库,需要下载相应版本的客户端,笔者推荐使用Oracle Client 10g Express Edition。MATLAB需要确认安装数据库工具箱(Database Toolbox),本文使用2011年9月发行的2011b版本的MATLAB。下面分别介绍三种主流访问机制在MATLAB下如何实现。

2.1 ODBC模式访问

在使用ODBC机制访问数据库之前,首先需要配置ODBC源。在WINDOWS的控制面板->管理工具里打开数据源(ODBC),或者在运行里键入odbcad32命令直接启动ODBC数据源管理器。如图1所示,在系统DSN的选项卡中点击添加按钮

图 1打开ODBC数据源管理界面 Fig. 1The administrator interface of opening the ODBC data source

出现创建新数据源对话框,如图2所示,选择Microsoft ODBC for Oracle驱动后点击完成

图 2选择数据库驱动 Fig. 2Selecting the database driver

如图3所示,出现Microsoft ODBC for Oralce Setup对话框。在服务器一栏填写数据库服务器的IP地址以及实例,如255.255.255.255/PDBDC。数据源名称描述一栏填写便于记忆的任何符合规则的字符串。用户名称可以填写也可以在后续对话框中填写。

图 3ODBC设置 Fig. 3ODBC setup

在完成配置后自动测试连接是否有效。随后在MATLAB的Command Window中键入如下代码:
conn=database('你取的数据源名称','用户名','密码');
ping(conn)

这里使用ping命令获得数据库连接的状态信息。如果连接成功,则打印如下信息,请注意最后一行AutoCommitTransactions的状态是True,代表可以对数据库进行操作:
DatabaseProductName: 'Oracle'
DatabaseProductVersion: '00.00.0000 Oracle Database 10g Enterprise Edition
Release 10.2.0.3.0 - 64bi'
JDBCDriverName: 'JDBC-ODBC Bridge (msorcl32.dll)'
JDBCDriverVersion: '2.0001 (02.575.1132)'
MaxDatabaseConnections: 0
CurrentUserName: 'QZDATA'
DatabaseURL: 'jdbc:odbc:ddd'
AutoCommitTransactions: 'True'

2.2 JDBC模式访问

JDBC模式访问适合在Linux系统或者没有安装ORACLE数据库客户端的情况下访问数据库。由于MATLAB对Java的支持良好,JDBC也是数据库工具箱推荐的访问模式,并且支持多种类型的数据库访问。在使用JDBC模式访问时同样需要配置JDBC驱动程序。配置过程如下:
(1)找到Oracle Client 10g Express Edition所在的安装目录中的ojdbc14.jar文件(一般位于...\XEClient\jdbc\lib),拷贝到如下文件目录下(一般位于...\MATLAB\R2011b\java\jar\toolbox)。
(2)打开如下目录中的classpath.txt文件(一般位于... \MATLAB\R2011b\toolbox\local),并在该文件中最后一行添加如下语句并保存:
$matlabroot/java/jar/toolbox/ojdbc14.jar
完成配置后,在MATLAB的Command Window中键入如下代码测试连接是否有效:
conn=database('数据库实例名','用户名','密码','oracle.jdbc.driver. OracleDriver','jdbc:oracle:thin:@IP地址:端口号:');
ping(conn)
如果连接成功则返回有效值。打印信息如下:
DatabaseProductName: 'Oracle'
DatabaseProductVersion: [1x128 char]
JDBCDriverName: 'Oracle JDBC driver'
JDBCDriverVersion: '11.2.0.1.0'
MaxDatabaseConnections: 0
CurrentUserName: 'QZDATA'
DatabaseURL: 'jdbc:oracle:thin:@10.5.67.11:1521:PDBQZ'
AutoCommitTransactions: 'True'

2.3 OLE-DB模式访问

OLE-DB模式非常适合在WINDOWS系统下多类型的数据库访问,通过其上层的ADO/ADO.NET等高级组件技术可获得很高的数据库访问效率。利用OLE-DB模式访问,同样需要驱动的支持。安装完Oracle Client 10g Express Edition后就产生OraOLEDB10.dll驱动。OLE-DB在使用过程中需要在MATLAB中创建ADO对象,其代码如下:
cn = actxserver('ADODB.Connection');

然后针对Oracle数据库使用invoke函数写入连接字符串以及连接信息:
invoke(cn,'Open', 'Provider=OraOLEDB.Oracle;Data Source=数据库IP/实例数据库;User Id=用户名;Password=密码');

最后设定保持连接时间和数据库操作状态:
set(cn,'CommandTimeout',60)
invoke(cn,'BeginTrans')

测试并查看是否已经连接使用如下命令,如果返回值为1,则连接成功:
cn.stat

通过Workspace可以查看cn的工作状态,如图4所示:

图 4ADO组件状态 Fig. 4ADO module mode

本文着重介绍ORACLE数据库连接的方法,但是如果想要访问更多种类的数据可以通过修改连接字符串Provider的方式,以下是常用的数据库连接字符串:

连接Access数据库
Provider=Microsoft.Jet.OLEDB.4.0;Data Source=X:\mydatabase.mdb;

连接Access2007数据库
Provider=Microsoft.ACE.OLEDB.12.0;Data Source=X:\myAccess2007file.accdb;
Persist Security Info=False

连接SQL Server 2008数据库
Provider=SQLNCLI10;Server=服务器IP;Database=数据库名称;Uid=用户名; Pwd=密码;

连接MySQL数据库
Provider=MySQLProv;Data Source=数据库IP/数据库名称;User Id=用户名; Password=密码;

连接IBM DB2数据库
Provider=IBMDADB2;Database=数据库名称;Hostname=数据库IP;Protocol=TCPIP;
Port=50000;Uid=用户名;Pwd=密码;

3 获取数据

通过上述讨论,已经建立了MATLAB下访问前兆数据库的三种方法,在成功获取连接信息后就需要获得感兴趣的数据信息。

首先介绍如何通过ODBC和JDBC方式获取数据。使用MATLAB的数据库工具箱操作数据库并获取数据,通常是在建立完ODBC和JDBC连接得到连接对后,统一使用exec和fetch命令获取数据,具体格式如下:
返回游标=exec(连接对象,sql语句)
获取数据的结构体=fetch(返回的游标)
最终数据=获取数据的结构体.data
这里涉及到的SQL语句需要符合标准SQL。
下例是使用该方法获取前兆数据库中所有产出秒采样数据的地磁台站的名称、经纬度等信息:
conn = database('数据库实例','用户名','密码','oracle.jdbc.driver. OracleDriver','
jdbc:oracle:thin:@IP地址:1521:');%获得连接
sql='select distinct(a.stationid), b.stationname, b.ALTITUDE, b.LONGITUDE,
b.LATITUDE from qz_312_dys_02 a, qz_dict_stations b where a.stationid=b.
stationid order by a.stationid';%得到台站名称及经纬度信息的sql语句
curs=exec(conn,sql);%执行sql语句返回游标
sdata=fetch(curs)%获得数据的游标结构体
data=sdata.data;

可以查看到sdata游标结构体中的data中有77行数据,即目前全国产生秒数据的台站有77个,每行5列,分别是台站编号、经纬度、海拔高度等。游标结构体及最终结果如图5所示:

在MATLAB中还提供了图形交互形式的数据库查询获取方式。其命令是在Command Window中输入querybuilder启动图形界面,在配置好的ODBC连接中选取特定的库和表进行交互式查询,如图6所示。通过2.1小节中的ODBC配置好ddd的连接后,选择表以及字段进行查询并指定变量存储结果。

图 5使用JDBC方式获取的台站信息数据 Fig. 5Station information data obtained using JDBC

图 6交互式方式获取数据 Fig. 6Interface of getting data

通过数据库工具箱以及ODBC和JDBC方式可以获取一部分前兆数据库中的信息,但是在获取观测数据方面却可能遇到困难。其原因主要包括:首先,观测数据在ORACLE数据库中使用了用于存储大对象的数据类型(LOB)中的CLOB类型字段,使得观测数据的存储空间增大至4GB,同时在如此大对象的处理上需要进行转换处理,比如java中需要转化为字节流形式或者采用oracle objects for ole方式;其次,MATLAB中的数据库工具箱不支持LOB字段的读取。在数据库工具箱中仅支持表字段数据类型:BOOLEAN、CHAR、DATE、DECIMAL、DOUBLE、FLOAT、INTEGER、LONGCHAR、NUMERIC、REAL、SMALLINT、TIME、TIMESTAMP、TINYINT、VARCHAR、NTEXT(Mathworks)。因此,采用MATLAB提供的数据库工具箱不能获得前兆数据库中存储观测数据的字段类型(Mathworks, 2001)。

采用COM组件形式调用ADO组件并以OLE-DB方式访问数据就可以解决这样的问题,关键在于:在以OLE-DB方式调用ADO组件的过程中,CLOB字段可以以字节流的形式进行转化,在MATLAB中以字符的形式展示。因此,获取CLOB观测数据后只需要将字符串转化为双精度数据即可。

下面以查询某台站、某个测点和某天的GM4原始观测数据为例予以说明。

SQL语句如下:
sql= select startdate,stationid,pointid,itemid,obsvalue from qz_312_dys_02 where
stationid='12005' and pointid='4' and startdate=to_date('2010-10-09','yyyy-mm-dd')

请注意,该SQL语句包含引号等特殊字符符号,在MATLAB中需要进行调整,即在单引号处转换为三个单引号,或者可以采用本文推荐的方式,即使用SQL语句在完成测试后写入文本文件,之后再由MATLAB中使用文本读取函数读入,避免由于字符串输入错误等原因导致操作失败。同时在文本文件中保存常用的SQL语句也有利于提高工作效率。

具体代码如下:
cn = actxserver('ADODB.Connection');
invoke(cn,'Open', 'Provider=OraOLEDB.Oracle;Data Source=数据库IP/实例数据库;
User Id=用户名;Password=密码');
set(cn,'CommandTimeout',60)
invoke(cn,'BeginTrans')
r = invoke(cn,'Execute',sql);
invoke(cn,'CommitTrans');
r.recordcount>0
x=invoke(r,'getrows');
x=x';
invoke(r,'release');

通过MATLAB运行后得到如图7所示的结果:

可以看到,最后得到的结果是细胞数组四行五列,分别是日期、台站编号、测向分量以及观测数据。通过对细胞数组的操作及转化可以得到具体的观测数据值。如:
cell2mat(ans(1,5))

得到了H分量的观测值。

图 7运行实例 Fig. 7Instace of run
4 实际应用

本章给出包装成函数的数据库连接及操作的源代码,通过本章的实例,可以完成使用MATLAB读取前兆数据库中数据的全过程。

首先给出封装成函数(pdbqz.m)的数据库连接及操作的源代码。该函数可以直接在MATLAB中调用:
function x=pdbqz(sql)
cnstr='Provider=OraOLEDB.Oracle;Data Source=IP地址/ 实例数据库;User Id=用户名;
Password=密码;';
cn = actxserver('ADODB.Connection');
set(cn,'CursorLocation',3);
invoke(cn,'Open', cnstr);
set(cn,'CommandTimeout',60);
invoke(cn,'BeginTrans');
try
r = invoke(cn,'Execute',sql);
invoke(cn,'CommitTrans');
sclSuccess = 1;
catch
invoke(cn,'RollbackTrans');
sclSuccess = 0;
end
if r.recordcount>0
x=invoke(r,'getrows');
x=x';
else
x=[];
end
invoke(r,'release');

下面使用该函数获取泰安基准台(台站编号37001)从2010.1—2010.6半年内的体应变观测数据。

SQL语句如下:
select * from qz_233_dys_01 where stationid=37001 and pointid='L' and startdate
between to_date('2010-01-01','YYYY-MM-DD') and to_date('2010-06-30','YYYY-MM-DD')

代码如下:
sql=txt2sql('sql.txt');
data=pdbqz(sql)

图8是运行结果:

图 8运行结果 Fig. 8Rcuslt of run
5 结论

本文介绍了ODBC、JDBC以及OLE-DB等主流数据库的访问机制,以及在MATLAB中如何实现以这些机制对前兆数据库进行访问,指出了应用在基于ORACLE前兆数据库中的局限性;然后,给出了通过组件对象模型(COM)的访问方式获取前兆观测数据的方法;最后,给出了对该方法进行函数封装后在实际应用中的实例。通过本文提供的方法和源代码,可以快速、方便的通过MATLAB获取前兆数据库中的相关数据信息,是进行科研及日常管理工作的捷径,同时也为地震前兆数据库在防震减灾工作中发挥应有的作用提供了参考。

参考文献
[1]周克昌,蒋春花,杨东梅等,2007.地震前兆数据库结构规范. 北京:地震出版社 [本文引用:1次]
[2]周克昌,蒋春花,纪寿文等,2010.地震前兆数据库系统设计. 地震 ,(2):143—151[本文引用:1次]
[3]Mathworks, 2011.http://www.mathworks.cn/products/new_products/latest_features.html?s_cid= HP_FP_LR_2011a [本文引用:1次]