Claws Garden

数据库——嵌入式SQL

嵌入式SQL

简介

嵌入式SQL,指的是嵌入其他程序语言,如COBOL, C/C++, JAVA等语言中的SQL语句,简称为ESQL。与之对立的是交互式SQL,即直接在终端和数据库进行交互式访问,简称ISQL。

例如下面是一段C语言中嵌入式SQL的例子:

1exec sql select count(*) into :host_var from customers;

使用ESQL时主要有以下几个部分:

例如在上面的小例子中,host_var就是个宿主变量,前面加:来区分。这些宿主变量在ESQL语句中使用之前都需要经过特殊的声明。

声明

声明部分用来声明在ESQL语句中将要使用到的宿主变量。

来根据一个例子看一下声明的格式:

1exec sql begin declare section;
2	char cust_id[5];
3	char cust_name[14];
4	float cust_discnt;
5	char user_name[20],user_pwd[20];
6exec sql end declare section;

在声明的开始和结束都有说明。

条件处理

很重要的一个方法就是whenever语句,第二部分会详细说明。

连接数据库

sql99中连接数据库的语句:exec sql connect to @hocalhost (as connect_name) (user root); 或者也可以直接通过exec sql connect to default; 连接到默认数据库。

Oracle里连接数据库的语句是:exec sql connect to :user_name identified by :user_pwd;

断开数据库

sql99中断开数据库语句:exec sql disconnect connect_name; 或者exec sql disconnect current;

需要注意的是,在断开数据库连接之前,务必通过exec sql commit work;提交修改结果或者通过exec sql rollback work;撤销更改。

Oracle中则将提交或撤销和数据库断开合并为了一条语句:exec sql commit release;或者exec sql rollback release;

游标 Cursor

可以协助选择多行。其实是每次选择一行,但是可以滚动,类似迭代器。

使用步骤包括:

  1. 声明游标
  2. 打开游标
  3. 用游标取结果集
  4. 关闭游标

直接通过一个例子说明:

 1//声明游标
 2exec sql declare agent_dollars cursor for 
 3    select aid, sum(dollars)
 4    from orders
 5    where cid = :cust_id
 6    group by aid;
 7
 8//打开游标
 9exec sql open agent_dollars;
10
11//使用游标取结果集
12exec sql whenever not found goto finish;//条件控制
13while(true){
14    exec sql fetch agent_dollars into :agent_id, :dollar_sum;
15    printf(agent_id,dollar_sum);
16}
17finish: exec sql close agent_dollars;//关闭游标

条件处理

通过whenever语句完成异常的判断和处理。whenever语句的格式是:exec sql whenever condition action; 其中condition有三种,而action有四种。

条件语句语句一旦声明,后面的直到遇到下一条条件处理语句,都是它的作用域。作用域中的每一条sql语句执行后都会按照条件进行检查。

三种条件:

四种动作:

whenever条件处理语句的作用域是按照语句写在代码里的位置决定的。

指示器变量可以用来代指空值(indicator=-1)。

通用ESQL语句

数据类型兼容表:

Basic sqlOracle typeDB2/UDB typeC data type
char(n)char(n)char(n)char arr[n+1]
varchar(n)varchar(n)varchar(n)char arr[n+1]
smallintsmallintsmallintshort int
integer, intinteger, int, number(10)integer, intint
realrealrealfloat
double precision, floatdouble precision, number, floatdouble precision, double, floatdouble

Select

1exec sql
2    select ...
3    into ...
4    from ...
5    (where condition);

声明游标

1exec sql
2    declare cursor_name cursor for subquery
3    (order by...)
4    (for read only/update(colname,...));

Delete

1exec sql
2    delete from tablename (corr_name)
3    (where condition / where current of cursor_name);

corr_name指的是表的别名

Update

1exec sql
2    update tablename (corr_name)
3    set column_name = expresion...
4    (where contion / current of cursor_name);

Insert

1exec sql
2    insert into tablename (column_name ... )
3    values (....)

和ISQL里面的插入基本相同。

事务 Transaction

将一些语句打包成一个事务可以避免多个用户同时存取数据库的时候出现类似多线程数据不同步的错误。打包的事务一旦开始执行就不能被打断,直到整个事务执行完毕。

可以通过exec sql set transaction isolation level serializable;类似的语句声明事务的开始。

动态SQL

有三种类型:

另外还有一些高级概念。。。但是不是重点,就不赘述了。

#数据库课程