基于C_C++与ORACLE9i的嵌入式SQL编程技术

 1 概述

  SQL语言是作为独立语言在终端交互方式下使用的,它是面向集合的描述性语言,是非过程性的,即大多数语句都是独立执行,与上下文无关的。而许多事务处理应用都是过程性的,需要根据不同的条件来执行不同的任务,因此单纯用SQL语言是很难实现这类应用的。

  为了解决这一问题,将SQL语言嵌入到某种高级语言(例如C/C++)中使用,利用高级语言的过程性结构来弥补SQL语言实现复杂应用方面的不 足。这种方式下使用的SQL语言称为嵌入式SQL(Embedded SQL),而嵌入SQL的高级语言称为主语言或宿主语言。

  2 针对ORACLE9i和C/C++的嵌入式SQL的形式

  对宿主型数据库语言SQL,DBMS(数据库管理系统)可采用两种方法处理,一种是预编译,另一种是修改和扩充主语言使之能处理SQL语句。我 们采用的是ORACLE9i预编译方法,由DBMS的预处理程序(PRO*C程序)对源程序进行扫描,识别出SQL语句,把它们转换成宿主语言 (C/C++) 调用语句,以使宿主语言编译程序能识别它,最后由宿主语言的编译程序(我们用的是VC++编译程序)将整个源程序编译成目标代码,连接后形成可执行文件。

  在嵌入式SQL中,为了能够区分SQL语句与宿主语言语句,所有SQL语句都必须加前缀EXEC SQL。SQL语句的结束标志则随宿主语言的不同而不同,C/C++语言中以分号(;)结束。例如一条交互形式的SQL语句:DROP TABLE emp;嵌入到C/C++程序中,应写作EXEC SQL DROP TABLE emp;

  在宿主C/C++语言程序中,任何允许出现可执行的语句的地方,都可以写可执行SQL语句;任何允许出现说明性的语句的地方,都可以写说明性SQL语句;

  3 嵌入式SQL语句与C/C++宿主语言之间的通信

  将SQL嵌入到C/C++语言中混合编程,SQL语句负责操纵ORACLE9i数据库,C/C++语句负责控制程序流程。这时程序中会含有两种不同的计算模型的语句,一种是描述性的面向集合的SQL语句,一种是过程性的C/C++语言语句,它们之间如何通信呢?

  (1) SQL通信区

  ORACLE数据库管理系统提供了两个通讯区:SQL通信区(SQLCA)和ORACLE通信区(ORACA)。说明SQL通信区,用以记录执行每一个嵌入SQL语句的状态信息。

  EXEC SQL INCLUDE Sqlca;SQLCA是一个结构类型的变量,它是ORACLE9i和应用程序的一个接口,该结构变量是为诊断错误和事件处理而设置的。在执行PRO*C 程序时,ORACLE9i把每一个嵌入SQL语句执行的状态信息存入SQLCA中。

  SQLCA组成中含有sqlerrm,其是个子结构,它又包括sqlerrmc:保留与sqlcode中的错误代码相对应的错误信息文本。Sqlcode是一个整型变量,用于保留最近执行的SQL语句的状态码。

  (2) 变量的说明与引用

  SQL变量的说明和引用:SQL变量在引用之前必须先说明。即说明段,使用C/C++的类型说明语句为每一个SQL变量指定一个ORACLE9i能支持的C/C++数据类型。如:

  EXEC SQL BEGIN DECLARE SECTION;开始

  int emp_number;char name[15];

  EXEC SQL END DECLARE SECTION;结束

  在使用说明语句说明SQL变量的数据类型时,为变量指定的C/C++数据类型必须是与ORACLE9i的数据类型相兼容的类型。

  在SQL语句中使用SQL变量时,必须在其之前加一个冒号(:),但在C/C++语句中引用时,不需加冒号。在SELECT语句的INTO子句中所引用的变量叫输出SQL变量。在其它SQL语句(INSERT,UPDATE……)中所包含的变量都叫输入SQL变量。

  指示器变量的说明和引用:指示器变量是与宿主变量相关联的一类SQL变量,它被用来监督和管理与其相关联的宿主变量。每一个宿主变量都可定义一 个指示器变量。指示器变量的具体作用是:向数据库表列输入Null值;检查从数据库表列中选取的数据是否是Null值,或是否发生截断问题。

  指示器变量在说明段被说明为短整型变量。指示器变量名字前应加冒号,而且必须附在其相关联的宿主变量之后。用法如:

  EXEC SQL SELECT EMPNO

  INTO :emp_number:ind_num FROM EMP WHERE ENAME=:emp_name;

  if(ind_num=-1) printf(“\ Enploylee Number is Null!”);

  (3) 联接ORACLE9i数据库

  在主函数内应包含一个登录语句,如

  EXEC SQL CONNECT :username IDENTIFIED BY :password; 以实现与数据库系统的连接。

  EXEC SQL WHENEVER………; 以便指出在执行SQL语句时,如果发生错误,应如何处理。

  4 实例说明

  (1)库结构

  针对ORACLE9i数据库,我们设计了包含数据插入、更新、删除和查询的例子。在ORACLE9i数据库中设计一个员工工作简单记录系统,ORACLE9i数据库表EMP详细内容如图1所示:

  (2)编程模块

  程序的模块结构如图2所示:

  (3)部分程序清单

  ①主程序模块

  #include

  EXEC SQL BEGIN DECLARE SECTION;/*全程说明段*/

  VARCHAR username[20]; //预编译后形成结构体 username, password 结构体如下

  VARCHAR password[20]; // struct { unsigned short len; unsigned char arr[20]; }

  EXEC SQL END DECLARE SECTION;

  EXEC SQL INCLUDE splca; /*说明通讯区*/

  void insert(),update(),delete(),query(),not_found(),sql_error();//外部函数说明

  main() /*总控程序*/

  { char operate[5]

  strcpy(usernamc.arr."SCORTT");

  username.len=strlen(username.arr);

  strcpy(password.arr,"TIGER");

  password.len=strlen(password.arr);

  EXEC SQL WHENEVER SQLERROR GOTO logon_error;

  EXEC SQL CONNECT :username IDENTIFIED BY : password; /*登录到ORACLE上*/

  printf("\Connected to ORACLE as user:%s\n",username.arr);

  for(;;)

  { printf("\n* 1.Query 2.Update 3.Insert 4.Delete 5.Exit * ");/*菜单*/

  printf("\nEnter selection: \n");

  gets(operate);

  switch(operate[0]) /* 执行所选择的操作 */

  { case'1':query(); break;

  case’2’:update(); break;

  case'3':insert(); break;

  case'4'delete(); break;

  case'5':break;

  default:printf("\n\n Invalid Selection\n"); break:

  }

  if(operate[0]=='5') break;

  } / * 结束处理 * /

  EXEC SQL COMMIT RELEASE;

  printf("\n\nVery Good!\n\n");

  exit(0);

  logon_error: /*登录错误处理*/

  printf("\n invalid username/password\n");printf("\n%.70s\n",sqlca.splerrm.sqlerrmc);

  EXEC SQL WHENEVER SQLERROR CONTINUE;

  EXEC SQL ROLLBACK RELEASE;

  exit(1);

  }

  ②更新模块

  void update() /***该函数提示输入职员号,根据职员号查询该职员,然后更新它***/

  { EXEC SQL BEGIN DECLARE SECTION;

  int emp_number;VARCHAR emp_name[20]; VARCHAR job[50]; short ind_job;

  EXEC SQL END DECLARE SECTION;

  char empnum[8];

  printf("\n\nEnter Employee Number(press RETURN to abort):"); /*输入职员号*/

  gets(empnum);

  if(!strcmp(empnum," "))

  { printf("\n"); return; }

  emp_number=atoi(empnum);

  EXEC SQL WHENEVER SQLERROR GOTOsqlerror;

  EXEC SQL WHENEVER NOT FOUND GOTO notfound;

  EXEC SQL SELECT ENAME,JOB /*查询该职员信息*/

  INTO :emp_name,:job:ind_dob FROM EMP WHERE EMPNO=:emp_number;

  emp_name.arr[emp_name.len]='\0';

  switch(ind_job)

  { case -1:strcpy(job.arr,"NULL");job.len=strlen(job.arr); break;

  case 0:job.arr[job.len]='\0'; break;

  default:if(ind_job>0) printf("\n\nWARNING: Job truncated.\n"); break;

  }

  printf("\n\nNumber Employee Name Job\n");

  printf("-----------------------------------------\n");

  printf("%-9d%-15s%-8s\n",emp_number,emp_name.ar,job.arr);

  printf("\nEnter new employee name:");

  gets(emp_name.arr); /"输入新的职员信息*/

  emp_name.len=strlen(emp_name.arr);

  printf("\n\nEnter new job:");

  gets(job.arr); job.len=strlen(job.arr); ind_job=0;

  if(!strcmp(job.arr,""))ind_job=-1;

  EXEC SQL UPDATE EMP

  SET ENAME=:emp_name,JOB=:job:int_job WHERE EMPON=:emp_number; /*修改该职员信息*/

  printf("\n\nEmployee %d updated. \n",emp_number);

  EXEC SQL COMMIT; return;

  notfound: not_found();/*没查到处理*/

  sqlerror: sql_error(); /*错误处理*/

  }/*更新结束*/

  void not_found() //没找到

  { printf("\n\n WARNING: Employee %d does not exit.\n",emp_number); return;}

  void sql_error() //出错处理

  { printf("\n%.70s\n",sqlca.sqlerrm.sqlerrmc);

  EXEC SQL WHENEVER SQLERROR CONTINUE;

  EXEC SQL ROLLBACK;

  exit(1);

  }

嵌入式SQL编程的范例,使用VC6编译Oracle 10g 嵌入式SQL程序操作步骤 一、 基本要求 1、所需软件Visual C++ 6.0 2、 源代码包括 PRO C 文件: student.pc 3、安装ORACLE10G 或其客户端 在ORACLE10G CLIENT 安装时并没有 Precomp C 的选项,可以选择全部安装或者开发人员选项进行安装。安装后确保有如下几个文件: PROC的可执行文件 : $ORACLE_HOME\BIN\PROC.EXE Oracle支持SQL在VC环境的库文件OraSQL10.LIB Oracle支持SQL在VC环境的头文件 : 位于$ORACLE_HOME\precomp\ PUBLIC \*.h 文件 二、 将PROC集成到VC环境中 1、增加PROC到Tools(工具)菜单列表 在本例中,$ORACLE_HOME指的是E:\oracle\product\10.1.0\db_1目录。   a) 运行Microsoft Visual C++ 6.0;   b) 从菜单项Tools(工具)中选择Customize(定制)项。为表述简单起见,书写成如下格式:菜单Tools/ Customize(工具/定制) 项。以下采用类似的表达方法。此时出现Customize(定制)对话框;   c) 单击Tools(工具)选项卡(或属性页),用鼠标移动“Menu contents(菜单目录)”框滚动条到底部区域;   d) 双击点划线矩形区域,在空白区域上输入“PROC”,然后按回车键;   e) 在“Command(命令)”框中,输入PROC的可执行文件名。例如:E:\oracle\product\10.1.0\db_1\BIN\ PROC. EXE  f) 在“Arguments(参数)”框中输入“$(TargetName)”。其作用在从菜单Tools中选择PROC项时,VC会将当前项目名传递给PROC,尔后PROC会直接打开该项目文件目录下扩展名为 .pre的同名文件; g) 在“Initial directory(初始化目录)”框中输入“$(WkspDir)” / 单击“Close(关闭)”按钮,完成将PROC集成到VC环境中的工作。 2、指定头文件路径   为了确保VC顺利完成编译链接,需要将Oracle提供的头文件增加到VC环境中。指定头文件路径的具体步骤如下。   a) 菜单Tools / Options(工具/选择)项,出现“Options(选择)”对话框;   b) 单击“Directories(目录)”选项卡,从“Show directories for(显示目录为):”列表框中选择“Include files”;   c) 移动“Directories(路径)”框的滚动条到底部区域; d) 双击点划线矩形区域,在空白区域上输入包含Oracle支持SQL在VC环境头文件的子目录,对缺省安装即输入E:\oracle\product\10.1.0\db_1\ PRECOMP \ PUBLIC。 e) 单击“Directories(目录)”选项卡,从“Show directories for(显示目录为):”列表框中选择“Library files”;   f) 移动“Directories(路径)”框的滚动条到底部区域; d) 双击点划线矩形区域,在空白区域上输入包含Oracle支持SQL在VC环境头文件的子目录,对缺省安装即输入E:\oracle\product\10.1.0\db_1\ PRECOMP \ lib\msvc。 3、可执行文件路径 a) 菜单Tools / Options(工具/选择)项,出现“Options(选择)”对话框; b) 单击“Directories(目录)”选项卡,从“Show directories for(显示目录为):”列表框中选择“Executable files”; c) 查看“Directories(路径)”框是否包括$ORACLE_HOME\BIN 路径,一般先安装ORACLE再安装VC,这个路径会包括在内的,如果没有包括,添加这么一条路径。 三、 程序创建过程 1、 创建新工程 当运行Visual C++ 6.0后,操作步骤如下:   a) 菜单File / New项 / Project卡;   b) 选择Win32 console Application 项;   c) 由浏览选择或直接输入工程将位于的路径 / 填入创建的工程名如student 。 d) 单击OK按钮 / 依缺省值单击Finish / 单击OK,完成创建控制台应用工程框架。 e) 菜单工程/设置 项/link卡, 添加两个文件 oraSQL10.lib, oraSQX10.lib 到对象/库模块中 2、将PRO C 文件加入工程  a) 菜单Project / Add To Project 项 / Files 项;   b) 将文件对话框的文件类型改为“所有文件”;   c) 路径选为student.pc 文件所在目录   d) 选择student.pc文件,单击“打开”钮,完成将PRO C文件加入工程。 3、预编译  通过预编译,将预编译源文件如student.pc转换成为student.c的C程序源文件。在PROC集成到VC环境下时操作步骤如下:   a) 菜单Tools / PROC 项; b)此时弹出PROC预编译命令行窗口,从窗口标题可以看成,其执行E:\oracle\product\10.1.0\db_1\BIN\ PROC. EXE student 当窗口提示:“press any key to continue” ,敲任意键该窗口关闭。 此时可以看到生成student.c 文件 c) 如果预编译结束,预编译对话框左边显示的状态图标为黄色(警告)或红色(预编译失败)时,应双击该标识观察帮助或出错信息。预编译失败,应当修改源程序,再进行预编译,直到通过预编译。 4、编译准备   为了使工程能通过编译,需要将预编译输出的工程源文件和Oracle支持SQL在VC环境下的运行库文件加入到工程中,下面具体介绍增加这两个文件的步骤。   1) 将预编译的输出文件和有关头文件加入工程   a) 菜单Project / Add To Project 项 / Files 项;   b) 在文件对话框中选择正确路径,选定预编译输出生成的文件student.c,单击“打开”按钮,即将这些文件加入工程。   2) 将运行库文件加入工程   a) 菜单Project / Add To Project 项 / Files 项;   b) 将文件对话框的文件类型改为“所有文件”;   c) 路径选为$ORACLE_HOME\precomp\LIB   d) 选择OraSQL10.LIB文件,单击“打开”钮,完成将运行库文件加入工程。 5、编译链接   按F7键或单击编译图标,对工程进行编译链接。如果没有出现错误,则通过编译链接,生成可执行文件如student.exe。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值