C语言开发过程中,需要对数据库进行操作,使用 Oracle 数据库一般会采用Oracle Pro*C/C++ 预编译器。
本文章参考Oracle官方文档和自我实践,实验环境为 RHEL7 和 Oracle19c,详细介绍 Oracle Pro*C/C++ 预编译器,了解它在开发操作 Oracle 数据的应用程序中的作用,并了解它使您的应用程序能够做什么,具体如使用。
基本的 SQL 语句
可执行的 SQL 语句使您可以查询、操作和控制 Oracle 数据并创建、定义和维护 Oracle 对象,例如表、视图和索引。本章重点介绍查询和操作数据的语句。
在执行数据操作语句(如 INSERT、UPDATE 或 DELETE)时,除了设置任何输入主变量的值之外,您唯一关心的是语句是成功还是失败。要找出答案,您只需检查 SQLCA。(执行任何 SQL 语句都会设置 SQLCA 变量。)您可以通过以下两种方式进行检查:
- 使用 WHENEVER 语句进行隐式检查
- 显式检查 SQLCA 变量
但是,在执行 SELECT 语句(查询)时,您还必须处理它返回的数据行。查询可以分类如下:
- 不返回任何行的查询(即,仅检查是否存在)
- 只返回一行的查询
- 返回多于一行的查询
返回多于一行的查询需要显式声明的游标或使用主机数组(声明为数组的寄主变量)。
本章假设使用标量宿主变量。
以下嵌入式 SQL 语句可让您查询和操作 Oracle 数据:
| 嵌入式 SQL 语句 | 描述 |
|---|---|
| SELECT | 从一个或多个表中返回行。 |
| INSERT | 向表中添加新行。 |
| UPDATE | 修改表中的行。 |
| DELETE | 从表中删除不需要的行。 |
以下嵌入式 SQL 语句可让您定义和操作显式游标:
| 嵌入式 SQL 语句 | 描述 |
|---|---|
| DECLARE | 命名游标并将其与查询相关联。 |
| OPEN | 执行查询并识别活动集。 |
| FETCH | 推进游标并逐行检索活动集中的每一行。 |
| CLOSE | 禁用光标(活动集变为未定义)。 |
在接下来的部分中,您将首先学习如何编写 INSERT、UPDATE、DELETE 和单行 SELECT 语句。然后,您进入多行 SELECT 语句。
SELECT 语句
查询数据库是一种常见的 SQL 操作。要发出查询,请使用 SELECT 语句。在以下示例中,您查询 EMP 表:
EXEC SQL SELECT ename, job, sal + 2000
INTO :emp_name, :job_title, :salary
FROM emp
WHERE empno = :emp_number;
关键字 SELECT 后面的列名和表达式构成了选择列表。我们示例中的选择列表包含三个项目。在 WHERE 子句(以及后续子句,如果存在)中指定的条件下,Oracle 将列值返回给 INTO 子句中的主变量。
选择列表中的项目数应等于 INTO 子句中的主变量数,因此有一个地方可以存储每个返回值。
在最简单的情况下,当查询返回一行时,其形式如上一个示例所示。但是,如果查询可以返回多行,则必须使用游标 FETCH 行或将它们 SELECT 到主机变量数组中。本章稍后将讨论游标和 FETCH 语句。
如果编写的查询仅返回一行,但实际上可能返回多行,则 SELECT 的结果是不确定的。这是否会导致错误取决于您如何指定 SELECT_ERROR 选项。如果返回多于一行,则默认值 YES 会生成错误。
可用内容
您可以在您的项目中使用以下所有标准 SQL 子句
SELECT 语句:
- INTO
- FROM
- WHERE
- CONNECT BY
- START WITH
- GROUP BY
- HAVING
- ORDER BY
- FOR UPDATE OF
除了 INTO 子句外,嵌入式 SELECT 语句的文本可以使用 SQLPlus 以交互方式执行和测试。在 SQLPlus 中,您使用替换变量或常量代替输入主变量。
INSERT 语句
使用 INSERT 语句向表或视图添加行。在以下示例中,您向 EMP 表添加一行:
EXEC SQL INSERT INTO emp (empno, ename, sal, deptno)
VALUES (:emp_number, :emp_name, :salary, :dept_number);
您在列列表中指定的每一列都必须属于 INTO 子句中命名的表。VALUES 子句指定要插入的值行。这些值可以是常量、宿主变量、SQL 表达式、SQL 函数(例如 USER 和 SYSDATE)或用户定义的 PL/SQL 函数的值。
VALUES 子句中的值数必须等于列列表中的名称数。但是,如果 VALUES 子句包含表中每一列的值,则可以按照它们在表中定义的顺序省略列列表。
关于使用子查询
一个子查询是一个嵌套的SELECT语句。子查询使您可以进行多部分搜索。它们可用于
- 为 SELECT、UPDATE 和 DELETE 语句的 WHERE、HAVING 和 START WITH 子句中的比较提供值
- 定义要由 CREATE TABLE 或 INSERT 语句插入的行集
- 为 UPDATE 语句的 SET 子句定义值
以下示例在 INSERT 语句中使用子查询将行从一个表复制到另一个表:
EXEC SQL INSERT INTO emp2 (empno, ename, sal, deptno)
SELECT empno, ename, sal, deptno FROM emp
WHERE job= :job_title ;
此 INSERT 语句使用子查询来获取中间结果。
UPDATE 语句
使用 UPDATE 语句更改表或视图中指定列的值。在以下示例中,我们更新表中的SAL和COMM列 EMP:
EXEC SQL UPDATE emp
SET sal = :salary, comm = :commission
WHERE empno = :emp_number;
使用可选的 WHERE 子句指定更新行的条件。
SET 子句列出您必须为其提供值的一个或多个列的名称。您可以使用子查询来提供值,如以下示例所示:
复制
EXEC SQL UPDATE emp
SET Sal = (SELECT AVG(sal)*1.1 FROM emp WHERE deptno = 20)
哪里 empno = :emp_number;
UPDATE 语句有一个可选的returning clause,如 INSERT 和 DELETE 语句。它只允许在可选的 WHERE 条件之后。
DELETE 语句
使用 DELETE 语句从表或视图中删除行。在以下示例中,您从 EMP 表中删除给定部门的所有员工:
EXEC SQL DELETE FROM emp
WHERE deptno = :dept_number ;
我们使用了可选的 WHERE 子句来指定删除行的条件。
该returning clause选项也可用于 DELETE 语句。它在可选的 WHERE 条件之后是允许的。在前面的示例中,记录每个被删除员工的字段值是一种很好的做法。
WHERE 子句
使用 WHERE 子句仅对表或视图中满足搜索条件的行进行 SELECT、UPDATE 或 DELETE。WHERE 子句搜索条件是一个布尔表达式,可以包括标量宿主变量、宿主数组(不在 SELECT 语句中)、子查询和用户定义的存储函数。
如果省略 WHERE 子句,则处理表或视图中的所有行。如果在 UPDATE 或 DELETE 语句中省略 WHERE 子句,Oracle 将sqlwarn[4]在 SQLCA 中设置为 'W' 以警告所有行都已处理。