一般情况下,SQL语句是嵌套在宿主语言(如C语言)中的。有两种嵌套方式:

1.调用层接口(CLI):提供一些库,库中的函数和方法实现SQL的调用

2.直接嵌套SQL:在代码中嵌套SQL语句,提交给预处理器,将SQL语句转换成对宿主语言有意义的内容,如调用库中的函数和方法代替SQL语句

阻抗不匹配问题:连接SQL语句与常规编程语言的基本问题。SQL核心使用关系数据模型,而C语言等常规语言则使用整型、实数型、算数型、字符型、指针等类型。

一、SQL与宿主语言连接

EXEC SQL关键字提示预处理将由SQL代码进入。

共享变量:实现数据库和宿主语言之间的信息交换。

SQL中共享变量要加冒号,宿主语言中不需要。

SQLSTATE:特殊变量,由5个字符的数组组成(在C中分配空间要分配6个,后面有'\0'),存放表示调用过程出现的问题的代码。'00000'表示没有错误。

1.1 DECLARE节

声明共享变量要在声明节中。

EXEC SQL BEGIN DECLARE SECTION;

...

EXEC SQL END DECLARE SECTION;

EXEC SQL BEGIN DECLARE SECTION;
char studioName[], studioAddr[];
char SQLSTATE[];
EXEC SQL END DECLARE SECTION;

1.2 使用共享变量

任何不含返回结果的SQL语句,都可以用EXEC SQL为前缀嵌入宿主语言。

void getStudio(){
EXEC SQL BEGIN DECLARE SECTION;
char studioName[], studioAddr[];
char SQLSTATE[];
EXEC SQL END DECLARE SECTION; printf("please input studio name:\n");
scanf("%s", &studioName);
printf("please input studio address:\n");
scanf("%s", &studioAddr); EXEC SQL INSERT INTO Studio(name, address)
VALUES (:studioName, :studioAddr);

1.3 连接SQL返回结果到宿主语言

因为阻抗不匹配,使得返回结果无法直接返回到宿主语言中,必须使用下面两种机制中的一个。

单元组选择语句:只有一个结果的查询语句,将该元组存储到共享变量中。

游标:为查询声明一个游标,游标范围覆盖结果关系中的所有元组,每个元组一次被提取到共享变量,由宿主语言处理。

1.4单元组选择语句

类似于普通的select-from-where语句,只是SELECT子句后面紧跟着关键字INTO和一连串的共享变量。如果结果少于或多于一个元组,则共享变量中不会有值,且SQLSTATE中存入一个错误码。

void printNetWorth(){
EXEC SQL BEGIN DECLARE SECTION;
char studioName[];
int presNetWorth;
char SQLSTATE[];
EXEC SQL END DECLARE SECTION; /*输入studioName的代码*/ EXEC SQL SELECT netWorth
INTO :presNetWorth
FROM Studio, MovieExec
WHERE presC# = cert# AND
Studio.name = :studioName; /*检查SQLSTATE中的代码是否为'00000'*/
}

1.5 游标

游标声明:

EXEC SQL DECLARE 游标名称 CURSOR FOR 查询

初始化游标的位置:使之指向第一个元组

EXEC SQL OPEN 游标名称

得到下一个元组:

EXEC SQL FETCH FROM 游标名称 INTO 变量列表

变量列表中存放获取的结果,如果已经遍历结束则SQLSTATE中返回'02000'

关闭游标:

EXEC SQL CLOSE 游标名称

void worthRanges(){
int i, digits, counts[];
EXEC SQL BEGIN DECLARE SECTION;
int worth;
char SQLSTATE[];
EXEC SQL END DECLARE SECTION;
EXEC SQL DECLARE execCursor CURSOR FOR
SELECT netWorth FROM MovieExec; EXEC SQL OPEN execCursor;
for(i = 1; i < 15; i++)
counts[i] = 0;
while(1){
EXEC SQL FETCH FROM execCursor INTO :worth;
if(NO_MORE_TUPLES)
break;
digits = 1;
while((worth /= 10) > 0) digits++;
if(digits <= 14) counts[digits]++;
}
EXEC SQL CLOSE execCursor;
for(i = 1; i < 15; i++)
printf("digits = %d: number of execs = %d\n",i, counts[i]);
}

1.6 游标更新

可以通过游标删除或修改当前的元组。

WHERE后只能是 WHERE CURRENT OF

下面的例子将资产少于1000的删除,多余1000的翻倍。

#define NO_MORE_TUPLES !(strcmp(SQLSTATE,"02000"))

void changeWorth(){
EXEC SQL BEGIN DECLARE SECTION;
int certNo, worth;
char execName[], execAddr[], SQLSTATE[];
EXEC SQL END DECLARE SECTION;
EXEC SQL DECLARE execCursor CURSOR FOR MovieExec; EXEC SQL OPEN execCursor;
while(1){
EXEC SQL FETCH FROM execCursor INTO :execName, :execAddr, :certNo, :worth;
if(NO_MORE_TUPLES) break;
if(worth < 1000)
EXEC SQL DELETE FROM MovieExec
WHERE CURRENT OF execCursor;
else
EXEC SQL UPDATE MovieExec
SET netWorth = 2 * netWorth
WHERE CURRENT OF execCursor;
}
EXEC SQL CLOSE execCursor;
}

1.7 避免并发修改

如果在游标获取到元组到游标关闭前,不希望元组发生变化:

EXEC SQL DECLARE 游标名 INSENSITIVE CURSOR FOR 查询;

不希望通过游标修改元组

EXEC SQL DECLARE 游标名  CURSOR FOR 查询 FOR READ ONLY

1.8动态SQL

在运行时,通过输入SQL语句实现查询需要动态SQL语句支持。

EXEC SQL PREPARE V FROM 表达式;

EXEC SQL EXECUTE V; //这句可以多次执行 表明表达式V执行了多次

上面两句合并后可以写成:

EXEC SQL EXECUTE IMMEDIATE 表达式;

void readQuery(){
EXEC SQL BEGIN DECLARE SECTION;
char * query;
EXEC SQL END DECLARE SECTION; /*输入SQL语句,放入query中*/ EXEC SQL PREPARE SQLquery FROM :query;
EXEC SQL EXECUTE SQLquery;
}

【SQL】宿主语言接口的更多相关文章

  1. [转]SQLITE3 C语言接口 API 函数简介

    SQLITE3 C语言接口 API 函数简介 说明:本说明文档属作者从接触 SQLite 开始认识的 API 函数的使用方法, 由本人翻译, 不断更新. /* 2012-05-25 */ int sq ...

  2. 基于Oracle OCI的数据访问C语言接口ORADBI .

    基于Oracle OCI的数据访问C语言接口ORADBI cheungmine@gmail.com Mar. 22, 2008   ORADBI是我在Oracle OCI(Oracle 调用接口)基础 ...

  3. Swift中对C语言接口缓存的使用以及数组、字符串转为指针类型的方法

    由于Swift编程语言属于上层编程语言,而Swift中由于为了低层的高性能计算接口,所以往往需要C语言中的指针类型,由此,在Swift编程语言刚诞生的时候就有了UnsafePointer与Unsafe ...

  4. C语言接口与实现实例

    一个模块有两部分组成:接口和实现.接口指明模块要做什么,它声明了使用该模块的代码可用的标识符.类型和例程,实现指明模块是如何完成其接口声明的目标的,一个给定的模块通常只有一个接口,但是可能会有许多种实 ...

  5. SQL设置语言,返回中文”星期几”格式

    SQL中语言表: SELECT * FROM sys.syslanguages   eg: SET LANGUAGE 简体中文 --设置语言 PRINT DATENAME(weekday,GETDAT ...

  6. SQL Server数据库(SQL Sever语言 CRUD)

    使用SQL Sever语言进行数据库的操作 常用关键字identity 自增长primary key 主键unique 唯一键not null 非空references 外键(引用) 在使用查询操作数 ...

  7. 18 A GIF decoder: an exercise in Go interfaces 一个GIF解码器:go语言接口训练

    A GIF decoder: an exercise in Go interfaces  一个GIF解码器:go语言接口训练 25 May 2011 Introduction At the Googl ...

  8. SQLAlchemy 学习笔记(一):Engine 与 SQL 表达式语言

    个人笔记,如有错误烦请指正. SQLAlchemy 是一个用 Python 实现的 ORM (Object Relational Mapping)框架,它由多个组件构成,这些组件可以单独使用,也能独立 ...

  9. opencv的C语言接口和C++接口差别(入门篇)

    opencv是一个开源的图像处理库,最经典的1.0版本号提供的接口都是C语言接口. 后来的opencv2.x版本号保留了C语言接口,可是提供了C++接口,当中的C语言接口仅仅是为了向后兼容,而C++接 ...

随机推荐

  1. Go基础篇【第6篇】: 内置库模块 flag

    import "flag" flag包实现了命令行参数的解析.每个参数认为一条记录,根据实际进行定义,到一个set集合.每条都有各自的状态参数. 在使用flag时正常流程: 1.  ...

  2. 使用IMAGEMAGICK的CONVERT工具批量转换图片格式

    使用IMAGEMAGICK的CONVERT工具批量转换图片格式 http://www.qiansw.com/linux-imagemagick-convert-img.html Home > 文 ...

  3. WCF服务全局异常处理机制

    服务端增加WCF服务全局异常处理机制,任一WCF服务或接口方式出现异常,将统一调用WCF_ExceptionHandler.ProvideFault方法,因此不需要每个方法使用try catch写法. ...

  4. delphi中写SQL语句中变量的注意事项

    1.procedure TForm1.btn1Click(Sender: TObject); var   s: String; begin   S := 'select * from TMarketI ...

  5. Delphi 之 编辑框控件(TEdit)

    TEdit 组件主要用于数据的输入和显示和编辑等操作. AutoSelect 获取组件焦点.该属性只能在单行文本组件使用.值为True为选中.false则不选中. BorderStyle 设置编辑框控 ...

  6. BZOJ4327 JSOI2012玄武密码(AC自动机)

    当然可以在SA上二分答案,但看起来会被卡log.考虑对模板串建出AC自动机,用母串在上面跑,标记上所有能到达的点.注意到达某个点时需要标记所有其通过fail指针可以走到的点,如果遇到一个标记过的点就可 ...

  7. 【题解】HNOI2009无归岛

    这题真的是无语了,在哪个岛上根本就没有任何的用处……不过我是画了下图,感受到一定是仙人掌,并不会证.有谁会证的求解…… 如果当做仙人掌来做确实十分的简单.只要像没有上司的舞会一样树形dp就好了,遇到环 ...

  8. taotao购物车

    功能分析: 1.在用户不登陆的情况下也可以使用购物车,那么就需要把购物车信息放入cookie中. 2.可以把商品信息,存放到pojo中,然后序列化成json存入cookie中. 3.取商品信息可以从c ...

  9. 深入理解Java虚拟机—内存管理机制

    前面说过了类的加载机制,里面讲到了类的初始化中时用到了一部分内存管理的知识,这里让我们来看下Java虚拟机是如何管理内存的. 先让我们来看张图 有些文章中对线程隔离区还称之为线程独占区,其实是一个意思 ...

  10. POJ1637:Sightseeing tour(混合图的欧拉回路)

    Sightseeing tour Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 10581   Accepted: 4466 ...