嵌入式SQL
SQL语言提供了两种不同的使用方式
为什么要引入嵌入式SQL
这两种方式细节上有差别,在程序设计的环境下,SQL语句要做某些必要的扩充
一、嵌入式SQL的处理过程 主语言
处理过程
为了区分SQL语句与主语言语句,所有SQL语句必须加前缀EXEC SQL, 主语言为C语言时,语句格式:
EXEC SQL <SQL语句>;
二、嵌入式SQL语句与主语言之间的通信 将SQL嵌入到高级语言中混合编程,程序中会含有两种不同计算模型的语句 1.SQL语句
2.高级语言语句
3.数据库工作单元与源程序工作单元之间的通信 (1)向主语言传递SQL语句的执行状态信息,使主语言能够据此控制程序流程,主要用SQL通信区实现 (2)主语言向SQL语句提供参数,主要用主变量实现 (3)将SQL语句查询数据库的结果交主语言处理,主要用主变量和游标实现
4.SQLCA: SQL Communication Area SQLCA是一个数据结构 (1)SQLCA的用途
(2)SQLCA使用方法
EXEC SQL INCLUDE SQLCA
定义SQLCODE
b. 如果SQLCODE等于预定义的常量SUCCESS
,则表示SQL语句成功,否则表示出错
c. 应用程序每执行完一条SQL 语句之后都应该测试一下SQLCODE的值,以了解该SQL语句执行情况并做相应处理5.主变量
主变量的类型
6.指示变量
7.在SQL语句中使用主变量和指示变量的方法
(1)说明主变量和指示变量
BEGIN DECLARE SECTION
...
... (说明主变量和指示变量)
...
END DECLARE SECTION
(2)使用主变量
(3)使用指示变量
(4)在SQL语句之外(主语言语句中)使用主变量和指示变量的方法: 可以直接引用,不必加冒号
8.使用游标的原因
9.游标
(1)建立数据库连接
EXEC SQL CONNECT TO target[AS connection-name][USER user-name];
target是要连接的数据库服务器
a.常见的服务器标识串,如<dbname>@<hostname>:<port>
b.包含服务器标识的SQL串常量
c.DEFAULT
d.connect-name是可选的连接名,连接名必须是一个有效的标识符
e.在整个程序内只有一个连接时可以不指定连接名
f.程序运行过程中可以修改当前连接
EXEC SQL SET CONNECTION connection-name|DEFAULT;
(2)关闭数据库连接
EXEC SQL DISCONNECT [connection];
举个例子 依次检查某个系的学生记录,交互式更新某些学生年龄。
EXEC SQL BEGIN DECLARE SECTION; /*主变量说明开始*/
char Deptname[20];
char Hsno[9];
char Hsname[20];
char Hssex[2];
int HSage;
int NEWAGE;
EXEC SQL END DECLARE SECTION; /*主变量说明结束*/
long SQLCODE;
EXEC SQL INCLUDE SQLCA; /*定义SQL通信区*/
int main(void) /*C语言主程序开始*/
{
int count = 0;
char yn; /*变量yn代表yes或no*/
printf("Please choose the department name(CS/MA/IS): ");
scanf("%s",deptname); /*为主变量deptname赋值*/
EXEC SQL CONNECT TO TEST@localhost:54321 USER "SYSTEM"/"MANAGER"; /*连接数据库TEST*/
EXEC SQL DECLARE SX CURSOR FOR /*定义游标SX*/
SELECT Sno,Sname,Ssex,Sage /*SX对应的语句*/
FROM Student
WHERE SDept = :deptname;
EXEC SQL OPEN SX; /*打开游标SX,指向查询结果的第一行*/
for ( ; ; ) /*用循环结构逐条处理结果集中的记录*/
{
EXEC SQL FETCH SX INTO :HSno,:Hsname,:HSsex,:HSage; /*推进游标,将当前数据放入主变量*/
if (SQLCA.SQLCODE!= 0) /*SQLCODE != 0,表示操作不成功*/
break; /*利用SQLCA中的状态信息决定何时退出循环*/
if(count++ == 0) /*如果是第一行的话,先打出行头*/
printf("\n%-10s %-20s %-10s %-10s\n","Sno","Sname","Ssex", "Sage");
printf("%-10s %-20s %-10s %-10d\n",HSno,Hsname,Hssex,HSage); /*打印查询结果*/
printf("UPDATE AGE(y/n)?"); /*询问用户是否要更新该学生的年龄*/
do{scanf("%c",&yn);}
while(yn != 'N' && yn != 'n' && yn != 'Y' && yn != 'y');
if (yn == 'y' || yn == 'Y') /*如果选择更新操作*/
{
printf("INPUT NEW AGE:");
scanf("%d",&NEWAGE); /*用户输入新年龄到主变量中*/
EXEC SQL UPDATE Student /*嵌入式SQL更新语句*/
SET Sage = :NEWAGE
WHERE CURRENT OF SX;
} /*对当前游标指向的学生年龄进行更新*/
}
EXEC SQL CLOSE SX; /*关闭游标SX,不再和查询结果对应*/
EXEC SQL COMMIT WORK; /*提交更新*/
EXEC SQL DISCONNECT TEST; /*断开数据库连接*/
}
三、不用游标的SQL语句 (1)不用游标的SQL语句的种类
这类语句不需要使用游标,只需用INTO子句指定存放查询结果的主变量。
[例] 根据学生号码查询学生信息。
EXEC SQL SELECT Sno,Sname,Ssex,Sage,Sdept
INTO:Hsno,:Hname,:Hsex,:Hage,:Hdept
FROM Student
WHERE Sno=:givensno;
/*把要查询的学生的学号赋给为了主变量givensno*/
[例] 查询某个学生选修某门课程的成绩。假设已经把将要查询的学生的学号赋给了主变量givensno,将课程号赋给了主变量givencno。
EXEC SQL SELECT Sno,Cno,Grade
INTO :Hsno,:Hcno,:Hgrade:Gradeid /*指示变量Gradeid*/
FROM SC
WHERE Sno=:givensno AND Cno=:givencno;
如果Gradeid < 0,不论Hgrade为何值,均认为该学生成绩为空值。
[例] 修改某个学生选修1号课程的成绩。
EXEC SQL UPDATE SC
SET Grade=:newgrade /*修改的成绩已赋给主变量:newgrade*/
WHERE Sno=:givensno; /*学号赋给主变量:givensno*/
[例] 某个学生新选修了某门课程,将有关记录插入SC表中。假设插入的学号已赋给主变量stdno,课程号已赋给主变量couno。
gradeid=-1; /*gradeid为指示变量,赋为负值*/
EXEC SQL INSERT
INTO SC(Sno,Cno,Grade)
VALUES(:stdno,:couno,:gr :gradeid);/*:stdno,:couno,:gr为主变量*/
由于该学生刚选修课程,成绩应为空,所以要把指示变量赋为负值
四、使用游标的SQL语句 1.必须使用游标的SQL语句
2.使用游标的步骤 (1)说明游标 (2)打开游标 (3)推进游标指针并取当前记录 (4)关闭游标
3.使用DECLARE语句 (1)语句格式
EXEC SQL DECLARE <游标名> CURSOR
FOR <SELECT语句>;
(2)功能
4.使用OPEN语句 (1)语句格式
EXEC SQL OPEN <游标名>;
(2)功能
5.使用FETCH语句 (1)语句格式
EXEC SQL FETCH <游标名>
INTO <主变量>[<指示变量>]
[,<主变量>[<指示变量>]]...;
(2)功能
6.使用CLOSE语句 (1)语句格式
EXEC SQL CLOSE <游标名>;
(2)功能
(3)说明
7.CURRENT形式的UPDATE语句和DELETE语句的用途 (1)非CURRENT形式的UPDATE语句和DELETE语句
(2)如果只想修改或删除其中某个记录
WHERE CURRENT OF <游标名>
表示修改或删除的是最近一次取出的记录,即游标指针指向的记录 8.不能使用CURRENT形式的UPDATE语句和DELETE语句
五、动态SQL
静态嵌入式SQL
动态嵌入式SQL
1. 使用SQL语句主变量
2. 动态参数 动态参数
和主变量的区别
使用动态参数的步骤 (1)声明SQL语句主变量 (2)准备SQL语句(PREPARE)
EXEC SQL PREPARE <语句名>
FROM <SQL语句主变量>;
EXEC SQL EXECUTE <语句名>
[INTO <主变量表>]
[USING <主变量或常量>];
3. 执行准备好的语句(EXECUTE)
一、过程化SQL的块结构 1.过程化SQL
2.过程化SQL块的基本结构 (1)定义部分
DECLARE 变量、常量、游标、异常等
BEGIN
SQL语句、过程化SQL的流程控制语句
EXCEPTION
异常处理部分
END;
二、变量和常量的定义 1. 变量定义
变量名 数据类型 [[NOT NULL]:=初值表达式]
变量名 数据类型 [[NOT NULL] 初值表达式]
2. 常量定义
常量名 数据类型 CONSTANT :=常量表达式
常量必须要给一个值,并且该值在存在期间或常量的作用域内不能改变。如果试图修改它,过程化SQL将返回一个异常 3. 赋值语句
变量名称 :=表达式
三、流程控制 过程化SQL功能 1. 条件控制语句 IF-THEN,IF-THEN-ELSE和嵌套的IF语句 (1)
IF condition THEN
Sequence_of_statements;
END IF;
(2)
IF condition THEN
Sequence_of_statements1;
ELSE
Sequence_of_statements2;
END IF;
(3)在THEN和ELSE子句中还可以再包含IF语句,即IF语句可以嵌套
2. 循环控制语句 LOOP,WHILE-LOOP和FOR-LOOP (1)简单的循环语句LOOP
LOOP
Sequence_of_statements;
END LOOP;
多数数据库服务器的过程化SQL都提供EXIT、BREAK或LEAVE等循环结束语句,保证LOOP语句块能够结束。 (2)WHILE-LOOP
WHILE condition LOOP
Sequence_of_statements;
END LOOP;
(3)FOR-LOOP
FOR count IN [REVERSE] bound1 … bound2 LOOP
Sequence_of_statements;
END LOOP;
3. 错误处理
一、存储过程 过程化SQL块类型
1.存储过程 由过程化SQL语句书写的过程,经编译和优化后存储在数据库服务器中,使用时只要调用即可。 2.存储过程的优点
3.存储过程的用户接口
CREATE OR REPLACE PROCEDURE 过程名([参数1,参数2,...]) AS <过程化SQL块>;
a.过程名:数据库服务器合法的对象标识
b.参数列表:用名字来标识调用时给出的参数值,必须指定值的数据类型。参数也可以定义输入参数、输出参数或输入/输出参数,默认为输入参数
c.过程体:是一个<过程化SQL块>,包括声明部分和可执行语句部分
CALL/PERFORM PROCEDURE 过程名([参数1,参数2,...]);
a.使用CALL或者PERFORM等方式激活存储过程的执行
b.在过程化SQL中,数据库服务器支持在过程体中调用其他存储过程
ALTER PROCEDURE 过程名1 RENAME TO 过程名2;
DROP PROCEDURE 过程名();
二、函数 函数和存储过程的异同
1. 函数的定义语句格式
CREATE OR REPLACE FUNCTION 函数名 ([参数1,参数2,…]) RETURNS <类型> AS <过程化SQL块>;
2. 函数的执行语句格式
CALL/SELECT 函数名 ([参数1,参数2,…]);
3. 修改函数 重命名
ALTER FUNCTION 过程名1 RENAME TO 过程名2;
重新编译
ALTER FUNCTION 过程名 COMPILE;
ODBC优点
一、ODBC概述 1.ODBC产生的原因
2.ODBC
3.ODBC约束力
二、ODBC工作原理概述 1.ODBC应用系统的体系结构 (1)用户应用程序 (2)ODBC驱动程序管理器 (3)数据库驱动程序 (4)数据源
2.ODBC应用程序包括的内容
3.驱动程序管理器:用来管理各种驱动程序
4.主要功能
5.ODBC通过驱动程序来提供应用系统与数据库平台的独立性 6.ODBC应用程序不能直接存取数据库
7.ODBC驱动程序类型 单束
多束
8.数据源:是最终用户需要访问的数据,包含了数据库位置和数据库类型等信息,是一种数据连接的抽象 数据源对最终用户是透明的
三、ODBC API 基础 ODBC 应用程序编程接口的一致性 API一致性
语法一致性
1. 函数概述 ODBC 3.0 标准提供了76个函数接口
2. 句柄及其属性 句柄是32位整数值,代表一个指针 。
ODBC 3.0中句柄分类
应用程序句柄之间的关系
3. 数据类型
四、ODBC的工作流程
1. 配置数据源 方法:
创建数据源—第一步:定义句柄和变量
创建数据源—第二步:初始化环境
创建数据源—第三步:建立连接
创建数据源—第四步
创建数据源—第五步:执行SQL语句
结果集处理步骤
创建数据源—第六步:结果集处理 应用程序中止步骤
创建数据源—第七步:中止处理
2. 初始化环境 3. 建立连接 4. 分配语句句柄 5. 执行SQL语句 6. 结果集处理 7. 中止处理