SQL系统环境
- 格式:docx
- 大小:21.02 KB
- 文档页数:9
第8章SQL系统环境
本章主要讨论数据库的设计步骤以及每个步骤用到的方法。
数据库的设计主要有四个步骤:需求分析、概念设计、逻辑设计和物理设计。
本章的主要知识点包括:
学习要点1、嵌入式SQL
学习要点2、有关事物的嵌入式SQL
学习要点3、SQL环境
学习要点4、数据库的完整性
学习要点5、SQL中的平安和用户权限
学习要点1、嵌入式SQL
1、什么是嵌入式SQL
当一个程序既要访问数据库,又要处理数据时,把SQL语言嵌入程序设计语言即宿主语言中,将SQL语言访问数据库的功能和宿主语言的数据处理功能相结合,是目前解决该问题的最有效途径。这样使用的SQL称为嵌入式SQL。
2、如何实现嵌入式SQL对于不同的DBMS和宿主语言,实现嵌入式SQL的方法根本相同,只是在一些特殊的地方略有差异。实现嵌入式SQL语言主要是实现说明局部的嵌入和执行局部的嵌入。
以SQL嵌入C语言为例说明实现嵌入式SQL的方法。说明局部C语言和SQL语言之间是通过共享变量来进行数据的传送。
共享变量是由宿主语言程序定义、用SQL的DECLARE语句说明,以后可在SQL语句中引用的宿主语言变量。
共享变量需用以“EXEC SQL〞为前缀的说明语句说明,在说明语句的结尾加“;〞。
在SQL语句中引用共享变量时,每个共享变量前要加“:〞。
在共享变量中,有一个系统定义的特殊变量,称为SQLSTA TE。在每执行一个SQL语句时,都要返回一个SQLSTA TE代码,来表示这个SQL语句是否执行成功等情况。
当SQLSTATE为全零时,表示SQL语句执行成功;
当SQLSTATE为“02000〞时,表示SQL语句已执行,但未找到元组。所有SQL语句中用到的共享变量,除系统定义的〔例如SQLSTA TE〕以外,都必须在宿主程序中进行说明。说明语句的开头行为:
EXEC SQL BEGIN DECLARE SECTION;
说明语句的结束行为:
EXEC SQL END DECLARE SECTION;
在一个说明语句中定义几个共享变量,它们都是按照C语言的数据类型和格式进行定义的。
EXEC SQL BEGIN DECLARE SECTION;
char sno[6],sname[20];
int sage;
char SQLSTATE[6];
EXEC SQL END DECLARE SECTION;
执行局部
插入语句的格式为:
EXEC SQL INSERT
INTO Student (StudentNo,StudentName)
V ALUES (:sno, :sname);
修改语句的格式为:
EXEC SQL UPDA TE Student
SET (StudentName=:sname,StudentAge=:sage)
WHERE StudentNo=:sno;删除语句的格式为:
EXEC SQL DELETE
FROM StudentCourse
WHERE StudentNo=
(SELECT StudentNo FROM Student
WHERE StudentName=:sname〕;
查询语句:
当查询的结果只有一个元组时,
EXEC SQL SELECT StudentName,StudentDept INTO :sname,:sdept FROM Student WHERE StudentNo=:sno;
当查询的结果有多个元组时,需采用涉及到游标的查询方法。
3、使用游标的SQL编程利用游标进行查询需要四种语句:说明游标语句、翻开游标语句、推进语句和关闭游标语句。分析学生成绩的分布情况。首先从StudentCourse中取出每个元组的Grade;其次设置游标scCursor复盖这些元组;然后翻开游标,使之处于初始位置;随后,推进游标,取出一个单分量元组放入共享变量grade;接着,确定该成绩属于哪一段,并在相应的统计上加1;不断推进游标,重复上述统计过程,直到元组全部取完,再关闭游标;最后打印统计结果。
举例:
假设分析学生成绩的分布情况,把统计结果划分为11段:0-9,10-19,20-29 (90)
-99,100。
首先从StudentCourse中取出每个元组的Grade;其次设置游标scCursor复盖这些元组;然后翻开游标,使之处于初始位置;随后,推进游标,取出一个单分量元组放入共享变量grade;接着,确定该成绩属于哪一段,并在相应的统计上加1;不断推进游标,重复上述统计过程,直到元组全部取完,再关闭游标;最后打印统计结果。程序如下:#define NO-TUPLE !(strcmp(SQLSTA TE,"02000"))
void gradeSection()
{
int i,section,count[11];
EXEC SQL BEGIN DECLARE SECTION;
int grade;
char SQLSTATE[6];
EXEC SQL END DECLARE SECTION;
EXEC SQL DECLARE sc Cursor CURSOR FOR
SELECT Grade FROM SC;
EXEC SQL OPEN scCursor;
for(i=0;i<11;i++) count[i]=0;
while(1){
EXEC SQL FETCH FROM scCursor INTO:grade;
if (NO-TUPLE) break;
section=grade/10;
count[section]++;
}
EXEC SQL CLOSE scCursor;
for(i=0;i<11;i++)
cout<<"Section="<
<<" number="< }; 学习要点2、有关事物的嵌入式SQL 在集中选课的时间里,学生可以在能连接到数据库上的成百上千台计算机上同时对一个数据库进行操作。在同一时间里,数据库中完全有可能存在相互影响的两个或者更多的操作。如果对这些操作的顺序没有限制,那么它们之间的相互影响就有可能产生错误。 1、事务假定某门课的选课余额为1,这时,同时有两名学生进行了上面的查询。结果两名学生都选上了这门课,并分别把选课余额由1修改为0。把一个选课的名额送给两个学生显然是不妥当的。 解决这个问题的方式就是当一个函数正在执行的时候,限制另一个函数,不能让它也执行。这种方式执行的两个函数是串行的。SQL中的机制就是使两个函数的执行实现串行化。 EXEC SQL BEGIN DECLARE SECTION; int cNo; char cName[20]; int nLeft; EXEC SQL END DECLARE SECTION; void ChooseCourse(){ cout<<; cin >> cNo; EXEC SQL SELECT numLeft INTO :nLeft FROM Course WHERE courseNo=:cNo; if(nLeft>0){ EXEC SQL UPDA TE Course SET numLeft=numLeft-1 WHERE courseNo=:cNo; cout << “你已经选定了这门课。〞; EXEC SQL COMMIT; } else{ cout << “选课人数已满。〞; EXEC SQL ROLLBACK; } } 除了两个或者多个数据库操作同时执行有可能影响到结果的正确性之外,单个操作如果在执行过程中由于软件或是硬件的“崩溃〞,也有可能产生错误的结果。