预编译概念

本章主要介绍嵌入式SQL中的一些关键概念与术语,并简单介绍了开发PRO*C程序的步骤。本文档中从本章开始的所有示例,除了例子中特别建的表外,其余都使用DM示例库中的表。

2.1嵌入式SQL关键概念

2.1.1嵌入式SQL语句

嵌入式SQL是指在应用程序里直接嵌入SQL语句。因为嵌入SQL,应用程序又叫宿主程序,编写应用程序的高级语言又叫宿主语言。例如,PRO*C/C++能够在C和C++宿主程序嵌入一些SQL语句。

可嵌入的SQL语句包括DDL与DML语句,以及一些事务控制语句,这些语句都是嵌入的可执行语句。可执行语句在编译时会调用libdmdpc.so库接口,通过它们连接数据库,进行数据定义及查询操作数据库数据,以及处理事务,它们能存在C/C++语言中任何可执行语句能嵌入的地方。表2.1列出了常用的嵌入可执行语句。

表2.1 常用的嵌入可执行语句
可执行语句 作用
ALLOCATE 初始化变量
ALTER,CREATE TABLE DDL
DELETE,UPDATE, INSERT,SELECT DML
COMMIT,ROLLBACK,SAVEPOINT,SET TRANSACTION 事务控制
DESCRIBE,EXECUTE,PREPARE 动态SQL

除了可执行语句,可嵌入SQL还包括一些在宿主程序与DM数据库之间传输数据的指令。这些指令在编译时不需要调用libdmdpc.so库接口,也不会操作数据库数据,用户可以使用它们声明通信区域和宿主变量。表2.2列出了常用的嵌入指令。

表2.2常用的嵌入指令
指令 作用
BEGIN DECLARE SECTION 声明宿主变量
INCLUDE 包含其他文件
TYPE 类型定义
WHENEVER 捕获运行错误

2.1.2嵌入式SQL语法

在PRO*C程序中能够自由地使用SQL语句与C语句,也可以在SQL语句中使用C变量和结构。在PRO*C中使用SQL语句必须在SQL语句前加上关键字“EXEC SQL”并且以分号结束。DM的预编译命令行运行程序dpc_new将所有带有“EXEC SQL”的语句转换为对libdmdpc.so库中接口的调用。

许多嵌入式SQL语句与交互式SQL语句的区别只在于能够使用程序变量或者是增加了额外的“EXEC SQL”关键字,下面的例子比较了交互式与嵌入式COMMIT语句的区别,他们的作用是一样的。

COMMIT; --交互式

EXEC SQL COMMIT; --嵌入式

2.1.3静态SQL与动态SQL

大多数程序使用静态的SQL处理固定的语句,在这种情况下,你必须在运行前事先知道SQL语句和事务的组成,以及哪些SQL命令会被执行,哪些表的结构会变动,哪些列会被更新等等。

然而,在某些情况下可能要在运行时才能确定要执行的有效的SQL语句,因此你在运行前可能不知道所有的SQL命令、数据库表、牵涉到的列等,只有在程序执行时才能构造出完整的SQL。动态SQL是一种高级编程技术,能够让程序在运行时处理执行过程中临时生成的SQL语句。

2.1.4嵌入PL/SQL块

PRO*C把PL/SQL语句块视作单一的嵌入SQL语句,任何SQL语句能嵌入的地方也能嵌入PL/SQL块。在宿主程序中嵌入PL/SQL块,必须使用关键字EXEC SQL EXECUTE和END-EXEC将PL/SQL语句块括起来。

2.1.5宿主变量与指示符

宿主变量是数据库与应用程序联系的关键,宿主变量是在C中声明的SQL与C程序都能使用的变量。程序使用输入宿主变量向数据库传递数据,数据库使用输出宿主变量传输数据或其他状态信息给应用程序。宿主变量能够在任何SQL表达式可以使用的地方使用。在SQL语句中,宿主变量必须以“:”作为前缀以便于同关键字区分开来。

应用程序中也能用结构来包含多个宿主变量,在SQL语句中使用结构时也要用“:”作为前缀,DM会把结构里的每个成员都当宿主变量处理。

每个宿主变量后都能跟一个指示符变量。指示符变量是一个整型的宿主变量,其作用是用来指示宿主变量的取值情况。在SQL语句中,指示符变量必须加上“:”前缀并且只能紧跟在它指示的宿主变量后面。可以在宿主变量与指示变量中间加上关键字INDICATOR使含义更明确,也可以省略。

如果宿主变量是定义在结构体中,你只需要定义一个指示符的结构,里面的指示变量与宿主结构中的宿主变量一一对应,再在SQL语句使用指示结构即可。与非结构指示变量一样,也需要紧跟在宿主结构之后,且前缀加上“:”,也可在中间加上关键字INDICATOR。

2.1.6DM数据类型

一般来说,应用程序输入数据到数据库,数据库输出数据到程序。数据库将输入的数据存储到到表中,输出数据存放到宿主变量里。

存储数据必须知道数据类型,以确定存储格式。数据在DM数据库表中的存储格式为DM内部数据类型;数据在宿主变量中的存储格式为外部数据类型。DM数据库能同时识别这两种数据类型,且在二者间进行转换。

2.1.7宿主数组

PRO*C允许定义数组宿主变量和数组结构宿主变量,并且在单个SQL中使用。使用数组可以同时操作大量数据,也可以在结构中使用数组宿主变量。

2.1.8事务

PRO*C中嵌入的SQL也适用交互式SQL中事务的概念,可以通过COMMIT、ROLLBACK、SAVEPOINT等语句对事务进行控制。

2.1.9错误与警告

当嵌入式SQL执行出错或产生警告时,PRO*C提供了三种方法来捕获错误与警告:SQLCA结构、WHENEVER语句、SQLCODE与SQLSTATE。具体使用方法见后面章节介绍。

2.2开发嵌入式程序的步骤

举例说明嵌有SQL语句的C语言程序PRO*C的运行过程:

  1. 编写嵌有SQL语句的源程序test.pc;
  2. 使用DM预编译工具dpc_new编译test.pc,生成test.c;
  3. C编译器编译链接上述文件,以及dpc_dll.h、DPI.h、DPItypes.h、sqlca.h、dmdpc.lib、dmdpc.dll,生成test.exe可执行程序。若在Linux下则将dmdpc.lib、dmdpc.dll改为libdmdpc.a和libdmdpc.so。

2.3程序编写

本节简单介绍一些嵌入式程序编写的语法、惯例、限制等,具体在后续章节中会有详细介绍。

  • 程序注释

可以在嵌入的SQL语句中使用C类型注释(/*…*/),也可以在一行的结尾使用ANSI标准的注释(//…)。

例如:

EXEC SQL SELECT NAME,/*名字*/ SEX

INTO :name, :sex -- output host variables

FROM PERSON.PERSON

WHERE PERSONID = :personid;
  • 声明节

一个声明节的组成如下例所示:

EXEC SQL BEGIN DECLARE SECTION;

/* 声明宿主变量在这里 */

char username[20],password[20],servername[20];

...

EXEC SQL END DECLARE SECTION;

声明节以“EXEC SQL BEGIN DECLARE SECTION;”语句开始,以“EXEC SQL END DECLARE SECTION;”结束。在声明节中能够存在的内容包括有以下语句:

  1. 宿主变量与指示符变量的定义
  2. 非宿主的C变量
  3. C的注释
  4. EXEC SQL TYPE语句
  • 引号

C使用单引号表示单个字符,SQL使用单引号界定字符串,例如:

EXEC SQL SELECT NAME, SEX FROM EMP WHERE PHONE = '123456789';

C使用双引号界定字符串,SQL使用双引号界定包含小写或特殊字符的标识符,例如:

EXEC SQL CREATE TABLE "test"(c1 INT);
  • 行延长

在SQL语句中能够使用反斜杠延长一行字符串到另一行,例如:

EXEC SQL INSERT INTO PERSON.PERSON (NAME, PHONE) VALUES ('XQ', '123\456');
微信扫码
分享文档
扫一扫
联系客服