很多来自网络,自己整理了一下。
☆
概念
利用高级语言的过程性结构来弥补SQL语言实现复杂应用方面的不足。
嵌入SQL的高级语言称为主语言或宿主语言。
在混合编程中,SQL语句负责操作数据库,高级语言语句负责控制程序流程。
预编译方法:由DBMS的预处理程序对源程序扫描,识别出SQL语句,把它们转换成主语言调用语句,以使主语言编译器能识别它,最后由主语言编译器将整个源程序编译成目标码。
☆
嵌入式SQL的一般形式
所有的嵌入式SQL语句都必须加前缀EXEC SQL
在C语言中: EXEC SQL <SQL语句>
例如:EXEC SQL DROP TABLE Student;
☆
嵌入式SQL与主语言的通信
向主语言传递SQL语句执行状态信息,使语言能够据此信息控制程序流程,用SQL通信区(SQLCA【SQL Communication Area】)实现。
主语言向SQL语句提供参数,主要用主变量(Host Variable)实现;
将SQL语句查询数据库的结果交主语言进一步处理,主要用主变量和游标(Cursor)实现。
☆
SQL通信区
SQLCA中有一个存放每次执行SQL语句后返回代码的变量SQLCODE。
每次执行完SQL语句后都应该测试一下SQLCODE的值,以了解该SQL语句执行情况并做相应处理,如果SQLCODE等于预定的常量SUCCESS,则表示SQL语句成功,否则在SQLCODE中存放错误代码。
SQLCA(SQL Communication Access) 系由系统提供之系统记录架构,作为back end与 front end 之间沟通之用,当发生 I/O 状态时,系统会记录该状态于SQLCA 中,front end 即可依据其其内容得知 I/O 运作是否成功,再决定往后执行的步骤。SQLCA 为系统定义之 GLOBAL变量,以下为其架构并介绍其内容与用途:
DEFINE SQLCA RECORD
SQLCODE INTEGER,
SQLERRM CHAR(71),
SQLERRP CHAR(8),
SQLERRD ARRAY[6] OF INTEGER,
SQLAWARN CHAR(8)
END RECORD
.SQLCODE :表示 I/O 的结果
0 表示 I/O 成功
100 表示 NOTFOUND
< 0 表示 I/O 失败
.SQLERRM :保留未用
.SQLERRP :保留未用
.SQLERRD :为一个含有6个INTEGER数组
SQLERRD[1]:保留未用
SQLERRD[2]:新增时 SERIAL 字段所传回之值
SQLERRD[3]:处理资料的笔数
SQLERRD[4]:查询时预估的 CPU COST
SQLERRD[5]:SQL指令之错误位移
SQLERRD[6]:最后一个 ROWID 值
.SQLAWARN :为一个含有8个字符的字符串,以记录I/O时产生的警告讯息。若正确无误,则相对应之字符设定为空白,否则会被设定为"W"。
SQLAWARN[1]:若第2至第8字符中任意一个被设成"W",则此字符亦为"W",否则为空白。
SQLAWARN[2]:若资料太长而被截掉时,会被设成 "W"。
SQLAWARN[3]:若 aggregate function(如 SUM,AVG,MAX,MIN) 处理时遇到 NULL 值,则会被设成"W"。
SQLAWARN[4]:若查询时,若欲查询的字段数目和 INTO 之变量数目不合时,会被设成 "W"。
SQLAWARN[5]:如转换 float 成 integer 时,则会被设成 "W"。
SQLAWARN[6]:保留未用
SQLAWARN[7]:保留未用
SQLAWARN[8]:保留未用
☆
主变量
一个主变量既可是输入主变量也可是输出主变量。
主变量必须在SQL语句EXEC SQL BEGIN DECLARE SECTION与EXEC SQL END DECLARE SECTION之间进行说明。
例如:
EXEC SQL BEGIN DECLARE SECTION;
int i=0;
EXEC SQL END DECLARE SECTION;
SQL语句的主变量名前要加冒号作为标志。
在SQL语句之外,主变量直接引用,不须加冒号。
☆
使用游标查询
EXEC SQL DECLARE cur CURSOR FOR select name,sex from student where no like :no;//定义游标
EXEC SQL OPEN cur;//打开游标
for(;;){
EXEC SQL fetch cur into :name,:sex;//推进游标
if(sqlca.sqlcode==100)//没有满足条件的数据
break;
//操作数据
}
EXEC SQL close cur;//关闭游标
EXEC SQL free cur;//释放游标
☆
使用事务
事务的三个常用操作:开始事务(BEGIN WORK),提交事务(COMMIT WORK),回滚(ROLLBACK WORK),
例如:
EXEC SQL BEGIN WORK;
……//数据库操作
if(sqlca.sqlcode<0)
EXEC SQL ROLLBACK WORK;
else
EXEC SQL COMMIT WORK;
☆
CURRENT形式的UPDATE语句和DELETE语句
UPDATE和DELETE语句都是集合操作,如果只想修改或删除其中的某个记录,则需要用带游标的SELECT语句查出所有满足条件记录,从中进一步找出要修改或删除的记录,然后用CURRENT形式的UPDATE和DELETE语句处理。
用DELCARE语句说明游标。如果是为CURRENT形式的UPDATE语句作准备,则SELECT语句中要用 FOR UPDATE OF<列名>用来指明查询出的数据在指定列是可修改的。如果是为CURRENT形式的DELETE语句作准备,则不必使用上述子句。
检查该记录是否为该修改或删除的记录。如果是,则修改或删除之。这时UPDATE和DELETE语句中要用子句 WHERE CURRENT OF<游标名>,表示修改或删除的是最近一次取出的记录,即游标指针指向的记录。
例如:
char yn;
EXEC SQL BEGIN DELCARE SECTION;
char Sno[20],Sname[20],NEWSname[20];
EXEC SQL END DECLARE SECTION;
EXEC SQL DECLARE cur CURSOR FOR SELECT Sno, Sname FROM Student WHERE Sno like '01%' FOR UPDATE OF Sname;
EXEC SQL OPEN cur
while(1) { /*用循环结构逐条处理结果集中的记录*/
EXEC SQL FETCH cur INTO :Sno,:Sname;
if(sqlca.sqlcode==100)
break; /*若查询结果处理完或出现错误,则退出循环*/
printf("no=%s,name=%s",Sno,Sname);
printf("UPDATE Name(y/n)?"); /*问用户是否需要修改*/
scanf("%c", &yn);
if(yn='y' or yn='Y') /*需要修改*/
{
printf("INPUT NEW Name:");
scanf("%d",&NEWSname);
EXEC SQL UPDATE Student SET Sname = :NEWSname WHERE CURRENT OF cur;
};
};
EXEC SQL CLOSE cur;
☆
数据类型
1、SQL与C数据类型的对应简单类型
SQL C
CHAR(n) char(n+1)
CHARCTER(n) char *
SMALLINT short
INTERGER int
SMALLFLOAT float
FLOAT/DOUBLE double
SERIAL long int
DATE long int
VARCHAR string
2、数据类型转换
转换类型 转换后
FLOAT DECIMAL(16)
SMALLFLOAT DECIMAL(8)
INTERGER DECIMAL(10,0)
SAMLLINT DECIMAL(5,0)
☆
有关CHAR类型的函数
1、以空值结尾的串的操作函数
rdownshift(char *s) 把一个字符串中的所有字母转换成小写形式。
rupshift(char *s) 把一个字符串中的所有字母转换成大写形式。
stcat(char *s, char *dest) 把一个字符串同另一个字符串相连接。
stcmpr(char *s1, char *s2) 比较两个字符串。
stcopy(char *from, char *to) 把一个字符串拷贝到另一个字符串。
stleng(char *string) 统计字符串的长度。
2、定长串的操作函数
bycmpr(char byte1, byte2, rpt len) 比较两组连续的字节内存块。
bycopy(char *from, char *to, int len) 把一块内存的内容拷贝到另一块内存。
byfill(char *to, int len, char ch) 用字符填充指定的内存块。
byleng(char from, int count) 统计有效字符的数目。有效字符是指字符串去除了末尾空格所剩的字符。
3、字符串操作函数
ldchar(char *from, int num, char *to) 拷贝定长串到空值结尾的串。
stchar(char *from, char *to, int num) 拷贝空值结尾的串到定长串。
4、字符串函数简单数值转换
rstod(char *str, double *dblval) 把以空值结束的字符串转换成C的double型
rstoi(char *str, int *intval) 把以空值结束的字符串转换成C的int类型。
rstol(char *str, long *lngval) 把以空值结束的字符串转换成C的long类型。
☆
DATE类型的函数
1、创建内部日期
rdefmtdate(long *jdate, char *frmt char *str) 生成具有确定格式的日期字符串。(str字符串和fmt必须按月、日、年的同一顺序)
返回代码:0操作成功;-1204在str参数中有非法的月份;-1206在str参数中有非法的日期;-1209由于str中没有包含年、月、日各部分间的定界符,str的长度必须准确定义为6或8个字节长;-1212fmt中没有包含年、月、日部分。
fmt和str的有效组合
fmt str
"mmddyy" "DEC 25th 1997"
"mmm.dd.yyyy" "dec 25 1997"
"mmm.dd.yyyy" "DEC-25-1997"
"mmm.dd.yyyy" "12251997"
"mmm.dd.yyyy" "12/25/1997"
"yy/mm/dd" "97/12/25"
"yy/mm/dd" "1997,December, 25th"
"yy/mm/dd" "In the year 1997, the month of December, its 25th day"
"dd-mm-yy" "This 25th day of December, 1997"
rmdyjul(short mdy[3], long *jdate) 用三个短整数生成一个内部日期这三个整数是有关年、月、日的数字值。(年必须以完整的形式表达)
返回代码:0操作成功。 -1204在mdy[2]中有非法年份。 -1205在mdy[1]中有非法月份。 -1206在mdy[0]中有非法日期。
rstrdate(char *str, long *jdate) 将一个字符串日期转换成一内部格式的日期。
rtoday(long *jdate) 从系统日期创建一个内部日期值。
2、从内部日期转换成其他类型
rfmtdate(ling jdate, char *fmt, char *str) 从内部格式的日期类型值创建格式化的字符串。返回代码:0操作成功。 -1210内部日期不能被转换成月-日-年格式。-1211程序存储溢出,即存储分配错误。
rjulmdy(long jdate, short mdy[3]) 从一个内部日期生成一个含有3个短整数的数组对应内部日期的月、日、年。
rdatestr(long jdate, char *str) 从一个内部日期值创建缺省的日期字符串。
rdayofweek(long jdate) 给定一内部格式表示的日期,此函数返回所对应的星期中的某一天。
rleapyear(int year) 用来判断给定的年份是否为闰年。 返回值:TRUE(1)是闰年;FALSE(0)不是闰年
☆
简单数值类型的格式化函数
rfmtdouble(double dbval, char *fmt, char *str) 将双精度格式化为指定的模板格式。
rfmtlong(double longval, char *fmt, char *str) 将长整型值格式化为指定的模板格式。
可以构成格式模板串的字符:
*以星号代替空格。
&以0代替空格。
#代表一个数字或空格的位置。
<左调整,显示一个逗号,仅当左边有数字时才显示。
.显示一个小数点,一个格式模板串只能有一个小数点。
-显示负号,当数字为负的时候显示。
+显示正号,当数字为正的时候显示。
(显示一个负号,同(一起显示负值。
)显示一个负号,同)一起显示负值。
$显示美元符号。
☆
处理空值的数值类型函数
risnull(int type, char *c) 检查C变量是否为空值。
rsetnull(int type, char *c) 给C变量置空值。
☆
其他函数
typalign(int pos, int type) 返回一具有指定数据类型变量的下一个位置。
rtypmsize(int sqltype, int sqllen) 返回你必须分配在存储单元中的指定的C或RDSQLD的字节数。
rtyname(int sqltype) 返回一包含指定RDSQL类型名的以空结尾的串。
rtypwidth(int sqltype, intsqllen) 返回一具有RDSQL类型的值转换为一字符类型时避免截取所需的最小字符数。
posted on 2007-07-23 13:56
破茧而出 阅读(3361)
评论(0) 编辑 收藏 所属分类:
数据库 、
C/C++