数据库笔记(上)

❤️❤️❤️
数据模型(模型⬅️模式⬅️数据)
模式:外模式(子模式)、概念模式(全局模式)、内模式(存储模式)    //E-C映像(外模式到概念模式)、C-I映像(概念模式到内模式)
三层模式、两层映像实现了逻辑独立性和物理独立性

三种经典模型
关系模型:表的形式组织数据    //消除了层次模型和网状模型的指针
层次模型:树的形式组织数据
网状模型:图的形式组织数据    //层次模型和网状模型已经用的不多了,数据之间的关联关系由复杂的指针系统来维系,结构描述复杂

简要发展史:
数据库技术探索阶段    //Data Base
数据库技术确立阶段    //三大数据库提出
数据库技术成熟阶段    //标准化数据库系统结构模型 关系DB迅速发展和理论日臻完善
数据库技术深化发展阶段

操作系统➡️文件系统(以记录为单位)➡️数据库(引入数据库管理系统DBMS,数据存取以记录为单位,以数据项和记录集合为单位)
关系数据库(必须满足关系的第一范式:数据不可再分)➡️对象-关系数据库➡️面向对象数据库
XML数据库(半结构化数据库):数据与数据的语义合并在一起进行存储和处理,面向数据交换
ODBC和JDBC(java环境下):实现多种多样的数据库开放式互连
新型数据库:数据库与各种先进技术结合形成的    //NoSQL

关系模型:
三个组成:各种数据的基本结构形式、Table与Table之间的关系运算、操作应该遵循的约束条件
三个要素:基本结构、基本操作(并、差、积、选择、投影、交、连接、除)、完整性约束

Table:
表/关系            //关系:一组域的笛卡尔积的子集    //关系中元组的数目成为关系的基数
行/元组/记录        //笛卡尔积:从n个域形成所有可能组成的n元组的集合
列/字段/属性/数据项    //列的取值范围:域    //属性名与域名不同

关系模式和关系:
关系模式是稳定的,关系是某一时刻的值

关系的特性:
列是同质的
不同列可以来自同一个域,称其中每一列为一个属性
区分哪一列靠列名、区分哪一行靠某一或某几列的值
理论上,关系的任意两个元组不能完全相同    //Table和关系有一点点差别,表可以重复
!!!关系第一范式:属性不可再分特性

第一范式(1NF):无重复的列
第二范式(2NF):非主属性完全依赖于主键
第三范式(3NF):属性不依赖于其他非主属性


候选码/候选键:
关系中的一个属性组,其值能唯一标识一个元组,若从该属性组中去掉任何一个属性,它就不具有这一性质了,这样的属性组称作候选码        //当有多个候选码时,可以选定一个“主码”
包含在任何一个候选码中的属性被称为“主属性”,其他的称为“非主属性”
所有属性构成这个关系的候选码,称为“全码”

外码/外键:
一个组的非主属性,是另一个组的主属性

完整性:
实体完整性-关系中的主码的属性值不能为空值(不知道、不存在或无意义的值)
参照完整性-外码可以取空值,或者必须取其主码中的取值
用户自定义完整性-用户针对具体的应用环境定义的完整性约束条件

关系代数:    //集合操作(并、交、差、笛卡尔积)、纯关系操作(投影、选择、连接、除)
并相容性-两个关系及其相关属性之间有一定的对应性、可比性或意义

基本操作:
并:将两个关系的元组合并成一个关系,在合并时去掉重复的元组
差:R-S,它由出现在关系R中但不在关系S中的元组组成的关系
广义笛卡尔积:R*S,关系R中的元组与关系S中的元组进行所有可能的拼接构成
选择:从关系R中选择出满足给定条件conditon的元组构成    //保留所需的行
投影:从关系R中选出属性包含在A中的列构成    //保留所需的列

扩展操作:
交:它由同时出现在关系R和关系S中的元组构成
连接:它由关系R和关系S的笛卡尔积中,选取R中属性A与S中属性B之间满足连接条件的元组构成    //等值连接(值相等)、自然连接(属性相同且值相等)

复杂扩展操作:
除:R/S,关系R中属性减去关系S中属性        //新元组:R/S的结果元组与关系S中每一个元组组合,与关系R元组都相同则保留    //能够整除的留下来
外连接:两个关系R和S进行连接时,如果关系R中元组在关系S中找不到相匹配的元组,为了避免元组信息丢失,从而将R元组与S中假定存在的全为空值的元组形成连接
外连接形式分为左外连接、右外连接、全外连接

❤️❤️❤️
关系演算:    //SQL语言是继承了关系代数和关系演算各自的优点形成的        //关系演算基于逻辑思维
存在量词、全称量词:元组变量t前有存在量词或者全称量词,则该变量称为约束变量,否则称为自由变量
关系演算包括元组演算和域演算        //元组演算和域演算可以等价交换互换
元组演算和关系代数可以相互转换(有前提)

域演算语言QBE:非过程化语言        //关系名区、属性名区、操作命令区、查询条件区(操作框架)
Print或P.:显示输出操作
Delete或D.:删除操作
Insert或I.:插入操作
Update或U.:更新操作

关系演算的安全性:不产生无限关系和无穷验证的运算是安全的
关系代数是一种集合运算,是安全的
关系演算不一定是安全的        //施加约束条件

关系运算比较总结:
关系代数:以集合为对象的操作思维
元组演算:以元组为对象的操作思维
域演算:以域变量为对象的操作思维
三种运算之间是等价的        //关系代数与“安全的元组演算表达式”与“安全的域演算表达式”是等价的
三种关系运算都是非过程的    //域演算的非过程性最好,元组演算次之
三种关系运算是抽象的,但却是衡量数据库语言完备性的基础

❤️❤️❤️
SQL语言概述:        //交互式SQL➡️嵌入式SQL➡️动态SQL
SQL语言是集DDL、DML和DCL于一体的数据库语言
DDL:数据定义语言
DML:数据操作语言
DCL:数据控制语言

主要由九个单词引导的操作语言:
DDL:Create(建立)、Alter(修改)、Drop(撤销)
DML:Insert、Delete、Update、Select
DCL:Grant(授权)、Revoke(取消授权)

创建数据库:create database 数据库名;
创建Table:create table 表名(列名 数据类型【primary key|unique】【not null】,列名 数据类型...);
(primary key:主键约束(只能定义一个) unique:唯一性约束(可以定义多个) not null:非空约束)
添加元组:insert into 表名(列名,列名,...)values(属性值,属性值,...);
添加元组省略版:insert into 表名 values(属性值,属性值,...);
批量添加元组:insert into 表名 子查询;
检索语句:select 列名 from 表名【where 检索条件】【order by 列名【asc|desc】】;
多表联合查询:select 列名 from 表名1,表名2,... where 检索条件;
删除元组:delete from 表名【where 条件表达式】;
更新元组:update 表名 set 列名=表达式,...【where 条件表达式】;

模糊查询:
在检索条件中引入运算符like来表示:列名 【not】 like "字符串"
"%":匹配零个或多个字符
"_":匹配任意单个字符
"\":转义字符

表别名/表别名:
select 列名 as 列别名 from 表名1 as 表别名1,表名2 as 表别名2,...where 检索条件;    //as可以省略

创建表的示例:
1.
create table student(S# char(8) not null, Sname char(10), Ssex char(2), Sage integer, D# char(2), Sclass char(6));
2.
Create table course(C# char(3), Cname char(12), Chours integer, Credit float(1), T# char(3));

添加元组示例:
1.
insert into Student(S#, Sname, Ssex, Sage, D#, Sclass) values('9830', '张四', '女', 20, '03', '98301');
2.
insert into Course values('001', '数据库', 40, 6, '001');

检索语言示例:
1.    
select Sage,Sname from Student where Sage<=19;
2.    //筛选查询
select S# from SC where C#='001' or C#='002';
3.    //去重
select distinct S# from SC where Score>80;    //distinct去重效果
4.    //排序查询
select distinct S# from SC where Score>80 and C#='002' order by Score desc;
5.    //模糊查询
select S#, Sname from Student where Sname like '张%';
6.    //多表连接
select Sname from Student, SC where Student.S#=SC.S# and SC.C#='001' order by Score DESC;
7.    //不等值连接
select T1.Tname as Teacher1, T2.Tname as Teacher2 from Teacher T1, Teacher T2 where T1.Salary>T2.Salary;
8.    //自连接
select S1.S# form SC S1, SC S2 where S1.S#=S2.S# and S1.C#='001' and S2.C#='002';
9.    //批量插入
insert into St(S#, Sname) select S#, Sname from Student where Sname like '%伟';
10.    //删除语句
delete from Student where S# in(select S# from SC where Score<60 group by S# Having Count(*)>=4);
11.    //更新操作
update Teacher set Salary=Salary*1.1 where D# in(select D# from Dept where Dname='计算机');

修正数据库:
alter table tablename
【add {列名 数据类型,...}】    //增加新列
【drop{完整性约束名}】    //删除完整性约束
【modify{colname datatype,...}】    //修改列定义
示例:
1.
alter table student add Saddr char(40), PID char(18);
2.
alter table student modify Sname char(10);
3.
alter table student drop unique(Sname);

撤销表:drop table 表名;
撤销数据库:drop database 数据库名;

指定当前数据库:use 数据库名;
关闭当前数据库:close 数据库名;

❤️❤️❤️
(not)in子查询:
表达式 【not】in (子查询)
示例:
1.
select * from student where Sname in("张三","王三");
2.
select S#, Sname from student where S# in(select S# from SC C#=‘001’);
3.
select S# from SC where C#=‘001’ and S# in(select S# from SC where C#=‘002’);
4.
select Sname from student where S# not in(select S# from SC,Course C,Teacher T where T.Tname=‘李明’andSC.C#=C.C#andT.T#=C.T#);

相关子查询:
外层向内层传递的参量需要使用外层的表名或表别名来限定        //只能外层向内层传递参数

some/all子查询:
表达式 比较运算符 some (子查询)    //有一个值比较,满足则为真
表达式 比较运算符 all (子查询)    //所有值比较,满足则为真
示例:
1.
select Tname from Teacher where Salary<=all(select Salary from Teacher);
2.
select S# from SC where C#=‘001’ and Score<some(select Score from SC where C#='001');
3.    //涉及相关子查询    
select Sname from Student where 60>all(select score from SC where S#=Student.S#);

等价变换:
表达式=some(子查询) 等于 表达式in(子查询)
表达式not in(子查询) 等于 表达<>all(子查询)

(not)exists子查询:
表达式 【not】exists (子查询)
示例:
1.
select distinct Sname from Student where exists(select * from SC,Course,Teacher where SC.C#=Course.C#and SC.S#=Student.S#and Coure.T#=Teacher.T#and Tname='赵san');
2.
select Sname from Student where not exists(select * from Course where Coure.T#='001' and not exists(select * from SC where S#=Student.S# and C#=Course.C#));

结果计算与聚集计算:
示例:
1.
select T1.Tname as TR1,T2.Tname as TR2,T1.Salary-T2.Salary from Teacher T1,Teacher T2 where T1.Salary>T2.Salary;
2.
select S.S#,S.Sname,2015-S.Sage+1 as Syear from Student S;

聚集函数:
count:求个数
sum:求和
avg:求平均
max:求最大
min:求最小
示例:
1.
select sum(Salary) from Teacher;
2.
select avg(Score) from Course C,SC where C.Cname='数据库' and C.C#=SC.C#;

分组查询与分组过滤:
select 列名...    from 表名1... 【where 检索条件】【group by 分组条件【having 分组过滤条件】】;        //没有group by不能有having

示例:
1.    //求每个学生的平均成绩
select S#,avg(Score) from SC group by S#;
2.    //求每个课程的平均成绩
select S#,avg(Score) from Sc group by C#;
3.    //求不及格课程超过两门的同学的学号
select S# from SC where Score<60 group by S# having count(*)>2;
4.    //求有10人以上不及格的课程号
select C# from SC where Score<60 group by C# having count(*)>10;

并运算:union
交运算:intersect
差运算:except
基本语法:子查询{union【all】|intersect【all】|except【all】子查询} //不带all,自动删除重复元组
示例:
1.
select distinct S# from SC except select S# from SC where C#='002';
2.
select S# from SC where C#='002' intersect select S# from SC where C#='003'

空值检测:
is【not】null
//如果null参与算术运算,则结果值为null
//如果null参与比较运算,则结果值为false,在SQL92中为unknown
//如果null参与聚集运算,则除count(*)之外其他聚集函数都忽略null

内连接、外连接:
select 列名...from 表名1【natural】【inner|【left|right|full】【outer】】join表名2【on 连接条件|using(colname...)】【where 检索条件】...;
//出现在结果关系中的两个连接关系的元组在公共属性上取值相等,且公共属性只出现一次
//出现在结果关系中的两个连接关系的元组取值满足连接条件,且公共属性出现两次
//(col1,col2...coln)是两个连接关系的公共属性的子集,元组在(col1,col2...coln)上取值相等,且(col1,col2...coln)只出现一次
示例:
1.    
select Teacher.T#,Tname,Cname from Teacher inner join Course on Teacher.T#=Course.T# order by Teacher.T# asc;

面向对象/对象关系数据库的查询SQL➡️OQL
基本SQL:另一select-from-where只能出现在where子句
新标准:引入对象概念,可以在能使用聚集的任何位置使用        //from select where

SQL视图:
外模式的数据-视图 概念模式的数据-基本表
视图不仅包含外模式,而且包含其E-C映像
基本表是实际存在的,视图只是基本表产生的映像

定义视图:create view view_name[...] as 子查询[with check option]
示例:
1.
create view CompStud as (select * from Student where D# in(select D# from Dept where Dname='计算机'));
2.
create view Teach as(select T.Tname, C.Cname, Credit from Teacher T,Course C where T.T#=C.T#);
3.
create view StudStat(S#,Sname,AvgS,MinS,MaxS,CNT)as(select S#,Sname,avg(Score),min(Score),max(Score),count(*) from Student S,SC where S.S#=SC.S# group by S.S#);
使用视图:
示例:
1.
select T.Tname from Teach T where T.Cname='数据库';
2.
select * from CompStud where Sage<20;

视图更新:
1.如果视图的select目标列包含聚集函数,则不能更新
2.如果视图的select子句使用了unique或distinct,则不能更新
3.如果视图中包括了group by子句,则不能更新
4.如果视图中包括经算术表达式计算出来的列,则不能更新
5.如果视图是由单个表的列构成,但并没有包括主键,则不能更新

撤销视图:drop view view_name;

❤️❤️❤️
数据库完整性:指DBMS应保证的DB的一种特性--在任何情况下的正确性、有效性和一致性
广义完整性:语义完整性、并发控制、安全控制、DB故障恢复等
狭义完整性:语义完整性

数据库完整性管理的作用:
防止和避免数据库中不合理数据的出现
DBMS应尽可能自动防止DB中语义不合理的现象
DBMS允许用户定义一些完整性约束规则(用SQL—DDL来定义)

完整性约束条件的一般形式:
Integrity Constraint::=(O,P,A,R)
O:数据集合-约束的对象?
P:谓词条件-什么样的约束?
A:触发条件-什么时候检查?    //默认更新时检查
R:响应动作-不满足时怎么办?    //默认拒绝

按约束对象分类:
域完整性约束    //施加在某一列上
关系完整性约束条件    //施加在table上

按约束来源分类:
结构约束    //来自模型的约束
内容约束    //来自用户的约束

按约束状态分类:
静态约束
动态约束

SQL语言支持如下约束:
静态约束: 列完整性-域完整性约束 表完整性-关系完整性约束
动态约束: 触发器

create table三种功能:定义关系模式、定义完整性约束(列完整性、表完整性)和定义物理存储特性
create table tablename(colname datatype[default{default_constant|null}][col_constr{col_constr...}],table_constr...);

col_constr列约束:    //table_constr也差不多
not null //列值非空
constraint constraintname //为约束命名
primary key //列为主键
check(search_cond) //列值满足条件,条件只能使用列当前值
references tablename[{colname}][on delete{cascade|set null}] //连接

示例:
1.
create table Student(S# char(8) not null unique,Sname char(10),Ssex char(2) constraint ctssex check(Ssex='男'orSsex='女'),Sage integer check(Sage>=1and Sage<150),D# char(2) references Dept(D#) on delete cascade,Sclass char(6));
2.
create table SC(S# char(8),C# char(3),Score float(1) constraint ctscore check(Score>=0.0and Score<=100.0),foreign key(S#)references student(S#)on delete cascade,foreign key(C#)references course(C#)on delete cascade);

断言assertion
断言测试增加了数据库维护的负担,效率带来影响

触发器trigger   //过程性约束
create trigger trigger_name before|after {insert|delete|update[of colname...]}on tablename[referencing corr_name_def...][for each row|for each statement][when(search_condition)]{statement|begin atomic statement...end}
当某一事件发生时(before|after),对该事件产生的结果(或是每一个元组,或是整个操作的所有元组),检查条件search_conditon,如果满足条件,则执行后面的程序段。条件或程序段中引用的变量可用corr_name_def来限定

corr_name_def:
old[row][as] old_row_corr_name    //更新前的旧元组命别名
new[row][as] new_row_corr_name    //更新后的新元组命别名
old table[as] old_table_corr_name    //更新前的旧table命别名
new table[as] new_table_corr_name    //更新后的新table命别名

示例:
1.
create trigger teacher_chgsal before update of salary on teacher referencing new x,old y for each row when(x.salary<y.salary)begin raise_application_error(-20003,'invalid salary on update');end;
2.
create trigger sumc after insert on sc referencing new row newi for each row begin update student set SumCourse=SumCourse+1 where S#=:newi.S#;end;
3.
create trigger updS# after update of S# on student referencing old oldi ,new newi for each row begin update sc set S#=newi.S# where S#=:oldi.S#;end;
4.    //当删除某一同学S#时,该同学的所有选课都要被删除
create trigger delS# after delete on Student referencing old oldi for each row begin delete sc where S#=:oldi.S#;end;

5.    //假设Dept(D#,Dname,Dean),而Dean一定是该系教师Teacher(T#,Tname,D#,Salary)中工资最高的教师
create trigger upddean before update of Dean on Dept referencing old oldi,new newi for each row when(dean not in(select Tname from Teacher where D#=:newi.D#and salary>=all(select salary from Teacher where D#=:newi.D#))begin raise_application_error(-20003,'invalid Dean on update');end;

❤️❤️❤️
数据库安全性是指DBMS应该保证的数据库的一种特性:免受非法、非授权用户的使用、泄漏、更改或破坏

DBMS的安全机制:
自主安全性机制:存取控制    //用户自主管理数据库安全性
强制安全性机制:对数据和用户强制分类
推断控制机制:防止通过历史信息和聚集信息,推断出私密信息
数据加密存储机制:通过加密、解密保护数据

自主安全性机制:    
通过授权机制来实现
DBMS允许用户定义一些安全性控制规则(用SQL-DCL来定义)

AccessRule::=(S,O,t,P)
S:请求主体    //用户多时,可以建立用户组
O:访问对象    //属性、元组、关系、数据库
t:访问权利    //包括创建、增、删、该、查等
P:谓词        //拥有权利需满足的条件

自主安全性的实现方式:
1.存储矩阵
2.视图

超级用户(DBA)➡️账户级别(程序员用户)➡️关系级别(普通用户)
级别一:select读
级别二:modify更新 - insert插入、update更新、delete删除
级别三:create创建 - create创建、alter更新、drop删除

授权命令:
grant{all privileges|privilege...} on[table] tablename|viewname to{public|user-id...}[with grant option];
//user-id,某一个用户账户,由DBA创建的合法账户
//public,允许所有有效用户使用授予的权力
//privilege:select|insert|update|delete|all priviledges
//with grant option选项是允许被授权者传播这些权力

示例:
假定高级领导为Emp0001,部门领导为Emp0021,员工管理员为Emp2001,收发员为Emp5001
grant all priviledges on emplouyee to emp2001;
grant select on EmpV2 to Emp5001;
grant select on EmpV3 to public;
grant select on EmpV4 to Emp0021;

收回授权:
revoke{all privileges|priv...} on tablename|viewname from{public|user...};

强制安全机制:
安全级别:绝密、机密、可信、无分类
对属性和元组引入安全性分级特性或称分类特性
访问规则:
1.用户S,不能读取数据对象O,除非level(S)>=level(O)
2.用户S,不能写数据对象,除非level(S)<=level(O)

❤️❤️❤️
交互式SQL语言:
select Sname,Sage from Student where Sname='张三';
嵌入式SQL语言:
exec sql select Sname,Sage into :vSname,:vSage from Student where Sname='张三';

在嵌入式SQL程序执行之前,首先要与数据库进行连接
建议的连接语法:
exec sql connect to target-server as connect-name user user-name;
或者
exec sql connect to default;

在执行过程中,必须有提交和撤销语句才能确认其操作结果
提交:exec sql commit work;
撤销:exec sql rollback work;

事务:(从程序员角度)是一个存取或改变数据库内容的程序的一次执行,或者说一条或多条SQL语句的一次执行
begin transaction ... end transaction    //这两行语句在嵌入式SQL程序中不需要了

事务:(从围观角度,或者从DBMS角度)是数据库管理系统提供的控制数据的一种手段,通过这种手段,应用程序员将一系列的数据库操作结合在一起作为一个整体进行操作和控制,以便数据库管理系统能够提供一致性状态转换的保证

事务的特性:ACID
原子性Atomicity:DBMS能够保证事务的一组更新操作是原子不可分的,即对DB而言,要么全做,要么全不做
一致性Consistency:DBMS保证事务的操作状态是正确的,符合一致性的操作规则,它是进一步由隔离性来保证的
隔离性Isolation:DBMS保证并发执行的多个事务之间互相不受影响。
持久性Durability:DBMS保证已提交事务的影响是持久的,被撤销事务的影响是可恢复的

单行结果处理(into)和多行结果处理(cursor游标)
游标是指向某检索记录集的指针
通过这个指针的移动,每次读一行处理一行,直到处理完毕
读取数据是通过fetch..into(一次一行)
记录集有结束标识EOF,用来标记后面已经没有记录了
游标需要先定义、再打开(执行)、接着一条接一条处理,最后再关闭
游标可以定义一次,多次打开(多次执行),多次关闭

标准的游标始终是自开始向结束方向移动,一条记录只能被访问一次,再次访问某记录只能关闭游标后重新打开
ODBC支持可滚动的cursor(声明时加入:scroll):
next:向结束方向移动一条
prior:向开始方向移动一条
first:回到第一条
last:移动到最后一条
BOF位置(起始记录的前面)
EOF位置(最后一条记录的后面)

查找删除/定位删除:
exec sql delete from tablename [corr_name] where search_conditon|where current of cursor_name;
查找更新/定位更新:
exec sql update tablename [corr_name] set columnname=expr...[where search_condition]|where current of cursor_name;
插入:
exec sql insert into tablename [col...][values(expr...)];

示例:
1.    //查找删除
exec sql delete from customers c where c.city='Harbin' and not exists(select * from orders o wher o.cid=c.cid);
2.    //查找更新
exec sql update student s set sclass='035102' where s.sclass='034101';
3.    //插入
exec sql insert into student(sno,sname,sclass) values('035001','张三','035');

状态是嵌入式SQL语句的执行状态,尤其指一些出错状态
状态捕获及处理:
1.设置SQL通信区:exec sql include sqlca;    //程序开始处便设置
2.设置状态捕获语句:exec sql whenever sqlerror goto report_error //任何位置都可以设置,次数无限制,但有作用域
3.状态处理语句:report_error:exec sql rollback;

SQL通信区-sqlca:是一个已被声明过的具有c语言的结构形式的内存信息区,其中的成员变量用来记录SQL语句执行的状态

状态捕获语句:exec sql whenever condition action;
condition:
sqlerror:检测是否有SQL语句出错
not found:执行某一SQL语句后,没有相应的结果记录出现
sqlwarning:不是错误,引起注意

action:
continue:忽略条件或错误,继续执行
goto:转移到标号所指示的语句,去进行相应的处理
stop:终止程序运行、撤销当前的工作、断开数据库的连接
do函数或call函数:调用宿主程序的函数进行处理,函数返回后从引发该condition的exec sql语句之后的语句继续进行

状态捕获语句whenever的作用范围是其后的所有exec sql语句,直到程序中出现另一条相同条件的whenever语句为止
!一定要添加这条语句:exec sql whenever sqlerror continue;    //避免无限循环

状态信息的三种方法:
1.状态记录:
sqlcode-记录执行sql语句的状态:==0、<0、>0
2.sqlca.sqlcode
3.sqlstate

❤️❤️❤️
动态SQL特点:SQL语句可以在程序中动态构造,形成一个字符串,然后再交给DBMS执行,交给DBMS执行时任然可以传递变量

示例:
1.    //Customers(Cid,Cname,City,discnt)
    //char Vcname[];
    //char Vcity[];
    //double range_from,range_to;
    //int Cname_chose,City_chose,Discnt_chose;
    //从Customers表中删除满足条件的行
#include<stdio.h>
#include"prompt.h"
char Vcname[];
char Vcity[];
double range_from,range_to;
int Cname_chose,City_chose,Discnt_chose;
Cname_chose=0;City_chose=0;Discnt_chose=0;
int sql_sign=0;
char continue_sign[];
//程序变量声明
exec    sql include sqlca;
exec sql begin declare section;
    char user_name[20],user_pwd[20];
    char sqltext[]="delete from customers where";
exec sql end declare section;

int main(){
    exec sql whenever sqlerror goto report_error;    //SQL错误捕获语言
    strcpy(user_name,"poneilsql");
    strcpy(user_pwd,"XXXX");
    exec sql connect:user_name identified by:user_pwd;
    while(1){
    memset(Vcname,'\0',20);
    memset(Vcity,'\0',20);
    if(GetCname(Vcname)) Cname_chose=1;
    if(GetCity(Vcity)) City_chose=1;
    if(GetDiscntRange(&range_from,&range_to)) Discnt_chose=1;
    if(Cname_chose){
        sql_sign=1;
        strcat(sqltext,"Cname=\'");
        strcat(sqltext,Vcname);
        strcat(sqltext,"\'");
    }
    if(City_chose){
    sql_sign=1;
        if(Cname_chose) strcat(sqltext,"and City=\'");
        else strcat(sqltext,"City=\'");
        strcat(sqltext,Vcity);
        strcat(sqltext,"\'");
    }
    if(Discnt_chose){
        sql_sign=1;
        if(Cname_chose=0and City_chose=0) strcat(sqltext,"discnt>");
        else strcat(sqltext,"and (discnt>");
        strcat(sqltext,dtoa(range_from)); //数值变量转换成字符串
        strcat(sqltext,"and discnt<");
        strcat(sqltext,dtoa(range_to));    //数值变量转换成字符串
        strcat(sqltext,")");
    }
    if(sql_sign){
        exec sql execute immediate    :sqltext;
        exec sql commit work; 
    }
    scanf("continue(y/n)%1s",continue_sign)
    if(continue_sign="n"){
        exec sql commit release;
        return 0;
    }
    }//while()
    report_error:
        print_dberror();
        exec sql rollback release;
        return 1;
}//main()

动态SQL的两种执行方式:
1.立即执行语句
exec sql execute immediate    :host-variable;
2.prepare-execute-using语句
prepare语句先编译,execute语句执行,using语句将动态参数值传送给编译好的SQL语句

数据字典(系统目录):
是系统维护的一些表或视图的集合,这些表或视图存储了数据库中各类对象的定义信息,这些对象包括用create语句定义的表、列、索引、视图、权限、约束等,这些信息又称数据库等元数据--关于数据的数据

ODBC:是一种标准--不同语言的应用程序与不同数据库服务器之间通讯的标准
1.一组API(应用程序接口),支持应用程序与数据库服务器交互
应用程序通过调用ODBC API,实现与数据库服务器的连接、向数据库服务器发送SQL命令、一条一条的提取数据库检索结果中的元组传递给应用程序的变量
2.具体的DBMS提供一套驱动程序,即Driver库函数,供ODBC调用
3.ODBC可以配合很多高级语言使用

JDBC:java版的ODBC,提供了java应用程序与数据库服务器连接和通讯能力
JDBC API分成两个程序包:Java.sql核心API,Javax.sql可选扩展API

嵌入式语言-ODBC-JDBC比较:
嵌入式语言:
建立数据库连接--声明一个游标--打开游标--获取一条一条记录--关闭游标--断开数据库连接
ODBC:
建立数据库连接--分配语句句柄--用句柄执行SQL--建立高级语言变量与句柄属性的对应--获取一条记录--释放语句句柄--断开数据库连接
JDBC:
建立数据库连接--创建语句对象--用语句对象执行SQL并返回结果对象--从结果对象获取一条一条记录--提取对象的属性值传给高级语言变量--释放语句对象--断开数据库连接

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值