TimesTen和Oracle数据库同属于Oracle公司产品,而且都支持SQL语言,支持JDBC, OCI, PRO*C API。因此TimesTen程序的开发和Oracle程序的开发极为类似,如果没有使用到特定于各种产品的特性,仅仅是执行SQL,那么可以说程序的代码几乎是一样的。
下面以一个PRO*C的程序为例,来说明一套完全相同的代码,就可以同时用于访问Oracle数据库或TimesTen数据库。
PRO*C的源代码如下:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sqlda.h>
#include <sqlcpr.h>
void sql_error(char *msg);
int main(int argc, char** argv)
{
char user[32] = "tthr";
char pass[32] = "timesten";
char svc[32] = "tnssampledb_1122";
EXEC SQL WHENEVER SQLERROR DO sql_error("ORACLE error--\n");
EXEC SQL CONNECT :user IDENTIFIED BY :pass USING :svc;
EXEC SQL CREATE TABLE a (a int);
EXEC SQL INSERT INTO a values(12345);
EXEC SQL COMMIT WORK RELEASE;
exit(0);
}
void sql_error(char *msg)
{
char err_msg[128];
size_t buf_len, msg_len;
EXEC SQL WHENEVER SQLERROR CONTINUE;
printf("\n%s\n", msg);
buf_len = sizeof (err_msg);
sqlglm((unsigned char *) err_msg, &buf_len, &msg_len);
printf("%.*s\n", (int) msg_len, err_msg);
EXEC SQL ROLLBACK RELEASE;
exit(EXIT_FAILURE);
}
此代码中,关键的部分在于连接字符串,由于需要同时用于Oracle和TimesTen,那么连接的接口文件只能指定为TNS方式,因为DSN方式Oracle并不支持。
首先使用此程序访问Oracle,那么我们可以在tnsnames.ora中定义服务tnssampledb_1122指向Oracle数据库。
以下为tnsnames.ora中的tnssampledb_1122服务和Oracle数据库TTORCL的定义:
$ cd $TNS_ADMIN
$ cat tnsnames.ora
# tnsnames.ora Network Configuration File: /home/oracle/app/oracle/product/11.2.0/dbhome_1/network/admin/tnsnames.ora
# Generated by Oracle configuration tools.
tnssampledb_1122 =
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST = localhost)(PORT = 1521))
)
(CONNECT_DATA =
(SID = orcl)
)
)
TTORCL =
tnssampledb_1122 =
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST = localhost)(PORT = 1521))
)
(CONNECT_DATA =
(SID = orcl)
)
)
测试与Oracle数据库的连接:
$ sqlplus tthr/timesten@ttorcl
SQL*Plus: Release 11.2.0.2.0 Production on Tue Jul 19 06:50:18 2016
Copyright (c) 1982, 2010, Oracle. All rights reserved.
Connected to:
Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - 64bit Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options
SQL> drop table a;
Table dropped.
$ ./helloworld
SQL> select * from a;
A
----------
12345
接下来测试与TimesTen数据库的连接,我们先需要修改tnsnames.ora中tnssampledb_1122服务的定义,使其指向TimesTen:
cat tnsnames.ora
...
tnssampledb_1122 =(DESCRIPTION=(CONNECT_DATA = (SERVICE_NAME = sampledb_1122)(SERVER = timesten_direct)))
...
$ ttisql -v1 "dsn=sampledb_1122;uid=tthr;pwd=timesten"
Command> drop table a;
$ ./helloworld
Command> select * from a;
< 12345 >
以上说明,代码不修改,仅仅通过设置tnsnames.ora中的服务,一套代码即可用于连接Oracle或TimesTen
上面的测试中,我们看到,由于在PRO*C中指定了服务名,因此连接不同的数据库还需要每次临时在tnsnames.ora中修改服务名的指向。
那么还有一种方法,可以不修改tnsnames.ora,而直接通过TWO_TASK环境变量来指向相应的服务即可,我们知道TWO_TASK既可以是TNS名,也可以是easy connect string。而后者是基于DSN的。
因此这时我们在程序中并不指定服务,而通过环境变量来控制连接何种服务。
唯一的代码修改是将:
EXEC SQL CONNECT :user IDENTIFIED BY :pass USING :svc;
改为
EXEC SQL CONNECT :user IDENTIFIED BY :pass;
测试与Oracle数据库的连接, 这时TWO_TASK指定的是TNS名, ttorcl在tnsnames.ora中定义,见前面的定义:
$ export TWO_TASK=ttorcl
$ sqlplus tthr/timesten@ttorcl
SQL*Plus: Release 11.2.0.2.0 Production on Tue Jul 19 06:50:18 2016
Copyright (c) 1982, 2010, Oracle. All rights reserved.
Connected to:
Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - 64bit Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options
SQL> drop table a;
Table dropped.
$ ./helloworld
SQL> select * from a;
A
----------
12345
接下来测试与TimesTen数据库的连接, 这时TWO_TASK指定的是easy connect string,easy connect string只支持DSN。
$ ttisql -v1 "dsn=sampledb_1122;uid=tthr;pwd=timesten"
Command> drop table a;
$ export TWO_TASK="localhost/sampledb_1122:timesten_direct"
$ ./helloworld
Command> select * from a;
< 12345 >
可以看到,这种方法根本不访问tnsnames.ora,而是通过DSN文件来直接访问TimesTen数据库。