oracle proc 编程基础及最小化案例

2023-10-20 18:27:00 浏览数 (2)

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


最小化实现代码

代码语言:javascript复制
#include <stdio.h>
#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 = %sn”, serversid);
EXEC SQL connect :serversid;// 连接服务器
if (sqlca.sqlcode != 0)// 错误处理机制,后文会有详细介绍
{
ret = sqlca.sqlcode;
printf(“connect error…errcode = %dn”, 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 <stdio.h>
#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: %sn”, 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 = %dn”, 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…

0 人点赞