3.7 嵌入式SQL

可以放入所有高级语言中去,如C

因为,SQL是过程性语句,需要高级语言的非过程性处理集合的分类处理

一、一般形式

  • 所有的SQL语句都必须加前缀EXEC SQL
  • SQL语句完成结束标志(;或END EXEC)
EXEC SQL<SQL语句>;
EXEC SQL<SQL语句> END EXEC

例:

EXEC SQL drop table Student;

二、嵌入式SQL语言与主语言之间的通信

  • 向主语言传递SQL语言的执行状态信息,使主语言能够根据此信息控制程序流程,主要使用SQL通信区(SQLCA);
  • 主语言向SQL语句提供参数,主要用主变量实现;
  • 将SQL语句查询数据库结果交主语言进行处理,主要用主变量和游标实现。

1.SQL通信区(SQLCA)

1)用EXEC SQL INCLUDE SQLCA进行定义;

2)每执行完一条SQL语句应测试返回代码SQL CODE的值,以了解执行情况并做相应处理

SQLCODE

=0:SQL语句执行成功,并满足条件的记录;

=100:SQL语句处理完最后一条满足条件的记录或者是数据库中没有满足条件的记录;

<0:SQL语句执行出错

2.主变量

主变量:SQL语句中使用的主语言程序变量

指示变量:指示变量的值或条件

  • 必须在SQL语句BEGIN DECLARE SECTION与END DECLARE SECTION之间进行说明;
  • 主变量可以在SQL语句中任一能够使用表达式的地方出现
  • SQL语句中的主变量名前要加上冒号(:)作为标志,与数据库对象区别
  • SQL语句之外,主变量和指示变量可以直接引用

3.游标:

用来协调SQL语言和主语言之间的处理速度失调问题(SQL语言:面向集合,可产生或处理多条记录    主语言:面向记录,只能存放一条记录)

系统为用户开设的一个数据缓冲区,存放SQL语句的结果。每个游标区都有一个名字,用户可通过游标逐一获取记录,并赋予主变量,交给主语言进一步处理

例:

exec sql include salca;
exec sql bedin declare section;
char Sno(5);
char Cno(3);
int Grade;
exec sql end declare section;
main()
{
exec sql declare c1 cursor for select Sno,Cno,Grade from SC;
exec sql open c1;
for(;;)
{
exec sql fetch c1 into :Sno,:Cno,:grade;
if(sqlCode!=0)
break;
printf("Sno:%s,Cno:%s,Grade:%d\n",:Sno,:Cno,:Grade);
}
exec sql chose c1;
}

三、不用游标的的SQL语言

  • 说明性语句
exec sql begin declare section;
exec sql end declare section;
  • 数据定义语句
exec sql create...
exec sql drop...
  • 数据控制语句
exec sql grant...
exec sql revoke...
  • 查询结果为单记录的select语句

1)用into子语句制定查询结果的存放变量

2)into语句,where语句,having短语中均可使用主变量

3)查询结果若为多记录则出错

exec sql select Sno,Sname,Sage,Sdept into:Sno,:Sname,:Sage,:Sdept from SC where Sno=: give Sno and Cno=:give Cno;
  • 非current形式的update语句
exec sql update SC set Grade=Grade+:raise where Cno='';
exec sql update Student set Sage=null where Sdept='CS'
  • 非current形式的delete语句
exec sql delete from SC where Sno=(select Sno from Student where Sname=:stdna);
  • insert语句

gradeid=-1;    指示变量

exec sql insert into SC(Sno,Cno,Grade) values (:Sno,:Cno,:Grade,:gradeid);

四、使用游标的SQL语言

  • 查询结果为多条结果的select语句
exec sql begin declare section;
...
exec sql end declare section;
...
exec sql declare SX cursor for select Sno,Sname,Sage,Ssex from Student where Sdept =:deptname;//说明游标
while(gets(deptname)!=null)
{
exec sql open SX;//打开游标
while(1)
{
exec sql fecth SX into :Sno,:Sname,:Sage,:Ssex;//推进游标指针并取当前记录
if(sqlcode=100)
break;
}
if (sqlcode<0)
{printf("error\n");
break;
}
...
};
exec sql close SX;//关闭游标
};
...
  • current形式的update和delete语句
exec sql  begin declare section;
...
exec sql end declare section;
...
Gets(deptname);
exec sql declare SX cursor for select Sno,Sname,Sage,Ssex from Student where Sdept=:deptname for update of Sage;//声明游标
exec sql open SX;//打开游标,进入缓冲区
while(1)
{
exec sql fetch SX into :Sno,:Sname,:Sage,:Ssex;//推进游标指针并取当前记录
if(sqlcode!=0)break;
printf("%s,%s,%d,%s\n",Sno,Sname,Sage,Ssex);
printf("update age?\n");
scanf("%c",&yn);
if(yn='y' or yn='Y')
{
print ("input new age;");
scanf("%d",&newage);
exec sal update Student set Sage =:newage where current of SX;
};
...
};
exec sql close SX;//关闭游标
...
上一篇:【转】Js获取当前日期时间及其它操作


下一篇:HashMap 之弱引用 - WeakHashMap