一套程序,两样用途:论TimesTen程序和Oracle程序的兼容性

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数据库。

你可能感兴趣的:(oracle,数据库,内存,timesten)