oracle proc 定义宿主,oracle proc 编程基础及最小化案例

本文介绍了Oracle Pro*C编程的基本流程,包括编辑.pc文件,使用proc预处理生成.c文件,然后通过gcc进行编译。预处理后的代码包含了C语言的执行语句,用于连接Oracle服务器。在编译时需要注意指定动态库和头文件路径,以解决链接错误。通过这个过程,读者可以理解Pro*C如何与Oracle数据库交互。
摘要由CSDN通过智能技术生成

oracle proc 编程是在我的概念中是非常陌生的,学习了一天下来发现这东西真的好古老,但是依然健壮、稳定,其中间是编辑一个 .pc 的文件使用 proc 进行预处理,预处理后生成一个真正的.c文件,此时再由 gcc 去编译成一个可执行文件运行。因为 proc 涉及到的知识较多,我无法整理到几篇博文中就概述这些所涉及的知识,所以只能总结代码做好注释防止以后自己需要时忘记。如果有想进一步了解 proc 编程的,可以买名为“Oracle9I ProC C++编程指南”。包括 oracle 的环境搭建也并不是我们讨论的重点,如果有精力的话,我会给大家编写类似的教程。

最小化实现代码

#include

#include "sqlca.h"// 包含 proc 头文件

EXEC SQL BEGIN DECLARE SECTION;

char* serversid = "scott/tiger@orcl";// 定义宿主变量

EXEC SQL END DECLARE SECTION;

int main(int argc, char* argv)

{

int ret = 0;

printf("connect server str = %s\n", serversid);

EXEC SQL connect :serversid;// 连接服务器

if (sqlca.sqlcode != 0)// 错误处理机制,后文会有详细介绍

{

ret = sqlca.sqlcode;

printf("connect error...errcode = %d\n", ret);

return ret;

}

printf("connect oracler server success...\n");

EXEC SQL commit release;// 提交并关闭连接

return 0;

}

使用 proc 命令进行编译,编译结果如下:

[oracle@localhost 0723]$ proc hello.pc

Pro*C/C++: Release 11.2.0.1.0 - Production on Fri Jul 24 13:20:03 2015

Copyright (c) 1982, 2009, Oracle and/or its affiliates. All rights reserved.

System default option values taken from: /home/oracle_11/app/oracle/product/11.2.0/db_1/precomp/admin/pcscfg.cfg

此时会在当前目录下生成一个预处理过的 .c 文件,.c文件的内容如下:

/* Result Sets Interface */

#ifndef SQL_CRSR

# define SQL_CRSR

struct sql_cursor

{

unsigned int curocn;

void *ptr1;

void *ptr2;

unsigned int magic;

};

typedef struct sql_cursor sql_cursor;

typedef struct sql_cursor SQL_CURSOR;

#endif /* SQL_CRSR */

/* Thread Safety */

typedef void * sql_context;

typedef void * SQL_CONTEXT;

/* Object support */

struct sqltvn

{

unsigned char *tvnvsn;

unsigned short tvnvsnl;

unsigned char *tvnnm;

unsigned short tvnnml;

unsigned char *tvnsnm;

unsigned short tvnsnml;

};

typedef struct sqltvn sqltvn;

struct sqladts

{

unsigned int adtvsn;

unsigned short adtmode;

unsigned short adtnum;

sqltvn adttvn[1];

};

typedef struct sqladts sqladts;

static struct sqladts sqladt = {

1,1,0,

};

/* Binding to PL/SQL Records */

struct sqltdss

{

unsigned int tdsvsn;

unsigned short tdsnum;

unsigned char *tdsval[1];

};

typedef struct sqltdss sqltdss;

static struct sqltdss sqltds =

{

1,

0,

};

/* File name & Package Name */

struct sqlcxp

{

unsigned short fillen;

char filnam[9];

};

static struct sqlcxp sqlfpn =

{

8,

"hello.pc"

};

static unsigned int sqlctx = 18323;

static struct sqlexd {

unsigned long sqlvsn;

unsigned int arrsiz;

unsigned int iters;

unsigned int offset;

unsigned short selerr;

unsigned short sqlety;

unsigned int occurs;

short *cud;

unsigned char *sqlest;

char *stmt;

sqladts *sqladtp;

sqltdss *sqltdsp;

unsigned char **sqphsv;

unsigned long *sqphsl;

int *sqphss;

short **sqpind;

int *sqpins;

unsigned long *sqparm;

unsigned long **sqparc;

unsigned short *sqpadto;

unsigned short *sqptdso;

unsigned int sqlcmax;

unsigned int sqlcmin;

unsigned int sqlcincr;

unsigned int sqlctimeout;

unsigned int sqlcnowait;

int sqfoff;

unsigned int sqcmod;

unsigned int sqfmod;

unsigned char *sqhstv[4];

unsigned long sqhstl[4];

int sqhsts[4];

short *sqindv[4];

int sqinds[4];

unsigned long sqharm[4];

unsigned long *sqharc[4];

unsigned short sqadto[4];

unsigned short sqtdso[4];

} sqlstm = {12,4};

/* SQLLIB Prototypes */

extern sqlcxt ( void **, unsigned int *,

struct sqlexd *, struct sqlcxp * );

extern sqlcx2t( void **, unsigned int *,

struct sqlexd *, struct sqlcxp * );

extern sqlbuft( void **, char * );

extern sqlgs2t( void **, char * );

extern sqlorat( void **, unsigned int *, void * );

/* Forms Interface */

static int IAPSUCC = 0;

static int IAPFAIL = 1403;

static int IAPFTL = 535;

extern void sqliem( unsigned char *, signed int * );

typedef struct { unsigned short len; unsigned char arr[1]; } VARCHAR;

typedef struct { unsigned short len; unsigned char arr[1]; } varchar;

/* CUD (Compilation Unit Data) Array */

static short sqlcud0[] =

{12,4130,1,0,0,

5,0,0,0,0,0,27,13,0,0,4,4,0,1,0,1,97,0,0,1,10,0,0,1,10,0,0,1,10,0,0,

36,0,0,2,0,0,30,22,0,0,0,0,0,1,0,

};

#include

#include "sqlca.h"

/* EXEC SQL BEGIN DECLARE SECTION; */

char* serversid = "scott/tiger@orcl";// 定义宿主变量

/* EXEC SQL END DECLARE SECTION; */

int main(int argc, char* argv[])

{

int ret = 0;

printf("serversid: %s\n", serversid);// 打印一下服务器的连接地址字符串

/* EXEC SQL CONNECT :serversid; */

{

struct sqlexd sqlstm;

sqlstm.sqlvsn = 12;

sqlstm.arrsiz = 4;

sqlstm.sqladtp = &sqladt;

sqlstm.sqltdsp = &sqltds;

sqlstm.iters = (unsigned int )10;

sqlstm.offset = (unsigned int )5;

sqlstm.cud = sqlcud0;

sqlstm.sqlest = (unsigned char *)&sqlca;

sqlstm.sqlety = (unsigned short)4352;

sqlstm.occurs = (unsigned int )0;

sqlstm.sqhstv[0] = (unsigned char *)serversid;

sqlstm.sqhstl[0] = (unsigned long )0;

sqlstm.sqhsts[0] = ( int )0;

sqlstm.sqindv[0] = ( short *)0;

sqlstm.sqinds[0] = ( int )0;

sqlstm.sqharm[0] = (unsigned long )0;

sqlstm.sqadto[0] = (unsigned short )0;

sqlstm.sqtdso[0] = (unsigned short )0;

sqlstm.sqphsv = sqlstm.sqhstv;

sqlstm.sqphsl = sqlstm.sqhstl;

sqlstm.sqphss = sqlstm.sqhsts;

sqlstm.sqpind = sqlstm.sqindv;

sqlstm.sqpins = sqlstm.sqinds;

sqlstm.sqparm = sqlstm.sqharm;

sqlstm.sqparc = sqlstm.sqharc;

sqlstm.sqpadto = sqlstm.sqadto;

sqlstm.sqptdso = sqlstm.sqtdso;

sqlstm.sqlcmax = (unsigned int )100;

sqlstm.sqlcmin = (unsigned int )2;

sqlstm.sqlcincr = (unsigned int )1;

sqlstm.sqlctimeout = (unsigned int )0;

sqlstm.sqlcnowait = (unsigned int )0;

sqlcxt((void **)0, &sqlctx, &sqlstm, &sqlfpn);

}

// 连接服务器

if (sqlca.sqlcode != 0)// 容错处理,后面会有更详细的文章介绍

{

ret = sqlca.sqlcode;

printf("connect oracle error... code = %d\n", ret);

return ret;

}

printf("connect oracle success...\n");

/* EXEC SQL COMMIT RELEASE; */

{

struct sqlexd sqlstm;

sqlstm.sqlvsn = 12;

sqlstm.arrsiz = 4;

sqlstm.sqladtp = &sqladt;

sqlstm.sqltdsp = &sqltds;

sqlstm.iters = (unsigned int )1;

sqlstm.offset = (unsigned int )36;

sqlstm.cud = sqlcud0;

sqlstm.sqlest = (unsigned char *)&sqlca;

sqlstm.sqlety = (unsigned short)4352;

sqlstm.occurs = (unsigned int )0;

sqlcxt((void **)0, &sqlctx, &sqlstm, &sqlfpn);

}

// 提交(commit)并关闭(release)连接

return 0;

}

这是由 proc 预处理过后的 .c 文件,只不过是将我们之前编写的 pc 文件中的一些 EXE SQL … 等关键字替换成了真正的 c 语言执行语句。最后我们需要使用 gcc 来编译它。如果你直接编译的话,会收到如下报错:

[oracle@localhost 0723]$ gcc hello.c -o hello

/tmp/cchZbCeQ.o: In function `main':

hello.c:(.text+0x86): undefined reference to `ECPGget_sqlca'

hello.c:(.text+0x1ed): undefined reference to `sqlcxt'

hello.c:(.text+0x1f2): undefined reference to `ECPGget_sqlca'

hello.c:(.text+0x200): undefined reference to `ECPGget_sqlca'

hello.c:(.text+0x27f): undefined reference to `ECPGget_sqlca'

hello.c:(.text+0x2b7): undefined reference to `sqlcxt'

这提示的意思是找不到动态库,所以我们需要手动指定动态库和头文件所在路径。正确的编译方法如下:

gcc hello.c -o hello -I $ORACLE_HOME/precomp/public -L $ORACLE_HOME/lib -l clntsh

编译完成后运行程序,如果提示连接成功,那么证明你的程序就可以正常连接 oracle 服务器了:

[oracle@localhost 0723]$ ./hello

serversid: scott/tiger@orcl

connect oracle success...

相关

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值