预编译概念

本章主要介绍嵌入式 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”关键字;同样的,对于 2.1.1 嵌入式 SQL 语句中所介绍的 DDL、DML 和事务控制等常用的嵌入式 SQL 语句,对应的交互式 SQL 语句语法介绍可查看《DM8_SQL 语言使用手册》的相关章节。

下面的例子比较了交互式与嵌入式 COMMIT 语句的区别,他们实际的作用是一样的。

COMMIT; //交互式
EXEC SQL COMMIT; //嵌入式

2.1.3 静态 SQL 与动态 SQL

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

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

2.1.4 嵌入 DMSQL 程序块

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

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、ORACA 结构。具体使用方法见后面章节介绍。

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');
微信扫码
分享文档
扫一扫
联系客服