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);
}
分享到:
相关推荐
总的来说,基于C/C++与ORACLE9i的嵌入式SQL编程技术提供了一种强大的方式,将数据库操作与复杂逻辑集成在一起,使得程序可以灵活地处理数据。通过理解SQL通信区的工作原理以及如何声明和使用SQL变量,开发者可以有效...
### 基于C/C++与Oracle 9i的嵌入式SQL编程技术 #### 概述 在《基于C/C++与Oracle 9i的嵌入式SQL编程技术》一文中,作者们探讨了如何将结构化查询语言(SQL)嵌入到C或C++程序中,并利用Oracle 9i数据库管理系统来...
基于C/C++与Oracle9i的嵌入式SQL编程技术主要涉及将SQL语句嵌入到C/C++程序中,以便利用C/C++的过程性和面向对象特性来弥补SQL语言在处理复杂应用时的不足。Oracle9i是一个广泛使用的数据库管理系统,而嵌入式SQL是...
《Oracle9i Pro_C_C++ 编程指南》是一本专为C和C++开发者设计的深入教程,它详尽地阐述了如何在这些编程语言中有效地利用Oracle数据库的特性,特别是通过使用Oracle的Pro*C预编译器进行系统程序开发。这本书的知识点...
1. **嵌入式SQL的基本概念**:嵌入式SQL是将SQL语句直接嵌入到主语言(这里是C/C++)的程序中,使得程序可以直接与数据库进行通信。在Pro*C/C++中,通过`EXEC SQL`关键字来标识SQL语句,例如`EXEC SQL SELECT ...`...
总的来说,Oracle9i Pro*C/C++编程指南源码提供了一个全面的学习平台,有助于开发者深入理解Oracle数据库与C/C++的集成技术,对于那些需要处理大量数据库操作的高性能应用开发者来说,这是一个不可或缺的参考资料。
6. **预编译器**:这些工具(如Pro*C)将嵌入式SQL语句预编译为C或C++代码,便于生成与Oracle数据库交互的应用程序。 7. **Oracle Instant Client**:这是Oracle9i客户端的一个子集,仅包含运行时库,无需安装即可...
2. Pro*C:Pro*C是Oracle为C程序员提供的预编译器,它可以将嵌入式SQL转换为标准C代码。在Pro*C中,通过游标和绑定变量可以实现会话间的数据交换。 在Visual Studio .NET环境下,需要配置Oracle的开发库,并且使用...
**4.1 嵌入式SQL编程概念介绍** - **可嵌入Pro*C/C++的SQL语句**:包括SELECT、INSERT、UPDATE、DELETE等标准SQL语句。 - **嵌入SQL语句的语法格式**:使用`EXEC SQL`关键字开始,并以`END-EXEC`结束。 - **静态和...
- Pro*C/C++是预编译器,将嵌入式SQL语句转换为标准C或C++代码,简化了与Oracle数据库的交互。 2. **PL/SQL相关问题** - PL/SQL是Oracle的编程语言,结合了SQL和过程编程。常见的问题可能涉及语法错误、异常处理...
4. **Pro*C/C++**:预编译器,将嵌入式SQL语句转换为标准C或C++代码,以便在应用程序中调用Oracle数据库。 5. **ODBC(Open Database Connectivity)驱动程序**:使非Oracle应用程序能够通过ODBC接口连接到Oracle...
- **嵌入式SQL编程概念介绍**:介绍了如何在C/C++程序中嵌入SQL语句,包括SQL语句的种类、语法格式等。 - **开发嵌入式PRO*C/C++程序过程**:从准备环境、编写代码、预编译、编译链接到最后测试运行,详细解释了整个...
6. 嵌入式SQL编程的概念,包括静态与动态SQL、嵌入式PL/SQL语句块的使用; 7. 数据类型及宿主变量的使用,如何声明和使用宿主变量、指示变量,以及数据类型转换的相关规则; 8. 事务的处理,包括事务的开始、结束、...
- **嵌入式SQL LOB类型处理结构**:此版本增加了对SQL LOB类型的处理支持,这使得在C/C++应用程序中处理大型对象(如文本、图像等)变得更加方便。LOB类型包括BLOB、CLOB、NCLOB和BFILE,可以用于存储二进制数据和...
另外,还有Pro*C/C++,它是预编译器,将嵌入式SQL代码转换为C或C++代码。 4. **管理工具**(Management Tools):如sqlplusw.exe,是SQL*Plus的图形化版本,提供了更友好的用户界面。还有OUI(Oracle Universal ...
Oracle Pro*c 是一种专门用于开发基于 Oracle 数据库的应用程序的工具,它允许开发者在 C 语言中嵌入 SQL 语句,从而实现与数据库的高效交互。这种结合了 C 语言的强大功能和 SQL 的数据库处理能力的方式,使得...
- **嵌入式SQL**:将SQL语句嵌入到宿主语言(如C/C++)中,实现数据处理逻辑与数据库操作的紧密结合。 - **MySQL集成**:介绍如何在Oracle环境中集成MySQL数据库,实现不同数据库之间的数据交换。 #### 六、错误...
- **嵌入式SQL编程概念**:包括可嵌入的SQL语句类型、语法格式、静态和动态SQL的区别、嵌入的PL/SQL语句块等内容。 - **程序编写规范**:涵盖了注释风格、常量表示方法、变量声明、定界符使用、文件长度限制等规范。...
一组通过嵌入式 SQL 连接到 Oracle9i 数据库的 C++ 类。
**Pro*C**是一种由Oracle提供的预编译工具,用于将C语言程序中的SQL语句预编译成能够直接与Oracle数据库交互的二进制代码。它主要用于在银行业务、电信营账等领域,这些领域通常需要高效的数据处理能力以及高度定制...