Pro*C 教程2025年3月17日 | 阅读18分钟 ![]() 在本教程中,我们将涵盖以下主题 什么是 Pro*C?Pro*C 意味着创建一个嵌入了 SQL 语句的程序。我们可以借助 Pro*C 访问 Oracle 数据库。C 编程语言通过操作或检索 Oracle 数据库中的数据提供了数据处理的灵活性。因此,我们可以说 Pro*C 允许 C 编程语言 将 C 程序 连接到 Oracle 数据库并根据我们的需求进行操作。 如何编译 Pro*C 程序?Oracle 软件提供了 PROC 编译器(Oracle Precompiler),该编译器处理包含嵌入式 SQL 语句的 C 程序。 什么是 Oracle 预编译器?Oracle 预编译器是一种编程工具,允许用户在高级源程序中嵌入 SQL 语句。该编译器将源程序作为输入,将嵌入的 SQL 语句替换为 oracle 运行时库调用,然后可以编译、链接和执行此修改后的程序。 Pro*C 程序的整个编译过程如下 ![]()
为什么我们需要 Pro*C 编译器?
要求Pro*C 的主要要求是安装 Pro*C 软件。当我们安装 Oracle 数据库时,我们必须确保选择了 Pro*C 组件。要检查 Oracle 的安装是否包含 Pro*C 组件,可以通过检查 Oracle 的 PRECOMP 目录来完成。 目录结构当我们安装 Oracle 时,会在我们的硬盘上为 Oracle 产品创建一个目录结构。主 Oracle 目录将包含 Pro*C 所需的子目录和文件。 当我们安装 Oracle 中的 Pro*C 时,Oracle Universal Installer 会在 ORACLE_BASE\ORACLE_HOME 目录中创建一个名为 precomp 的目录。此子目录,即 precomp,包含可执行文件、库文件和一些示例如下: precomp 目录结构
限制所有 Windows 操作系统 都可以包含文件名和目录名中的空格,但 Oracle Pro*C 预编译器不会预编译包含文件名中空格的文件。 例如,如果文件名是 the first program.pc,则此文件名无效。 嵌入式 SQL 语句这里,嵌入式 SQL 意味着将 SQL 语句放入源程序中。由于我们将语句放在 C 程序中,因此 C 程序也称为宿主程序,而我们使用的语言称为宿主语言。Pro*C 提供了在程序中嵌入 SQL 语句的能力。 嵌入式 SQL 语句有两种类型
可执行语句 可执行语句是允许您操作 Oracle 数据库中数据的 SQL 语句。这些语句调用 Oracle 运行时库。它还允许您的程序连接到 Oracle 数据库、定义查询、操作数据以及处理事务。这些语句可以写在可以放置 C 可执行语句的地方。 指令 指令或声明性语句是既不调用 Oracle 运行时库也不操作 Oracle 数据的 SQL 语句。它用于声明 Oracle 对象、SQL 对象。这些语句可以写在可以声明 C 变量的地方。 Pro*C 语法在 C 程序中,所有 SQL 语句都必须以 EXEC SQL 开头,并以分号 ; 结尾。我们可以在程序中的任何位置编写 SQL 语句,但有一个限制,即声明性语句不应出现在可执行语句之后。 假设我们想根据学生的 ID 从数据库中检索学生成绩,那么它的程序将这样编写 预处理器指令 当我们在 C 中处理 Pro*C 时,我们可以使用的预处理器指令是 #include 和 #if。但是,Pro*C 不认识 #define 指令。让我们通过下面给出的简单场景来理解这一点。 上面的代码是无效的,因为 Pro*C 不支持 #define 指令。 宿主变量宿主变量是与嵌入式 SQL 语句一起使用的宿主语言的变量。宿主变量是 Oracle 和 C 程序之间通信的关键。这些变量的声明方式与我们在 C 程序中的声明方式类似,并且可以被我们的程序和 Oracle 引用。 宿主变量可以放置在 SQL 表达式使用的地方,并且这些变量在 BEGIN DECLARE SECTION 和 END DECLARE SECTION 之间声明。当我们编写 SQL 语句时,宿主变量前面会加上冒号 ':'。 以下是 Oracle 支持的 C 数据类型列表
指针指针变量也可以用作 SQL 语句中的宿主变量。让我们通过一个简单的例子来理解。 在上面的代码中,我们声明了一个整数类型的指针变量,即 *age。声明后,我们执行一个 SELECT 语句,其中我们从 student 表中检索 age 的值,然后我们将 age 的值存储在宿主变量 age 中。结果将存储在 *age 中,而不是 age 中。 结构C 结构也用于 Pro*C。结构成员变量可以作为宿主程序中的宿主变量。当我们在 SQL 语句中提供结构名称时,每个宿主变量前面都必须加上冒号 ':',并且必须紧跟在宿主变量之后。 在上面的代码中,我们创建了一个名为 student 的结构,其中包含两个变量,即 student_id 和 name。创建结构后,我们声明了一个类型为 student 的变量 s1。然后,我们使用 insert 命令将这两个变量的值插入数据库。 数组数组可以用作嵌入式 SQL 语句中的宿主变量。让我们通过一个简单的例子来理解。 在上面的代码中,我们创建了一个整数类型的单维数组。我们实现 SQL INSERT 命令,该命令将一次性插入所有 10 个元组。 让我们看另一个使用二维数组的例子。 在 Pro*C 中,数组只能是单维的。但是,Pro*C 成功预编译了上面的代码,因为它将二维数组视为字符的单维数组,而不是字符的二维数组。 正如我们在上面的示例中所示,我们可以使用指示符变量在 SELECT 语句中确定输出宿主变量是否包含 NULL 或截断值。下表显示了 Oracle 可能返回的指示符变量值及其描述
如果我们想在 struct 中创建宿主变量的指示符变量,我们可以通过在 struct 中为每个宿主变量创建一个指示符变量来轻松实现。要在 SQL 语句中添加指示符变量的名称,我们需要编写结构指示符变量的名称,该名称前面必须带有冒号 ':',并且必须紧跟在宿主变量之后。 数据类型等价这是一个非常重要的特性,它增加了应用程序的灵活性。这意味着您可以根据 Oracle 如何解释输入数据和格式化输出数据来定制应用程序。 Oracle 包含两种数据类型
内部数据类型: Oracle 使用这些数据类型来定义数据如何在列中存储。 外部数据类型: Oracle 使用这些数据类型来格式化输出数据,然后这些输出数据将存储在宿主变量中。 让我们看看如何等价数据类型。 在逐个变量的基础上,我们使用 var 语句进行等价。var 语句的语法如下 例如,我们想从 student 表中检索学生姓名;然后,我们需要将这些学生姓名传递给接受 C 风格字符串的函数(最后一个字符必须是终止字符 '\0')。为了将宿主变量等价于 String 外部数据类型,我们使用以下代码: 该列,即 student name,包含 11 个字符。由于列 student name 包含 11 个字符,因此我们需要分配 12 个字符(11 个 student name 字符加上终止符 '\0')。我们使用 STRING 数据类型,它提供与 C 风格字符串的接口。Oracle 将自动添加 '\0' 字符。 到目前为止,我们等价了内置数据类型,即在上面的示例中,我们将 char 数组等价于 Oracle 外部数据类型(String)。我们还可以使用 TYPE 命令等价用户定义的数据类型。type 语句的语法如下 动态与静态 SQL 语句主要使用静态 SQL 语句处理固定应用程序,但有时程序需要动态创建 SQL 语句。要创建动态 SQL 语句,首先,我们需要将 SQL 语句存储在字符串变量中。存储语句后,我们使用 PREPARE 语句将字符字符串转换为 SQL 语句。最后,我们使用 EXECUTE 语句执行该语句。让我们通过一个例子来理解这个场景。 交易Oracle Pro*C 也遵循 SQL 标准定义的事务概念。事务是一系列语句,Oracle 使用这些语句来永久保存所有更改或撤销自事务开始以来的所有更改。我们使用两个语句,即 EXEC SQL COMMIT 和 EXEC SQL ROLLBACK。EXEC SQL COMMIT 语句用于永久保存自事务开始以来的所有更改。EXEC SQL ROLLBACK 语句用于撤销自事务开始以来的所有更改。如果我们不编写 EXEC SQL COMMIT 语句就开始下一个事务,那么在此事务期间所做的所有更改都将被丢弃。 错误处理C 编程提供了我们在源程序中使用的内置错误处理机制。错误处理是一种提供源程序状态的机制。我们需要一种处理错误的机制,因此 Pro*C 包含以下两种错误处理概念:
SQLCASQLCA (SQL Communication Area) 是我们的程序用于检查错误的 C 语言数据结构或区域。此数据结构包含 Oracle 使用的一些预定义变量。这些变量包含在运行时传递的程序的 C 语言状态信息。 sqlca 的结构如下 SQLCA 组件以下是 SQLCA 的组件
此字段包含两个组件 sqlerrml:它被声明为整数类型,用于保存 sqlerrmc 中存储的文本消息的长度。 sqlerrmc:它被声明为字符串,用于保存与 sqlcode 中存储的错误代码相对应的文本消息。
Whenever 语句Whenever 语句用于错误处理。它执行隐式的错误检查和处理。Whenever 语句的语法如下 当执行 Whenever 语句时,Oracle 将自动检查 SQLCA 是否满足 Whenever 语句中提到的条件。如果在 sqlca 中找到该条件,则将执行 Whenever 语句中给出的操作。 条件可以是 NOT FOUND、SQLERROR、SQLWARNING,动作可以是 CONTINUE、GOTO label、STOP、DO routine。 条件可以是以下类型
如果 Oracle 找到任何上述条件,则可以采取以下操作
创建程序的步骤以下是创建和运行程序所需的步骤
![]() 在命令提示符中输入 proc 命令后,我们按 Enter 键 ![]() 上面的屏幕显示 proc 已成功安装。
![]()
![]() 在上面的屏幕中,单击 Visual C++ 类别下左侧的 General,然后单击 Empty Project。现在,我们需要为此空项目提供一个名称。 ![]() 在上面的屏幕中,我们可以看到我们将项目名称命名为 Demo。
在上面的屏幕中,我们可以看到我们的项目工作区已创建。在最左侧,我们可以看到项目层次结构,其中包含 External Dependencies、Header Files、Resource Files 和 Source Files。
![]()
![]() 当我们单击 precomp 文件夹时,将出现下图 ![]() 单击上图中显示的 lib 文件夹。 现在添加两个对象库文件,即 orasql19,以及另一个是 orasqx19,它们位于 msvc 文件夹中。 ![]() ![]() 添加上述两个库文件后,我们的 Solution Explorer 窗口将如下所示 ![]() 在上图中,高亮显示的区域表明这两个库文件已成功添加到我们的项目中。
![]() 在上面的屏幕中,单击左侧的 Code,然后单击 C++ File。我们还为文件提供了名称 first,并带有 .pc 扩展名。
![]() 在上面的屏幕中,我们可以看到我们添加的文件的工作区已创建。
![]()
![]() ![]() 在上面的屏幕中,我们可以观察到 after first.pc by Oracle precompiler 编译后,first.c 已被创建。
![]()
运行 我们可以通过单击顶部菜单中的 Debug,然后单击 Start Debugging 来运行我们的程序。 ![]() |
我们请求您订阅我们的新闻通讯以获取最新更新。