posts - 108,comments - 56,trackbacks - 0
    很多来自网络,自己整理了一下。

    ☆概念
  利用高级语言的过程性结构来弥补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 破茧而出 阅读(3345) 评论(0)  编辑  收藏 所属分类: 数据库C/C++

只有注册用户登录后才能发表评论。


网站导航: