SQL 语言高级教程


SQL SQL SQL SQL 语言 入门 教程 语言 入门 教程 语言 入门 教程 语言 入门 教程 第一课 简介 SQL 是英文 Structured Query Language 的缩写,意思为结构化查询语言。 SQL 语言的主要功能就是同各种数据库建立联系,进行沟通。按照 ANSI(美国国家标 准协会)的规定,SQL 被作为关系型数据库管理系统的标准语言。SQL 语句可以用来执行 各种各样的操作,例如更新数据库中的数据,从数据库中提取数据等。 目前,绝大多数流行的关系型数据库管理系统,如Oracle, Sybase, Microsoft SQL Server, Access等都采用了 SQL 语言标准。虽然很多数据库都对 SQL 语句进行了再开发和扩展,但 是包括 Select, Insert, Update, Delete, Create, 以及 Drop 在内的标准的 SQL命令仍然可以被用 来完成几乎所有的数据库操作。 下面,我们就来详细介绍一下 SQL 语言的基本知识。 一个典型的关系型数据库通常由一个或多个被称作表格的对象组成。数据库中的所有数 据或信息都被保存在这些数据库表格中。数据库中的每一个表格都具有自己唯一的表格名 称,都是由行和列组成,其中每一列包括了该列名称,数据类型,以及列的其它属性等信息 , 而行则具体包含某一列的记录或数据。以下,是一个名为太平洋网络学院的数据库表格的实 例。 该表格中“栏目”,“用户群”就是两个不同的列,而表格中的每一行则包含了具体的 表格数据。 1. 创建表格 2. 数据查询 3. 向表格中添加、更新、删除记录 4. 删除数据库表格 第二课 创建表格   SQL 语言中的 create table 语句被用来建立新的数据库表格。create table 语句的使用格式 如下:   create table tablename   (column1 data type, 栏目 用户群 新手上路 电脑初学者 软件教室 一般的电脑用户 设计教室 电脑设计爱好者 开发教室 电脑编程人员   column2 data type,   column3 data type);   如果用户希望在建立新表格时规定列的限制条件,可以使用可选的条件选项:   create table tablename   (column1 data type [constraint],   column2 data type [constraint],   column3 data type [constraint]);   举例如下:   create table employee   (firstname varchar(15),   lastname varchar(20),   age number(3),   address varchar(30),   city varchar(20));   简单来说,创建新表格时,在关键词 create table 后面加入所要建立的表格的名称,然 后在括号内顺次设定各列的名称,数据类型,以及可选的限制条件等。注意,所有的 SQL 语句在结尾处都要使用“;”符号。   使用 SQL 语句创建的数据库表格和表格中列的名称必须以字母开头,后面可以使用字 母,数字或下划线,名称的长度不能超过 30 个字符。注意,用户在选择表格名称时不要使 用SQL 语言中的保留关键词,如 select, create, insert 等,作为表格或列的名称。   数据类型用来设定某一个具体列中数据的类型。例如,在姓名列中只能采用 varchar 或 char 的数据类型,而不能使用 number 的数据类型。   SQL 语言中较为常用的数据类型为:   char(size):固定长度字符串,其中括号中的 size 用来设定字符串的最大长度。 Char 类 型的最大长度为 255 字节。   varchar(size):可变长度字符串,最大长度由 size 设定。   number(size):数字类型,其中数字的最大位数由 size 设定。   Date:日期类型。   number(size,d):数字类型,size 决定该数字总的最大位数,而d则用于设定该数字在小 数点后的位数。   最后,在创建新表格时需要注意的一点就是表格中列的限制条件。所谓限制条件就是当 向特定列输入数据时所必须遵守的规则。例如,unique 这一限制条件要求某一列中不能存在 两个值相同的记录,所有记录的值都必须是唯一的。除 unique 之外,较为常用的列的限制 条件还包括 not null 和primary key 等 。not null 用来规定表格中某一列的值不能为空。primary key 则为表格中的所有记录规定了唯一的标识符。 第三课 数据查询 在众多的 SQL 命令中,select 语句应该算是使用最频繁的。select 语句主要被用来对数 据库进行查询并返回符合用户查询标准的结果数据。Select 语句的语法格式如下:   select column1 [, column2,etc] from tablename   [where condition];   ([] 表示可选项)   select 语句中位于 select 关键词之后的列名用来决定那些列将作为查询结果返回。用户 可以按照自己的需要选择任意列,还可以使用通配符“*”来设定返回表格中的所有列。   select 语句中位于 from 关键词之后的表格名称用来决定将要进行查询操作的目标表格。   Select 语句中的 where可选从句用来规定哪些数据值或哪些行将被作为查询结果返回或 显示。   在where条件从句中可以使用以下一些运算符来设定查询标准:   = 等于   > 大于   < 小于   >= 大于等于   <= 小于等于   <> 不等于   除了上面所提到的运算符外,LIKE 运算符在 where条件从句中也非常重要。LIKE 运算 符的功能非常强大,通过使用 LIKE 运算符可以设定只选择与用户规定格式相同的记录。此 外,我们还可以使用通配符“%”用来代替任何字符串。举例如下:   select firstname, lastname, city   from employee   where firstname LIKE‘E%’;   (注意,字符串必须被包含在单括号内)   上述 SQL 语句将会查询所有名称以 E开头的姓名。或者,通过如下语句:   select * from employee   where firstname = ‘May’;   查询所有名称为 May 的行。 第四课 向表格中添加、更新、删除记录 添加新记录 SQL 语言使用 insert 语句向数据库表格中插入或添加新的数据行。Insert 语句的使用格 式如下:   insert into tablename   (first_column,...last_column)   values (first_value,...last_value);   例如:   insert into employee   (firstname, lastname, age, address, city)   values (‘Li’,’Ming’,45, ‘No.77 Changan Road’,’Beijing’);   简单来说,当向数据库表格中添加新记录时,在关键词 insert into 后面输入所要添加的 表格名称,然后在括号中列出将要添加新值的列的名称。最后,在关键词 values 的后面按照 前面输入的列的顺序对应的输入所有要添加的记录值。   更新记录   SQL 语言使用 update 语句更新或修改满足规定条件的现有记录。update 语句的格式为:   update tablename   set columnname = newvalue [, nextcolumn = newvalue2...]   where columnname OPERATOR value [and|or column OPERATOR value];   例如:   update employee   set age = age+1   where first_name= ‘Mary’and last_name= ‘Williams’;   使用 update 语句时,关键一点就是要设定好用于进行判断的 where条件从句。 删除记录   SQL 语言使用 delete 语句删除数据库表格中的行或记录。Delete 语句的格式为:   delete from tablename   where columnname OPERATOR value [and|or column OPERATOR value];   例如:   delete from employee   where lastname = May;   简单来说,当需要删除某一行或某个记录时,在 delete from 关键词之后输入表格名称, 然后在 where从句中设定删除记录的判断条件。注意,如果用户在使用 delete 语句时不设定 where从句,则表格中的所有记录将全部被删除。 第五课 删除数据库表格 在SQL 语言中使用 drop table 命令删除某个表格以及该表格中的所有记录。drop table 命令的使用格式为:   drop table tablename;   例如:   drop table employee;   如果用户希望将某个数据库表格完全删除,只需要在 drop table 命令后输入希望删除的 表格名称即可。drop table 命令的作用与删除表格中的所有记录不同。删除表格中的全部记 录之后,该表格仍然存在,而且表格中列的信息不会改变。而使用 drop table 命令则会将整 个数据库表格的所有信息全部删除。   以上,我们对 SQL 语言主要的命令和语句进行了较为详细的介绍。应该说 SQL 语句的 语法结构和风格还是相当简单和直观的,只要用户结合实践多加练习,一定会在短期内迅速 掌握。   以Store_Information 数据表为例,我们可以在 GROUP BY 一节中所使用的 SQL 命令中 设置如下字段和数据表别名:   SELECT A1.store_name Store, SUM(Sales) "Total Sales"   FROM Store_Information A1   GROUPBY A1.store_name   查询结果显示为:   Store Total Sales   Los Angeles $1800   San Diego $250   Boston $700 SQL SQL SQL SQL 循序渐进 SQL SQL SQL SQL 循序渐进((( ( 目录))) ) SQL 循序渐进(1)-------介绍 SQL SQL 循序渐进(2)-------表的基础知识 SQL 循序渐进(3)-------数据检索 SQL 循序渐进(4)-------创建表 SQL 循序渐进(5)-------插入数据到表 SQL 循序渐进(6)-------删除表 SQL 循序渐进(7)-------更新记录 SQL 循序渐进(8)-------删除记录 SQL 循序渐进(9)-------SELECT 语句 SQL 循序渐进(10)------合计函数 SQL 循序渐进(11)------GROUP BY 子句 SQL 循序渐进(12)------HAVING 子句 SQL 循序渐进(13)------ORDER BY 子句 SQL 循序渐进(14)------组合条件和布尔运算符 SQL 循序渐进(15)------IN 和 BETWEEN 条件运算符 SQL 循序渐进(16)------数学运算符 SQL 循序渐进(17)------JOIN子句 SQL 循序渐进(18)------索引 SQL 循序渐进(19)------DISTINCT 和排除复制 SQL 循序渐进(20)------Aliases 、In以及子查询 SQL 循序渐进(21)------更多的子查询 SQL 循序渐进(22)------EXISTS 和 ALL SQL 循序渐进 (23) ------UNION 和 外部连接 SQL 循序渐进 (24) ------嵌入 SQL (1)(1)(1) (1) 介绍SQLSQLSQL SQL SQL(Structured Query Language,结构查询语言)是一个功能强大的数据库语言。SQL 通 常使用于数据库的通讯。ANSI(美国国家标准学会)声称,SQL 是关系数据库管理系统的 标准语言。SQL 语句通常用于完成一些数据库的操作任务,比如在数据库中更新数据,或 者从数据库中检索数据。使用 SQL 的常见关系数据库管理系统有:Oracle、 Sybase、 Microsoft SQL Server、 Access、 Ingres等等。虽然绝大多数的数据库系统使用 SQL,但是 它们同样有它们自立另外的专有扩展功能用于它们的系统。但是,标准的 SQL 命令,比如 "Select"、"Insert"、"Update"、"Delete"、"Create"和 "Drop"常常被用于完成绝大多数数 据库的操作。 但是,不象其它的语言,如C、Pascal 等 ,SQL 没有循环结构(比如 if-then-else、do-while) 以及函数定义等等的功能。而且 SQL 只有一个数据类型的固定设置,换句话说,你不能在 使用其它编程语言的时候创建你自己的数据类型。 SQL 功能强大,但是概括起来,它可以分成以下几组: DML(Data Manipulation Language,数据操作语言):用于检索或者修改数据; DDL(Data Definition Language,数据定义语言): 用于定义数据的结构,比如 创建、修 改或者删除数据库对象; DCL(Data Control Language,数据控制语言):用于定义数据库用户的权限。 DML 组可以细分为以下的几个语句: SELECT:用于检索数据; INSERT:用于增加数据到数据库; UPDATE:用于从数据库中修改现存的数据 DELETE:用于从数据库中删除数据。 DDL 语句可以用于创建用户和重建数据库对象。下面是 DDL 命令: CREATETABLE ALTERTABLE DROPTABLE CREATEINDEX DROPINDEX DCL 命令用于创建关系用户访问以及授权的对象。下面是几个 DCL 命令: ALTERPASSWORD GRANT REVOKE CREATESYNONYM 为了让你对 SQL 有一个直观的认识,下面先给出一个简单 SQL 语句的例子: 我们使用 SQL 语句来从 Employees 中检索 Department ID为CS 的姓名: SELECT Employees.Name FROM Employees WHERE Employees.DeptID = "CS" 可能你现在一开始不太理解这些语句,也许你会一头雾水,不要紧的,通过本教程的学习后 , 你会发现这段语句是多么的普通。为了不让你困惑,下面我也进行一番解释: 先对 FROM 子句吧,语句中的 FROM Employees 意思是从 Employees 表中检索数据。 而语句 WHERE Employees.DeptID = "CS"意思是检索 Employees 的DeptID 列为”CS”的行, 这样 SQL 语句检索的结果将是 DeptID 为CS 的列的所有数据,比如: 最后,我们来解释一个 SELECT 子句,它指定了从 Name 列检索来的所有数据,比如 EmpID Name Dept 123 Purple CS 124 Zsc CS Name Purple Zsc 好吧,开始我们下一节的教程-------表的基本知识。 (2)(2)(2) (2) 表的基础知识 关系数据库通常包含多个表。数据库实际上是表的集合,数据库的数据或者信息都是存 储在表中的。表是对数据进行存储和操作的一种逻辑结构,每一个表都代表一个对用户意义 的对象。例如,一个公司数据库中,会有雇员表、部门表、库存表、销售表、工资表等等。 我们经常见到的成绩表就是一种表,它是有行和列组成的,我们并且可以通过名字来识别数 据。列包含了列的名字、数据类型以及列的其它属性;行包含了列的记录或者数据。下面给 出一个成绩单,其中姓名、语文、数学、英语都是列,而行包含了这个表的数据,即每个人 的各科成绩: (3)(3)(3) (3) 数据检索 在SQL 中SELECT 语句通常用于检索数据库,或者检索满足你设定条件的数据,以下 是简单的 SELECT 语句的格式: select "column1"[,"column2",etc] from "tablename" [where "condition"]; [] = optional 其中列的名字跟着 SELECT 关键字,它决定了哪一列将被作为结果返回。你可以任意 指定多个列,或者你可以使用"*"来选择所有的列。 表的名字是紧跟着 FROM 关键字的,它指出了哪个表格将作为最后结果被查询。 而WHERE 子句(可选)指出哪个数据或者行将被返回或者显示,它是根据关键字 WHERE 后面描述的条件而来的。 在WHERE 子句中可以有以下的条件选择: = 等于 > 大于 < 小于 >= 大于等于 <= 小于等于 <> 不等于 LIKE 参见以下注释 注释:LIKE 模式匹配操作符同样可以使用在 WHERE 子句的条件条件中。LIKE 是一个功 姓名 语文 数学 英语 王小童 78 100 87 张柳风 85 92 95 紫云飞 65 89 86 黄天龙 98 67 75 能强大的操作符,它可以让你选择你"喜欢"指定的行。百分号"%" 可以被用来匹配任何可能 的字符,它可以出现在指定字符的前面或者后面,例如: select first, last, city from empinfo where first LIKE'Er%'; 以上这条 SQL 语句将会匹配任何名字以'Er'开始的名字,这里必须使用单引号。 或者你也可以使用"%"在字符的前面,例如: select first, last from empinfo where last LIKE'%s'; 这条 SQL 语句将会匹配任何名字以's'结尾的名字。这个"%"的作用就跟 DOS 命令的"*"号 很相似。 select * from empinfo where first = 'Eric'; 以上的 SQL 语句只选择 first名字为'Eric'的行。 (4)(4)(4) (4) 创建表 这个 create table 语句是用于创建一个新的表格。以下是一个简单创建表格语句的格式: create table "tablename" ("column1" "data type", "column2" "data type", "column3" "data type"); 如果你想使用可选的约束,创建表格的格式为: create table "tablename" ("column1" "data type" [constraint], "column2" "data type" [constraint], "column3" "data type" [constraint]); [] = optional 这里注意:你可以任意创建多列的表格,这个条件是可选的。 为了更好的理解,下面举个例子: create table employee (first varchar(15), last varchar(20), age number(3), address varchar(30), city varchar(20), state varchar(20)); 为了创建一个新表格,你可以在关键字 create table 之后跟着表的名字,然后一个圆左 括号”(”,然后是第一列的名字,再是这一列的数据类型,接着是任意的可选约束,最后是 圆右括号”)”。确保在开始表格内容之前使用圆左括号并且在表的最后一列定义之后使用圆 右括号是相当重要的。你还要保证每一个列定义之间有逗号分隔。最后在 SQL 语句结束时 候加上分号";"。 表格和列名必须以字母开头,第二个字符开始可以是字母、数字或者下划线,但是要保证名 字的总长度不要超过 30 个字符。在定义表格和列名不要使用不要使用 SQL 预定的用于表格 或者列名的关键字(比如"select"、"create"、"insert"等等),以避免错误的发生。 数据类型是指在特定的列使用什么样数据的类型。如果一个列的名字为 "Last_Name",它 是用来容纳人名的,所以这个特定列就应该采用"varchar" (variable-length character,变长度 的字符型) 数据类型。 以下是几种常见的数据类型: char(size) :固定长度的字符串型。 Size 是圆括号中指定的参数,它可以由用户随意设置, 但是不能超过 255 个字节。 varchar(size) :变长度的字符串型。它的最大长度是由括号中的参数 size 设定的。 number(size):数值型。最大数字的位数由括号中的参数 size 设置。 date :日期数值型。 number(size,d) :数值型。它的最大数字的位数由括号中的参数 sieze 设定,而括号中的参数 d是设置小数点的位数。 什么是约束呢?当表被创建的时候,可以一列也可以多列共用一个约束。约束是一个跟列有 关的基本准则,返回的数据必须遵循这个准则。下面举个例子,一个约束指定在一列中不能 有两个记录共用一个数值。它们必须单独的。其它两个流行的约束是:"not null",它设置了 列不能留空白,即一定要有数据;以及 "primary key"(主键),主键约束定义了表中每一个 记录(或行)的唯一标识。所有的这些将在以后的教程中再作进一步阐述。 好吧,也许你已经有跃跃欲试的冲动了。作为本节练习,下面我们自己来设计和创建表格。 你可以开始创建一个公司的雇员表格。你需要创建一个包含 firstname、lastname、 title、 age 和 salary 的表格。 (5)(5)(5) (5) 插入数据到表 Insert 语句用于往表格中插入或者增加一行数据,它的格式为: insert into "tablename" (first_column,...last_column) values (first_value,...last_value); [] = optional 简单举个例子: insert into employee (first, last, age, address, city) values ('Luke', 'Duke', 45, '2130 Boars Nest', 'Hazard Co'); 这里要注意:每一个字符窜都要用单引号括起来。 为了往表中插入数据,要在关键字 insert into 之后紧跟着表名,然后是左圆括号,接着是以 逗号分开的一系列的列名,再是一个右圆括号,然后在关键字 values 之后跟着一系列用圆括 号括起的数值。这些数值是你要往表格中填入的数据,它们必须与指定的列名相匹配。字符 串笔译用单引号括起来,而数字就不用。在上面的例子中,'Luke'必须与列 first相匹配,而 45 必须与列 age 相匹配。 假如你想往 employee 表格中插入以下数据; Zhang Weiguo,28,北京 601 信箱,北京 那么你要使用以下的 SQL 语句: insert into employee (first, last, age, address, city) values (' Zhang', ' Weiguo' ,28, '北京 601 信箱','北京'); (6)(6)(6) (6) 删除表 Drop table 命令用于删除一个表格或者表中的所有行。其语法格式为: drop table "tablename" 下面举个例子: drop table employee; 为了删除整个表(包括所有的行),可以使用 drop table 命令后加上 tablename。Drop table 命令跟从表中删除所有记录是不一样的: 删除表中的所有记录是留下表格(只是它是空的)以及约束信息;而 drop table 是删除 表的所有信息,包括所有行、表格以及约束信息等等。 (7)(7)(7) (7) 更新记录 Update 语句用于更新或者改变匹配指定条件的记录,它是通过构造一个 where语句来 实现的。其语句格式如下: update "tablename" set "columnname" = "newvalue"[,"nextcolumn" = "newvalue2"...] where "columnname" OPERATOR"value" [and|or "column" OPERATOR"value"]; [] = optional 下面举个例子来说明: update phone_book set area_code = 623 where prefix = 979; 以上语句是在 phone_book 表中,在 prefix=979 的行中将 area_code 设置为 623。 update phone_book set last_name = 'Smith', prefix=555, suffix=9292 where last_name = 'Jones'; 而以上的这段语句是在 phone_book 中,在 last_name= 'Jones'的行中将 last_name 设置为 'Smith', prefix 为555, suffix 为9292。 update employee set age = age+1 where first_name='Mary' and last_name='Williams'; 这段语句是在 employee 表中,在first_name='Mary' 和last_name='Williams'的行中将 age加1。 作为每课一练,你在结束本教程之后要好好作以下的练习: 1 因为 Jonie Weber 已经跟 Bob Williams 结婚,所以它需要将它的 last 名更新为 Weber- Williams。 2 Dirk Smith 的生日是今天,所以他的年龄应该加 1。 3 所有的秘书都叫做"Administrative Assistant".所以要将所有的标题标题都相应地修改。 就作这几个练习,千万不可大意哟。 (8)(8)(8) (8) 删除记录 Delete 语句是用来从表中删除记录或者行,其语句格式为: delete from "tablename" where "columnname" OPERATOR"value" [and|or "column" OPERATOR"value"]; [] = optional 下面还是举个例子: delete from employee; 这条语句没有 where语句,所以它将删除所有的记录,因此如果没有使用 where的时候,要 千万小心。 如果你只要删除其中一行或者几行,可以参考以下的语句: delete from employee where lastname = 'May'; 这条语句是从 emplyee 表中删除 lastname 为'May'的行。 delete from employee where firstname = 'Mike' or firstname = 'Eric'; 这条语句是从 emplyee 表中删除 firstname为'Mike'或者'Eric'的行。 为了从表中删除一个完整的记录或者行,就直接在"delete from"后面加上表的名字,并 且利用 where指明符合什么条件的行要删除即可。如果你没有使用 where子句,那么表中的 所有记录或者行将被删除。 (9)SELECT (9)SELECT (9)SELECT (9)SELECT 语句 在上面的教程中已经有用到 SELECT 语句。在本节教程中将详细对它进行阐述。 SELECT 语句是 SQL 的核心,在你的 SQL 语句中可能用的最多的就是 SELECT 语句了。由 于大量的选项可以用于 SELECT 语句,所以整个教程好象就是围这 SELECT 语句转。当我 们构造 SQL 查询语句(利用了 SELECT 语句)的时候,认识所有的可能选项和最好的或者 最有效率的方法来实现是很有用的。这个教程将为你提供这些技能。 SELECT 语句用于查询数据库并检索匹配你指定条件的选择数据。SELECT 语句有五个 主要的子句子你可以选择,而 FROM 是唯一必须的子句。每一个子句有大量的选择项、参 数等等。这些子句将罗列在下面,而且它们每一个都将在以后的教程有更为详细的描述。 以下是 SELECT 语句的格式: SELECT[ALL | DISTINCT] column1[,column2] FROM table1[,table2] [WHERE"conditions"] [GROUPBY"column-list"] [HAVING"conditions] [ORDERBY"column-list" [ASC | DESC]] 下面举个例子: SELECT name, age, salary FROM employee WHERE age > 50; 上面的这个语句将从 employee 表中选择 age 大于 50 的所有的 name、age 和salary 列的数值 。 注意:一定要在 SQL 语句末尾加上一个分号。这个分号提示 SQL 语句已经结束并准备被解 释。 以下的表格给出了各种比较运算符号: 举个例子吧: SELECT name, title, dept FROM employee WHERE title LIKE'Pro%'; 上面的语句是从 employee 表中选择 title 是以'Pro'为开头的 name、title 和dept 列中的所有行 或者数值。 另外 ALL 和DISTINCT 也是 SQL 中的关键字,它们用于在你的查询结果中选择 ALL(缺 省)或者"distinct"或者单一记录。如果你想在指定的列中检索单一记录,你可以使用 "DISTINCT" 关键子。 因为 DISTNCT 将会丢弃所有你在 SELECT 指定的列复制的记录, 比如 : SELECTDISTINCT age FROM employee_info; 这条语句将返回所有在 employee_info 表中单一的 age 数据。 而ALL 就将显示所有指定的类,包括所有的复制数据。在没有指定的时候,这个 ALL 关键 字是缺省的。 (10)(10)(10) (10) 合计函数 所有的合计函数如下表所示: = 等于 > 大于 < 小于 >= 大于等于 <= 小于等于 <> 不等于 LIKE 字符串比较测验 MIN 返回一个给定列中最小的数值 MAX 返回一个给定列中最大的数值 合计函数用于从 SELECT 语句中计算一个”返回列的数据”。它们是总结了所选数据 列的结果。虽然它们需要"GROUPBY"子句(后面一个教程介绍),但是这些函数也可以在 不用使用"GROUPBY"子句的情况被使用,比如 : SELECT AVG(salary) FROM employee; 这条语句将返回单一的结果,它包含了从 employee 表中所有 salary 列数据的平均值。为了 更好的理解,我们再举个例子: SELECT AVG(salary) FROM employee; WHERE title = 'Programmer'; 以上这条语句将返回 employee 表中所有 title 列为'Programmer'的数据的平均值。 下面的例子中使用的语句跟其它合计函数有点不用,因为没有一个类被指定给 COUNT 函 数。这条语句实际上将返回 employee 表的行数,如下: SELECT Count(*) FROM employees; 最后给出本节教程的配套练习: 1)作一个公司的销售表 items_ordered,里面有 price、product和amount。 从items_ordered 表中选择 price最大的数据。这里提示:使用 MAX 函数。 2) 计算 items_ordered 表中的行数。 (11)GROUP(11)GROUP(11)GROUP (11)GROUP BYBYBY BY 子句 GROUP BY 子句 首先讲讲 GROUPBY 子句语法: SELECT column1, SUM(column2) FROM"list-of-tables" GROUPBY"column-list"; 这个 GROUP BY 子句将集中所有的行在一起,它包含了指定列的数据以及允许合计函数来 计算一个或者多个列。当然最好解释的方法是给出一个例子啦: 假设我们将从 employee 表中搜索工资最高的列,可以使用以下的 SQL 语句: SELECT max(salary), dept FROM employee GROUPBY dept; 这条语句将在每一个单独的部门中选择工资最高的工资。结果他们的 salary 和dept 将被返 回。 SUM 返回一个给定列中所有数值的总和 AVG 返回一个给定列中所有数值的平均值 COUNT 返回一个给定列中所有数值的个数 COUNT(*) 返回一个表中的行数 (12)HAVING (12)HAVING (12)HAVING (12)HAVING 子句 HAVING 子句 下面先给出 HAVING 子句的语法: SELECT column1, SUM(column2) FROM"list-of-tables" GROUPBY"column-list" HAVING"condition"; 这个 HAVING 子句允许你为每一个组指定条件,换句话说,可以根据你指定的条件来选择 行。如果你想使用 HAVING 子句的话,它应该处再 GROUP BY 子句之后。 下面将以一个例子来解释 HAVING 子句。假设我们的 employee 表中包含雇员的 name、 departmen、salary 和age。如果你想为每个部门中每个雇员选择平均工资的话,你可以使用 下面的 SQL 语句: SELECT dept, avg(salary) FROM employee GROUPBY dept; 当然,如果你还想只计算和显示 salary 大于 20000 的平均工资的话,你还可以加上 HAVING 子句: SELECT dept, avg(salary) FROM employee GROUPBY dept HAVING avg(salary) > 20000; (13)ORDER(13)ORDER(13)ORDER (13)ORDER BYBYBY BY 子句 ORDER BY 子句 ORDER BY 子句的语法为: SELECT column1, SUM(column2) FROM"list-of-tables" ORDERBY"column-list" [ASC | DESC]; [] = optional ORDER BY 是一个可选的子句,它允许你根据指定要 order by 的列来以上升或者下降的顺 序来显示查询的结果。例如: ASC = Ascending Order – 这个是缺省的 DESC = Descending Order 下面举个例子: SELECT employee_id, dept, name, age, salary FROM employee_info WHERE dept = 'Sales' ORDERBY salary; 这条 SQL语句将从 employee_info 表中列 dept 等于'Sales'选择 employee_id,、dept、 name、 age 和 salary,并且根据他们的 salary 按升序的顺序来列出检索结果。 如果你想对多列排序的话,那么在列与列之间要加上逗号,比如 : SELECT employee_id, dept, name, age, salary FROM employee_info WHERE dept = 'Sales' ORDERBY salary, age DESC; (14)(14)(14) (14) 组合条件和布尔运算符 以下的 SQL 语句中就含有组合条件: SELECT column1, SUM(column2) FROM"list-of-tables" WHERE"condition1" AND"condition2"; AND 运算符可以在 WHERE 子句中连接两个或者多个条件。AND 条件的两旁必须都为 true (真),即两个条件都同时满足的时候,这些行才将被显示。 当然,你也可以使用 OR 运算符,它也可以在 WHERE 子句中连接两个或者多个条件。但是 , 只要 OR 运算符两旁有一个为 true的时候条件就满足了,因此行才会被显示。所以你使用 OR 运算符的时候,可以是 OR 运算符两旁只有一个为 true或者两旁都为 true。 下面举个例子吧: SELECT employeeid, firstname, lastname, title, salary FROM employee_info WHERE salary >= 50000.00AND title = 'Programmer'; 这条 SQL 语句 是 从 employee_info 表中 选 择 salary 大于 等 于 50000.00 并且 title 等于 'Programmer'的列 employeeid、 firstname、 lastname、 title 和 salary。此时必须 AND 运算 符两旁的条件都为真,行才会最为检索结果返回。如果其中有一个条件为假,那么就什么都 没有显示。 你可以使用圆括号将条件括起来,虽然它们也不一定是必须的,但是括起来看起来更清晰一 些,这是一个编程习惯的问题。比如 : SELECT employeeid, firstname, lastname, title, salary FROM employee_info WHERE(salary >= 50000.00) AND(title = 'Programmer'); 下面再举个例子: SELECT firstname, lastname, title, salary FROM employee_info WHERE(title = 'Sales') OR(title = 'Programmer'); 这条语句将从 employee_info 表中选择 title 等于'Sales'或者等于'Programmer'的列 firstname、 lastname, title 和 salary。 (15)IN(15)IN(15)IN (15)IN 和 BETWEENBETWEENBETWEEN BETWEEN 条件运算符 下面是 IN条件运算符的 SQL 语句: SELECT column1, SUM(column2) FROM"list-of-tables" WHERE column3 IN(list-of-values); 下面是 BETWEEN条件运算符的 SQL 语句: SELECT column1, SUM(column2) FROM"list-of-tables" WHERE column3 BETWEEN value1 AND value2; 实际上,IN条件运算符是一个设置成员测试运算符,也就是说,它用于测试是否一个数值 处在 IN关键字之后提供的数值之中。举个例子如下: SELECT employeeid, lastname, salary FROM employee_info WHERE lastname IN('Hernandez', 'Jones', 'Roberts', 'Ruiz'); 这条语句是从 employee_info 表中选择 lastname 等于 Hernandez、Jones、 Roberts 或者 Ruiz 名字之一的列 employeeid、 lastname 和 salary。如果它在其中就将返回行。 IN条件运算符可以使用混合条件来替代,比如你可以使用等号运算符或者使用 OR 运算符 等等,但是结果是一样的,例如: SELECT employeeid, lastname, salary FROM employee_info WHERE lastname = 'Hernandez' OR lastname = 'Jones' OR lastname = 'Roberts' OR lastname = 'Ruiz'; 你可以观察到,利用 IN运算符时语句会更加简短并且容易读,特别是在你测试两个或者三 个数值以上的时候尤为突出。 当然你也可以使用 NOTIN 来在你的列表中排除行的。 而BETWEEN条件运算符是用与测试一个数值是否处在 BETWEEN关键字两边指定数值的 中间,比如: SELECT employeeid, age, lastname, salary FROM employee_info WHERE age BETWEEN 30 AND 40; 这条 SQL 语句是从 employee_info 表中选择 age 处于 30 到40 岁之间(包括 30 岁和 40 岁 ) 的列 employeeid、age、 lastname 和salary。 这条语句同样可以不用 BETWEEN运算符,而使用混合条件来替代,例如: SELECT employeeid, age, lastname, salary FROM employee_info WHERE age >= 30 AND age <= 40; 当然,你也可以类似于 NOTIN的方法,使用 NOTBETWEEN来排除一些数据。 (16)(16)(16) (16) 数学运算符 标准的 ANSI SQL-92 支持下面四个基本的算术运算符: + 加 - 减 * 乘 / 除 其中求余运算符决定除法的余数。这个运算符不是 ANSI SQL 支持的,但是,绝大多数 的数据库支持他。下面是一些有用的数学函数,因为可能要用到它,所以我这里要集中提一 下。在ANSI SQL-92 中不支持这些函数,但是它们可能对于某些特殊的 RDBMS 是有效的。 然而它们对于几个主要的数据库系统都是有效的。下面就说说这些数学函数吧: 下面举个例子: SELECT round(salary), firstname FROM employee_info 上面这条语句将从 employee_info 表中选择 salary 最接近的数以及 firstname列。 (17)JOIN (17)JOIN (17)JOIN (17)JOIN 子句 不知你有没有发现直到现在我们利用 SELECT 语句来检索的时候只能从一个表中进行。 如果你想从两个表或者更多的表中进行检索,该怎么办呢?好在我们可以使用 SQL 和关系 数据库系统的一个很有用的特性,即"Join"。为了简单说明,实际上"Join"就是使得关系数据 库系统相关的东东。"Join"允许你从两个表或者更多的表连接数据进行数据检索,而只需要 利用一个SELECT 语句。如果在 FROM关键字之后有多个表的话,"Join"可以在SQLSELECT 语句中识别它们。 下面举个例子: SELECT"list-of-columns" FROM table1,table2 WHERE"search-condition(s)" "Join" 通过示范当你只处理一个表的时候会发生什么事情可以使得"Join"的解释更简单,所以 这里我没有使用"Join"。这个单一的数据库有事也被称为"flat table"(平表)。现在你有一个 表的数据库用来检索所有顾客的信息以及他们从你的商店买了什么,下面就是这个表的所有 % 求余 ABS(x) 返回 x的绝对值 SIGN(x) 当x为负数、零、正数的时候分别返回 x的符号-1、0或者 1 MOD(x,y) 返回 x除以 y的余数,跟 x%y 作用一样 FLOOR(x) 返回小于等于 x的最大整数 CEILING(x) 或 CEIL(x) 返回大于等于 x的最小整数 POWER(x,y) 返回 x的y次方的数值 ROUND(x) 返回最接近于 x的数 ROUND(x,d) 返回小数点数为 4的接近于 x的数 SQRT(x) 返回 x的平方根 列: 每次一个新行被插入到表中,所有的列都将被更新,这样就导致了不必要的”多余数据”。 比如,每次 Jenny 买东西,下面的行都将被插入到表中: 为了避免”多余数据”,一个最好的方法:让数据库有两个表: 其中一个用来对顾客 保持跟踪;另外一个用来对他们买什么东西保持跟踪。 即有"Customer_info" 表和 "Purchases" 表: "Customer_info" 表为: "Purchases" 表为: 现在开始,不管顾客什么时候进行重复的购物,只有第二个表 "Purchases" 需要更新。 这样我们就减少了多余的数据,也就是说我们规格化了这个数据库。 你仔细点就会发现两个表中还是有一个"cusomer_number"列是相同的。这个列包含了单 独的顾客号,它将用来 JOIN(连接)两个表。下面举个例子来使用这两个表,假如你想搜 索顾客的名字以及他们所买的东西,你可以使用以下的语句来实现: SELECT customer_info.firstname, customer_info.lastname, purchases.item FROM customer_info, purchases WHERE customer_info.customer_number = purchases.customer_number; 特殊的"Join"有为"Inner Join" 或者"Equijoin",这是一个最常见的"Join"类型,以后我们经常 用使用到或者看到。 这里要注意每列总是在表名之前,这却也不是必需的。这是一个好的练习对于帮助你澄 清列后面跟着表的认识有很大帮助。如果两个表之间有一个相同的列,它就是必须的。我这 里推荐在使用 JOIN的时候最好在所有列之后加上表名。 注意;上面描述的这个语法将在绝大多数的数据库系统起作用,本教程的也是一样。但 是结果你会发现你上面的语句并不起作用,请仔细检查一下吧。 customer_number firstname lastname address city state zip customer_number date item price 当然你可以试一试修改以上的代码,你可以使用 JOIN(ANSI SQL-92 语法规范中的 INNERJOIN): SELECT customer_info.firstname, customer_info.lastname, purchases.item FROM customer_info INNERJOIN purchases ON customer_info.customer_number = purchases.customer_number; 再举另外一个例子: SELECT employee_info.employeeid, employee_info.lastname, employee_sales.comission FROM employee_info, employee_sales WHERE employee_info.employeeid = employee_sales.employeeid; 这个例子将从 employee_info 和employee_sales 表中选择当 employee_info 表的 employeeid 等于 employee_sales 表的 employeeid 的employeeid 、emplyee_info 表中 lastname 以及 employee_sales 表中的 comission 数值。 从上面的例子中可以发现利用 JION 的语句比价简练。既然有这样的有点,我们何乐而不为 呢? (18)(18)(18) (18) 索引 索引允许 DBMS 更快地访问数据。系统创建了这个内部地数据结构(即索引),它导致 当查询以列为索引的时候搜索行,这样查询会快得多。这个索引对于给定列索引数值的时通 知DBMS 找到表中某一行,这有点象书的索引,它告诉你对于给定的字你能找到哪一页。 下面让我们在 AntiqueOwners 列中为 OwnerID创建索引: CREATEINDEXOID_IDXONANTIQUEOWNERS(OWNERID); 下面语句是为名字创建所以: CREATEINDEXNAME_IDXONANTIQUEOWNERS(OWNERLASTNAME, OWNERFIRSTNAME); 为了删除索引,你可以利用 DROP: DROPINDEXOID_IDX; 就象前面教程中,我们也可以"drop"(删除)一个表。上面第二个例子中,是在两列上 创建索引的。 有些 DBMS 不强迫要求主键,换句话说就是,类的唯一性不会自动强制。这是什么意 思呢,好象听起来云里雾里的。好吧,再给你举个例子,如果你象插入另外一行到 AntiqueOwners 表中,比如这个 OwnerID 是02,有些系统可以让你这样做即使我们要求所 有行的数值都要是不同的。为了避免两行有相同的值,我们有一种方法来克服,就是在列上 创建唯一的索引,而在这个列上我们需要它成为主键,这样就可以系统不会出现复制的情况 : CREATEUNIQUEINDEXOID_IDXONANTIQUEOWNERS(OWNERID); (19)DISTINCT (19)DISTINCT (19)DISTINCT (19)DISTINCT 和排除复制 假如你象列出所有买过古董的 ID和名字,很明显,你可能会将所有的顾客都列出来而 没有考虑有些顾客是买过多讲古董的,所以这时你会发现有些数据是重复的。这就意味着你 需要通知 SQL 来排除复制的行,而不管这个顾客买过多少个古董只需要列出一次即可。为 了实现这个目的,你可以使用 DISTINCT 关键字。 首先我们需要为 AntiqueOwners 表来一个 equijoin 以得到顾客的 LastName 和First的详 细数据。但是,你要考虑到 Antiques 表中的 SellerID 列是 AntiqueOwners 表的一个外码,所 以顾客只能在 AntiqueOwners 表列出 ID和名字的行才被列出。我们还想在列的数据中排除 SellerID 复制的发生,所以我们要在发生重复的列上使用 DISTINCT。 为了防止复制的发生,我们还想将 LastName 以字母顺序排列,然后在按字母顺序排列 FirstName 最后排列 OwnerID,因此我们还必须使用 ORDER BY 子句,具体语句如下: SELECTDISTINCTSELLERID,OWNERLASTNAME,OWNERFIRSTNAME FROMANTIQUES,ANTIQUEOWNERS WHERESELLERID = OWNERID ORDERBYOWNERLASTNAME,OWNERFIRSTNAME,OWNERID 在这个例子中,因为每个人都买都一个件古董,所以我们将 Lasname 以字母顺序列出 所有的古董拥有者。 (20)Aliases(20)Aliases(20)Aliases (20)Aliases 、In In In In 以及子查询 在本节教程中,我们将要介绍 Aliases、 In以及子查询的用法。首先我们看一下一个查 询语句,它搜索所有已经定货的顾客的 LastName 以及他们定什么货,语句如下: SELECTOWN.OWNERLASTNAME Last Name, ORD.ITEMDESIRED Item Ordered FROMORDERSORD,ANTIQUEOWNERSOWN WHEREORD.OWNERID = OWN.OWNERID ANDORD.ITEMDESIREDIN (SELECTITEM FROMANTIQUES); 这条查询语句的结果为: Last Name Item Ordered --------------------- Smith Table Smith Desk Akins Chair Lawson Mirror 下面好好解释一下上面的这条语句: "Last Name" 和"Item Ordered"给出了报告的数据头。 OWN& ORD 是aliases(别名),它们使用在 FROM 子句中,可在它们的后面加一个点 号再加列名就可以进行查询了。这样做就避免了模棱两可的情况,特别是在 equijoin WHERE 子句中当两个列都名为 OwenerID 的时候,而点号就通知 SQL 我们使用是两个不同表的不 同OwnerID。 这里要注意,在 FROM 子句中 Orders 表被首先列出,并且确保 AntiqueOwners 表只用 于详细的信息(Last Name)。更为重要的,在 WHERE 子句中的 AND 强迫 In子查询被调用 ("=ANY" or "= SOME" 都等价于使用 IN)。但这到底做了些什么呢?当这个子查询完成了 , 它就返回 Antiques 表的所有 Items 因为这里没有 WHERE 子句。然后,对于从 Orders 表列 出的行,ItemDesired 必须在从 Antiques 表中返回的 Items 列表中,然后在定货可以有另外的 拥有者填写的情况下列出一个 item。你可以想想这个方法:子查询从 Orders 表中的每一个 ItemDesired 被比较中返回一系列的 Items;如果 ItemDesired 是在从 Antiques 表中返回的, 那么条件才为真。 (21)(21)(21) (21) 更多的子查询 我们可以使用在 SELECT 查询语句中再包括一个 SELECT 子查询语句。举个例子吧, 首先我们列除所有购买贵重物品的顾客,贵重物品的标准是比所有卖出的物品价钱的平均值 多100 元的物品。具体语句如下: SELECTOWNERID FROMANTIQUES WHEREPRICE > (SELECTAVG(PRICE) + 100 FROMANTIQUES); 上面子查询语句是计算物品的平均价格再加 100 元,并搜索所有在 ANTIQUES 表中 PRICE 大于这个数值的 OWNERID。这里你可以使用 DISTINCT OWNERID 来排除复制的 现象。 下面的语句列出了所有在 AntiqueOwners 表中的有买过物品的人的 LastName: SELECTOWNERLASTNAME FROMANTIQUEOWNERS WHEREOWNERID = (SELECTDISTINCTBUYERID FROMANTIQUES); 这个子查询返回了一系列的顾客,当且仅当物品拥有者的 ID出现在子查询的列表中, 古董的拥有者的 LastName 才会显示出来。 为了更新这个例子,我们假设有一个买过 bookcase 的顾客,他的FirstName 在数据库中 出错了,应该为 John: UPDATEANTIQUEOWNERS SETOWNERFIRSTNAME = 'John' WHEREOWNERID = (SELECTBUYERID FROMANTIQUES WHEREITEM = 'Bookcase'); 上面的语句中的子查询首先搜索买过 bookcase 的顾客的 BuyerID,然后在外层的查询中 来更新他的 FirstName。 (22)EXISTS(22)EXISTS(22)EXISTS (22)EXISTS 和 ALLALLALL ALL EXISTS 使用了一个子查询作为条件,只有当子查询返回行的时候这个条件才为真,如 果子查询不返回任何的行条件就为假。如果商店在处理 Chair 的时候,有个顾客想看看所有 拥有者的列表,就可以使用 EXSIST,语句如下: SELECTOWNERFIRSTNAME,OWNERLASTNAME FROMANTIQUEOWNERS WHEREEXISTS (SELECT* FROMANTIQUES WHEREITEM = 'Chair'); 如果在 Antiques 列中有 Chair,那么子查询就会返回一行或者多行,就使得 EXISTS 子 句为真,然后让 SQL 列出拥有者来。如果没有搜索到 Chair,则没有行被返回,条件就为假 。 ALL 是另外一个不寻常的关键字,因为 ALL 查询通常可以用不同的方法来进行,并且 可能是一种更为简单的方法。举个例子来说明吧: SELECTBUYERID,ITEM FROMANTIQUES WHEREPRICE >= ALL (SELECTPRICE FROMANTIQUES); 上面这条语句将返回最高价格的 Item以及它的买方。子查询返回了 Antiques 表中的所 有的 Price列,而外层的查询逐行查询 Antiques 表,并且如果它的 Price大于等于(或者 ALL) 列中的 Prices,它就会被列出,它就是最好价格的 Item。这里必须使用">="的原因是最高价 格的 Item要等于列表中的最高价格,因为这个 Item在Price列中。 (23)UNION(23)UNION(23)UNION (23)UNION 和 外部连接 有些时候,你可以想一起看多个查询的结果、组合它们的输出,你可以使用 UNION 关 键字。为了合并以下两个查询的输出:显示所有买方的 ID和已经有定货的顾客,你可以使 用以下语句: SELECTBUYERID FROMANTIQUEOWNERS UNION SELECTOWNERID FROMORDERS; 这里要注意 SQL 要求 SELECT 的列表必须匹配,即列于数据类型匹配。在本例子中, BuyerID 和OwnerID都是相同的数据类型,同为 Interger(整型)。同时还有一提的是,SQL 但使用 UNION 的使用会进行自动复制排除。而在单一的查询中,你就必须使用 DISTINCT。 Outer Join(外部连接)通常是在 JOIN查询被联合,而行没有包括到 JOIN中的时候使 用,特别是在常量文本"flags"被包括的时候尤为有用。下面我们看看这个查询先: SELECTOWNERID,'is in both Orders &Antiques' FROMORDERS,ANTIQUES WHEREOWNERID = BUYERID UNION SELECTBUYERID,'is in Antiques only' FROMANTIQUES WHEREBUYERIDNOTIN (SELECTOWNERID FROMORDERS); 第一个查询做了一个连接以列出两个表中的每个 owener,并且在 ID后面放置一个标记 线来重复引用。这个 UNION 合并了这个列表以及以下第二个的列表。第二个列表是列出不 是在 Orders 表的 ID,这样就产生了在 JOIN查询之外的 ID列表,它是利用引用标签列出的 。 这可能是一种最容易的方法来产生这个列表。 这个概念对于主键跟外码有关的状况是很有用的,但是有些主键的外码值是 NULL。比 如,在一个表中,主键是 salesperson,而在其它的表中主键是 customers,并且它们的 salesperson 列在相同的行。然而,如果 salesperson 没有 customers的时候,这个人的名字就 不会出现在 customer 表中。如果所有 salespersons的列表要显示出来,那么就要外部连接了 。 (24)(24)(24) (24) 嵌入式SQLSQLSQL SQL 为了更好的理解嵌入式SQL,本节利用一个具体例子来说明。嵌入式SQL 允许程序连 接数据库并且包括 SQL 代码到程序中,这样在程序中就可以对数据库进行使用、操作以及 处理数据等等。以下是用 C语言编写的使用嵌入 SQL 的例程,它将打印一个报告;这个程 序必须在普通的编译之前先预编译 SQL 语句。嵌入 SQL 对于不同系统是不一样的,所以在 不同的系统中对以下的程序稍作修改,特别是变量的声明以及过程记录等。在嵌入 SQL 时, 考虑网络、数据库管理系统、操作系统是相当重要的。 以下是详细的代码: #include /* 以下这部分是声明主机变量,它将使用于程序中*/ EXECSQLBEGINDECLARESECTION; int BuyerID; char FirstName[100], LastName[100], Item[100]; EXECSQLENDDECLARESECTION; /* 以下包括 SQLCA 变量,它可以用来进行错误检查 */ EXECSQLINCLUDESQLCA; main() { /* 以下连接数据库*/ EXECSQLCONNECT UserID/Password; /* 以下是连接数据库并检查是否有错误产生 T*/ if(sqlca.sqlcode) { printf(Printer, "Error connecting to database server.\n"); exit(); } printf("Connected to database server.\n"); /* 下面声明一个 "Cursor"。它将在查询结果多于一行的时候使用*/ EXECSQLDECLARE ItemCursor CURSORFOR SELECTITEM,BUYERID FROMANTIQUES ORDERBYITEM; EXECSQLOPEN ItemCursor; /* 你可以在这里还可以加入另外一些错误检查的内容,这里就省略了*/ /* 当这个 CURSOR 没有数据, sqlcode 将被产生以允许我们退出循环。这里注意,为 了简单起见,我们使程序遇到错误的时候就退出任何的 sqlcode。*/ EXECSQLFETCH ItemCursor INTO:Item, :BuyerID; while(!sqlca.sqlcode) { EXECSQLUPDATEANTIQUES SETPRICE = PRICE + 5 WHEREITEM = :ItemANDBUYERID = :BuyerID; EXECSQLSELECTOWNERFIRSTNAME,OWNERLASTNAME INTO:FirstName, :LastName FROMANTIQUEOWNERS WHEREBUYERID = :BuyerID; printf("%25s %25s %25s", FirstName, LastName, Item); EXECSQLFETCH ItemCursor INTO:Item, :BuyerID; } /* 关闭 CURSOR,提交变化并退出程序。*/ EXECSQLCLOSE DataCursor; EXECSQLCOMMITRELEASE; exit(); } 在SQLSQLSQL SQL Server Server Server Server 中保存和输出图片 有时候我们需要保存一些 binary data 进数据库。SQL Server 提供一个叫做 image 的特殊 数据类型供我们保存 binary data。Binary data 可以是图片、文档等。在这篇文章中我们将看 到如何在 SQL Server 中保存和输出图片。 建表 为了试验这个例子你需要一个含有数据的 table(你可以在现在的库中创建它,也可以创 建一个新的数据库),下面是它的结构: Column Name Datatype Purpose ID Integer identity column Primary key IMGTITLE Varchar(50) Stores some user friendly title to identity the image IMGTYPE Varchar(50) Stores image content type. This will be same as recognized content types of ASP.NET IMGDATA Image Stores actual image or binary data. 保存imagesimagesimages images 进SQLSQLSQL SQL ServerServerServer Server 数据库 为了保存图片到 table 你首先得从客户端上传它们到你的 web 服务器。你可以创建一个 web form,用 TextBox 得到图片的标题,用 HTML File Server Control 得到图片文件。确信 你设定了 Form 的encType 属性为 multipart/form-data。 Stream imgdatastream = File1.PostedFile.InputStream; int imgdatalen = File1.PostedFile.ContentLength; string imgtype = File1.PostedFile.ContentType; string imgtitle = TextBox1.Text; byte[] imgdata = new byte[imgdatalen]; int n = imgdatastream.Read(imgdata,0,imgdatalen); string connstr= ((NameValueCollection)Context.GetConfig ("appSettings"))["connstr"]; SqlConnection connection = new SqlConnection(connstr); SqlCommand command = new SqlCommand ("INSERTINTO ImageStore(imgtitle,imgtype,imgdata) VALUES(@imgtitle, @imgtype,@imgdata )", connection ); SqlParameter paramTitle = new SqlParameter ("@imgtitle", SqlDbType.VarChar,50 ); paramTitle.Value = imgtitle; command.Parameters.Add( paramTitle); SqlParameter paramData = new SqlParameter ("@imgdata", SqlDbType.Image ); paramData.Value = imgdata; command.Parameters.Add( paramData ); SqlParameter paramType = new SqlParameter ("@imgtype", SqlDbType.VarChar,50 ); paramType.Value = imgtype; command.Parameters.Add( paramType ); connection.Open(); int numRowsAffected = command.ExecuteNonQuery(); connection.Close(); 从数据库中输出图片 现在让我们从数据库中取出我们刚刚保存的图片,在这儿,我们将直接将图片输出至浏 览器。你也可以将它保存为一个文件或做任何你想做的。 private void Page_Load(object sender, System.EventArgs e) { string imgid =Request.QueryString["imgid"]; string connstr=((NameValueCollection) Context.GetConfig("appSettings"))["connstr"]; string sql="SELECT imgdata, imgtype FROM ImageStore WHERE id = " + imgid; SqlConnection connection = new SqlConnection(connstr); SqlCommand command = new SqlCommand(sql, connection); connection.Open(); SqlDataReader dr = command.ExecuteReader(); if(dr.Read()) { Response.ContentType = dr["imgtype"].ToString(); Response.BinaryWrite( (byte[]) dr["imgdata"] ); } connection.Close(); } 在上面的代码中我们使用了一个已经打开的数据库,通过 datareader 选择 images。接着 用Response.BinaryWrite 代替 Response.Write 来显示 image 文件。 数据库的备份与恢复 随着信息时代和互联网技术的飞速发展,企业的信息数据量也急剧增长。如何避免突如 其来的数据破坏(如:黑客攻击、病毒袭击、硬件故障和人为误操作等),提高数据的安全 性和数据恢复能力一直是用户和厂商关注的焦点。备份是恢复数据最容易和最有效的保证方 法,备份应定期进行,并执行有效的数据管理。 Microsoft 公司的 SQL Server 是一个功能完善的数据库管理系统,由于和 Windows 操作 系统无缝结合,操作简便易行,应用十分广泛。下面来看一看基于 NT 的SQL Server 7.0 的 备份与数据恢复的有效方法。 针对服务器系统 由于数据库服务器中安装的系统较多,设置复杂,如出现硬件故障,则必须重装系统, 恢复设置,因此有必要对数据库服务器进行备份。 1、使用 NT Server 提供的功能 在防止数据丢失方面,NT 的磁盘管理器具有强大的功能,它支持 RAID 的第 0、1、5 级。其中 RAID 1级是指把一个驱动器上的某一分区在另一个上建立一个镜像。进行写操作 时,数据将向两个磁盘中写入同样的数据,读取时可以从两个磁盘同时读取。当驱动器损坏 时,由它的镜像来进行恢复。 2、使用第三方备份工具 采用其他公司的备份软件来对服务器系统做备份。笔者常用的是 Norton 公司的磁盘备 份工具——Ghost。该软件可以直接将磁盘上的某个分区或整个硬盘克隆成一个镜像文件, 然后把它存放在别处,那么当该分区或硬盘出现问题甚至毁坏时,使用Ghost 在另一硬盘或 分区上,利用镜像文件快速还原。 针对SQLSQLSQL SQL ServerServerServer Server 1、在本地机上进行数据库备份 先确认 SQL Server 服务是否已经启动,如果没有启动,则使用 SQL Server 7.0 程序菜单 中的“SQL Server Service Manager”进行启动,然后打开 “Enterprise Manager”,展开左边 的SQL Server Group,展开 SQL Server 中的“Databases”,单击右键,在菜单中选择“所有 任务”选项中的“Backup Database”子选项,出现如图 1的数据库备份画面。 图1 选好要备份的数据库及备份方式后,单击[Add]按钮,在对话框中设置好存放目录及文 件名,单击[OK]按钮。如果要设置定期自动备份,可在“Schedule”中设置,完毕后,单击 [确定]按钮,数据库备份就开始执行了。 2、在本地机上进行数据库恢复 启动“Enterprise Manager”,展开其中的选项,选择“Databases”,单击右键,在对话框 中选择“所有任务”选项中的“Restore Database”(如图 2)。 图2 单击[Select Devices]按钮,选择要恢复的数据库文件。选择完毕后,“Backup Number” 选项将会变亮,选择最近的一次备份。然后单击[确定],数据库恢复过程开始执行。 3、将数据库导出到网络上的另一台计算机上进行备份与恢复 先在网络上的另一台计算机上安装一个新的 SQL Server,并启动它建立好数据库结构。 然后在本机上启动“Enterprise Manager”,在左边的目录栏中选中“SQL Server Group”,单 击右键,在对话框中选择“New SQL Server Registration”,进入注册向导,输入目标 SQLServer 的计算机名后,填写登录 ID和密码,将目标 SQL Server 注册在本机的“SQL Server Group” 中。然后选择“Databases”中需要备份的数据库标志,单击右键,在对话框选择“所有任务” 中的“Export Data...”选项。在弹出“Date Transfer Services Export Wizard”的界面后,单击 [下一步]按钮,选择需要备份的数据库,接着单击[下一步]按钮,选择目标服务器,选择SQL Server 验证模式,填写用户名和密码,在“Database”一项中输入新的数据库名称(如图 3), 单击[下一步]按钮,进入导出方式的界面,设置好之后,单击[下一步]按钮,在下面的步骤 中一般选择默认选项,可以顺利完成数据库的导出操作了。 图3 两个 SQL Server 中具有相同的数据库,当原来的数据库崩溃后,就可以直接启用另一 个,只是修改一下计算机上 ODBC 数据源中所设置的 SQL Server 主机名称。 网络数据库设计入门 (一) SQL SQL SQL SQL 语言简介 这一教程是对网络数据库设计的一个入门介绍,简要地介绍了 SQL 语言的基础以及如 何使用 MS ACCESS 和MSSQL SEVER 建立网络数据库。通过本教程的学习,你可以建立、 访问和操作你的数据库,可以学会如何使用 SQL 语句检索、增加、更新、删除数据库表中 的内容。这对于任何有关数据库的操作和开发都具有重要意义。 1.1 SQL 语言简介 1.1.1 SQL 语言及其优点 1.1.2 SQL 语言的分类及语法 1.2 中小型关系型数据库简介 1.2.1 关系型数据库简介 1.2.2 Access数据库及其基本操作 1.2.3 SQL Server 数据库及其基本操作 1.3 ODBC 与ADO 对象 1.3.1 ASP 访问数据库的几种方式 1.3.2 创建和配置 ODBC 数据源 1.3.3 用ADO 实现访问数据库 1.1 SQL 语言简介 SQL 是英文(Structured Query Language)的缩写,意思为结构化查询语言。SQL 语言的主 要功能就是同各种数据库建立联系,进行沟通。按照 ANSI(美国国家标准协会)的规定, SQL 被作为关系型数据库管理系统的标准语言。SQL 语句可以用来执行各种各样的操作, 例如更新数据库中的数据,从数据库中提取数据等。目前,绝大多数流行的关系型数据库管 理系统,如 Oracle, Sybase, Microsoft SQL Server, Access等都采用了 SQL 语言标准。 ((( ( 二)SQL )SQL )SQL )SQL 语言及其优点 1.1.1 SQL 语言及其优点 首先,让我们来了解一下使用 SQL 语言的优点: ● 非过程化语言 ● 统一的语言 ● 是所有关系数据库的公共语言 1.非过程化语言 SQL 是一个非过程化的语言,因为它一次处理一个记录,对数据提供自动导航。 SQL 允许 用户在高层的数据结构上工作,而不对单个记录进行操作,可操作记录集,所有 SQL 语句 接受集合作为输入,返回集合作为输出。SQL 的集合特性允许一条 SQL 语句的结果作为另 一条 SQL 语句的输入。 SQL 不要求用户指定对数据的存放方法, 这种特性使用户更易集中精力于要得到的结果; 所有 SQL 语句使用查询优化器,它是 RDBMS 的一部分,由它决定对指定数据存取的最快 速度的手段,查询优化器知道存在什么索引,在哪儿使用索引合适,而用户则从不需要知道 表是否有索引、有什么类型的索引。 2.统一的语言 SQL 可用于所有用户的 DB 活动模型,包括系统管理员、数据库管理员、 应用程序员、决 策支持系统人员及许多其它类型的终端用户。基本的 SQL 命令只需很少时间就能学会,最 高级的命令在几天内便可掌握。 SQL 为许多任务提供了命令,其中包括: ● 查询数据 ● 在表中插入、修改和删除记录 ● 建立、修改和删除数据对象 ● 控制对数据和数据对象的存取 ● 保证数据库一致性和完整性 以前的数据库管理系统为上述各类操作提供单独的语言,而SQL 将全部任务统一在一种语 言中。 3.是所有关系数据库的公共语言 由于所有主要的关系数据库管理系统都支持 SQL 语言,用户可将使用 SQL 的技能从一个 RDBMS( 关系数据库管理系统)转到另一个,所有用 SQL 编写的程序都是可以移植的。 ((( ( 三)SQL )SQL )SQL )SQL 语言的分类及语法 1.1.2 SQL 语言的分类及语法 可执行的 SQL 语句的种类数目之多是惊人的。使用 SQL,你可以执行任何功能:从一 个简单的表查询,到创建表和存储过程,到设定用户权限。在这个章节中,我们将重点讲述 如何从数据库中检索、更新和报告数据,也是基于这个目的,我们应该了解的最重要的 SQL 语句是: ● SELCET ● INSERT ● UPDATE ● DELETE ● CREAT ● DROP 以上这些命令可简要描述如表 1.1 所示,这些命令看起来并不困难,在下面的例子中,我们 将在实例中应用这些命令,了解其功能。 表1.1 重要的 SQL 语句 1.SELECT 语句语法 表1.2 SELECT 语句的组件 下面我们对这个重要的语句语法进行示例讲解,需要说明的是这一章节中所涉及到的例 子都是基于图 1.1 描述的表结构。 Authors id name phone address zip salary contract 图1.1 在test数据库中的 authors 表的结构 ● 一个简单的 SELECT 语句: SELECT id,name,phone,zip From authors 这个简单的查询的结果得出的内容为 authors 表中返回的选定列的数据。在同样的检索情况 下,如果你想缩小范围,比如只想知道住在福州鼓楼地区(邮编为 350002)的作者的名字,你 可以接着看后面的例子; 命令 类别 说明 SELECT 数据查询语言 从一个表或多个表中检索列和行 INSERT 数据操纵语言 向一个表中增加行 UPDATE 数据操纵语言 更新表中已存在的行的某几列 DELETE 数据操纵语言 从一个表中删除行 CREATE 数据定义语言 按特定的表模式创建一个新表 DROP 数据定义语言 删除一张表 组件 说明 SELECT 指明要检索的数据的列 FROM 指明从哪(几)个表中进行检索 WHERE 指明返回数据必须满足的标准 GROUPBY 指明返回的列数据通过某些条件来形成组 HAVING 指明返回的集合必须满足的标准 ORDERBY 指明返回的行的排序顺序 ● 添加 WHERE 子句 SELECT id,name,phone,zip From authors WHERE zip = ‘350002’ 在检索表行时,WHERE 子句可以使用多个列作为约束内容,当然在检索约束内容中还可以 加入通过 AND、OR 以实现多个约束。另外,在 SELECT 语句中我们还可以通过更改比较 操作符来改变约束的条件,以达到我们需要的检索目的。我们再看一个例子; ● 完整约束查询 SELECT id,name,phone,zip From authors WHERE zip <> ‘350002’AND phone = ‘1234567’ 这个例子查询结果返回的是住在福州鼓楼地区以外(邮编号不为 350002)的且电话号码为 1234567 的作者的资料。 表1.3 SELECT 语句中支持的比较操作符 ● 添加 ORDER BY 子句 SELECT id,name,phone,zip From authors WHERE zip = ‘350002 ‘ ORDERBY id 这样,这条 SQL 语句返回的结果将 id 列的升序排序。 1.1.2 SQL 语言的分类及语法 2.INSERT 语句语法 表1.4 INSERT 语句的组件 ● 一个简单的 INSERT 语句: INSERTINTO authors 操作符 说明 = 等于 > 大于 < 小于 >= 大于等于 <= 小于等于 <> 不等于 IN 位于指定列表值中,或者指定的子查询的结果中 BETWWEEN..AND 位于两个值之间 LIKE 包含与指定串相同的模式。此模式将与一个或多个通 配符的串相比较 组件 说明 INSERTINTO 指明要向哪个表中加入行 同时列出指定加入的列,如未指定的对象为表中 的每一列 VALUES 指明在列表中各列的填充值 SELECT SELECT 语句返回被加到表中的各行 VALUES (‘FZ1234’,’张三’,’1234567’,’深圳幸运计算机公司’,’350002’,’本文作者’) 这样,便向表中加入了一条记录。 我们也可以指明用哪几列来填充,看下面的例子; ● 一个简单的 INSERT 语句: INSERTINTO authors(id,name,phone) VALUES(‘FZ3456’,’李四’,’7654321’) 通过上面两个例子的方法,我们就可以往数据库中添加内容了,需要注意的是,我们插入值 (包含在 VALUES 部分中的)要按照 INSERTINTO 部分中指明的列的顺序,或是在未指 明的条件下按照数据库原始各列的顺序。 3.UPDATE 语句语法 表1.3 UPDATE 语句的组件 ● 将列设定为确定值: UPDATE authors SET zip = ‘350003’ WHERE id = ‘FZ4567’ 通过这个语句我们可以把数据库中 id 为 FZ4567 的条记录的 zip 列的值改为 350003。这时 如果我们无法给出确定的值,比如我们要给 id 为 FZ1234 的那位作者加薪 100 元,则可 以这样改写 SQL 语句语句; ● 基于已有的值来设置新的列值 UPDATE authors SET salary = salary + 100 WHERE id = ‘FZ1234’ 这样,即使不知道 authors 表中的 salary 列值,也可以用一条简单的 UPDATE 语句成功地把 薪水增加 100。 1.DELETE 语句语法 表1.4 DELETE 语句的组件 ● 删除一个表中的所有值: DELETEFROM authors 这条语句的执行结果是删除 authors 表中的所有行。 ● 删除一个表中的指定的行 DELETEFROM authors WHERE id = ‘FZ1234’ 这条语句的执行结果是删表 authors 中id 为 FZ1234 的行。 在前面的一部分内容中我们讲述了最常用的 SQL 语句的基本方法,但这只是 SQL 语句的一 组件 说明 UPDATE 指明要更新的表 SET 指明用来更新的列和分配给那些列的新值 FROM 指明 UPDATE 语句所以处理的对象表 WHERE 指明要更新的数据所满足的标准 组件 说明 DELETEFROM 指明要执行删除操作的表 WHERE 指明要删除行所满足的标准 部分,其它的 SQL 语句由于不常用就不一一讲述了。各位读者如果有兴趣可以参考一些专 门的 SQL 语法资料,这将能使你更好地操纵数据库,更好地通过数据库来帮助你完成你的 工作。 ((( ( 四))) ) 中小型关系型数据库简介 1.2 中小型关系型数据库简介 1.2.1 关系型数据库简介 在我们对数据库操作进行讲解前,我们觉得有必要向大家介绍一下关系型数据库这个概念, 因为我们觉得无论是你做什么样的系统,都或多或少要接触到数据库,而现在提到数据库, 当然就是关系型数据库了。那么,什么是关系型数据库(RDB)呢? 在关系型数据库中数据以行和列的形式存储,以便于用户理解,这一系列的行和列被称为表 , 一组表便组成了数据库。在关系数据库中:各数据项之间用关系来组织,关系(relationship)是 表之间的一种连接,通过关系,我们可以更灵活地表示和操纵数据;另外,用户可以非常方 便的用查询(Query)来检索数据库中的数据,一个 Query 是一个用于指定数据库中行和列 的SELECT 语句。 关系型数据库通常包含下列组件: ● 客户端应用程序(Client) ● 数据库服务器(Server) ● 数据库(Database) SQL 是Client 端通往 Server 端的桥梁,Client 用SQL 来象 Server 端发送请求,Server 返回 Client 端要求的结果。 现在比较流行的大中型关系型数据库有 IBM DB2、Oracle、SQL Server、SyBase、Informix 等,常用的小型数据库有 Access、Pradox、Foxpro 等,现在个人用户比较常用的主要是基于 中小型数据库 MSSQL Server 和Access的,所以在以下的篇幅中我们介绍这两种数据库系 统的简单操作。 ((( ( 五)Access )Access )Access )Access 数据库及其基本操作 1.2.2 Access数据库及其基本操作 Access是一个数据库管理系统,它之所以被集成到 Office中而不是 Visual Studio 中,是因为 它与其它的数据库管理系统(如 Visual FoxPro)相比更加简单易学,一个普通的计算机用户 即可掌握并使用它。而且最重要的一点是, Access的功能足够强大,足以应付一般的数据 管理及处理需要。 下面,让我们以用 MS Access创建一个数据库为例介绍这种数据库的基本用法,需要说明的 是,该数据库中包含了一张结构如图 1.1 的表。 1.新建数据库 新建一个数据库有两种方法:一种是创建一个空数据库,即建立一个没有表、查询、窗体和 报表等内容的数据库;另一种方法是使用 Access中提供的数据库模板创建数据库,即通过 对向导所提出的选项和不同选择来设计窗体、查询和报表等,从而建立一个完整的数据库。 这里我们将使用第一种方法: Step1:在 Access窗口中单击 “文件(F)”菜单,在下拉菜单中选择 “新建”项,将得到如 图1.2 所示的对话框。 图1.2 “新建”对话框 Step2:双击 “数据库” 图标,即会显示 “文件新建数据库” 对话框,如图 1.3 所示 图1.3 “文件新建数据库”对话框 Step3:在文件名文本框中输入要保存数据库的文件夹及新建的数据库名,如 “C:\test”,然 后选择 “确定”。即可创建好一个名为 “test” 的数据库,并显示如图 1.4。 图1.4 test 数据库窗口 二.添加数据表 表是 Access数据库的基础,是信息的载体。其它对象如查询、窗体和报表,也是将表中的 信息以各种形式表现出来,方便用户使用这些信息。在 Access中,创建表的方法有三种: 一是使用设计器创建表;二是通过输入数据创建表;三是利用向导创建表。在这里,我们采 用第一种方法创建表: Step4:在图 1.4 的窗体中,双击 “使用设计器创建表”,则会出现如图 1.5 所示的对话框。 图1.5 表设计器对话框 Step5:在“字段名称”列的第一行中输入 authors 表的第一个字段的名字 id。然后按回车键 , 此时在“数据类型”列中会显示出一个按钮,单击按钮,在弹出的下拉列表中选择“文本” 选项,设置 id 字段的类型为文本型。如图 1.6 所示。 图1.6 设置字段数据类型 Step6:在“字段属性”域的“常规”选项卡中,可以设置字段的大小、格式和规则等。如 我们可以把 id 字段的长度大小设置为 12,并且规 定 其 不 能 为 空 ,因此,可以设 置 如 下 :在“字 段大小”文本框中输入 12,在 “必填字段”文本框中输入“是”,在“允许空字符串”文 本框中输入“否”。如图 1.7 所示。 图1.7 设置字段属性内容 Step7:重复上述方法,添加其它字段,并设置其属性。 Step8:设置完成后,单击 “文件(F)”菜单,在下拉菜单中选择 “保存”项,将会出现一 个如图 1.8 的对话框,在“表名称”文本框中输入表名 authors,单击确定按钮。 图1.8 “保存”对话框 Step9:此时,系统会提示用户建立一关键字段。一般情况下单击“是”完成即可。 1.2.2 Access数据库及其基本操作 三.表的操作 在添加了数据表之后,我们实际上就初步地完成了一个数据库的建立工作,接下来我们就可 以通过 SQL 语句对数据库进行操作。当然,在 Access中,对表的操作十分的方便,可以浏 览表;为表添加、删除备忘录;对表记录进行排序,因为 Access是面向一些普通用户的, 所以其操作方法不必要用户清楚 SQL 语句的语法及结构。在此,我们就简要地介绍一下在 Access环境下表的操作。 (1)浏览表 打开原先建立的 test数据库,在对象栏中双击 authors 表的图 1.标即可打开表 authors。如图 1.9 所示。 图1.9 查看表 在打开了数据表之后,我们就可以通过记录选定器(图1.9 中左边界的栏目),定位按钮(图1.9 中左下方)和滚动条(在记录长度和数据超过一屏可以显示的范围时,窗体将自在右边界与右 下边界出现滚动条)。 (2)添加与编辑记录 在打开了的查看窗体中即可添加与编辑记录,其方法如图 1.10 所示。 图1.10 添加与编辑表内容 (3)删除表中的记录 对表中记录的删除两种,一种是删一条的记录,其操作方法如图 1.11 所示,单击该条记录 左边的记录选定器选定该记录,然后单击右键,在弹出的菜单中选择删除记录即可;另一种 操作是删除多条记录,其方法如图 1.12 所示,单击第一条要删除的第一条记录的记录选定 器,同时不要松开鼠标,继续向下拖动,直至覆盖要删除的其它记录为止,然后单击右键并 在弹出菜单中选择删除记录。 图1.11 删除单条记录 图1.12 删除多条记录 ((( ( 六)SQL)SQL)SQL )SQL Server Server Server Server 数据库及其基本操作 1.2.3 SQL Server 数据库及其基本操作 SQL Server 是一种高效的关系数据库系统,它与Windows NT/2000 及Windows 9x 等操作系 统紧密集成。这种安排使 SQL Server 能充分利用操作系统所提供的特性。对于今天复杂的 客户/服务器系统来说,SQL Server 是一个很好的选择。 下面,还是让我们以图 1.1 所示的表为例,在 SQL Server 中建立一个 test数据库,test库中 包含了该表。 1.新建数据库 Step1:启动 SQL Server Enterprise Manager,单击服务器旁的加号(+),其中便包含了已有的 数据库。 Step2:在 Databases 文件夹上单击鼠票右键,选择 New Database 菜单选项。系统会显示 Database Properties 对话框,如图 1.13 所示。 图1.13 用Enterprise Manager 创建一个数据库 Step3:选择 General 标签(如图 1.13,该标签在初始时已默认被选中),在 Name 的文本输入 一个数据库名,我们这里输入的是 test(即是创建后的数据库名)。 Step4:在 Database files 对话框的 Database files 部分,输入文件名、位置、初始大小和文件 组信息(一般按照默认的设置即可)。 Step5:如果你想使 SQL Server 能够自动地按需要增加数据库文件的大小,就应该选择 Automatic grow file 选项,否则则不选取。 Step6:在 Transaction Log 标签中的 Transaction Log 对话框部分,可以输入文件名、位置及 服务日志的初始大小。而日志的大小也可能通过 Automatic grow file 选项来设置是否能按需 要来增加日志文件的大小。 Step7:单击“确定”以完成创建数据库。 以上的(4)—(6)步聚均可按系统原来的默认设置来进行,这也是我们推荐的。 在SQL Server 中,当然也支持通过 SQL 语句来创建数据库,当然这对一个普通用户来说是 没有必要的,并且也是烦琐的,在此,我们不进行详细讲述。 2.创建数据表 Step1:打开 Databases 文件夹,在新建的 test数据库图 1.点上单击鼠标右键,选择 “新建” -> “Table..”菜单项。如图 1.14 所示 图1.14 创建数据表 Step2:在弹出的“选择”名称对话框的文本输入框中输入要创建的数据表名 authors,然后单 击确定以创建新表,如图 1.15 所示。 Step3:设置该表的字段属性,如图 1.16 所示。 Step4:保存设置并退出,新表即建立完成。 图1.15 设置新表的属性 图1.16 设置新表的字段属性 3.表的操作 在SQL Server 中,有提供了类同于 Access的界面予于用户进行对表的操作。限于篇幅,我 们就不在这里进行讲述了。 ((( ( 七)ODBC )ODBC )ODBC )ODBC 与ADO ADO ADO ADO 对象111 1 1.3 ODBC 与ADO 对象 1.3.1 ASP 访问数据库的几种方式 在我们介绍了数据库操作的基础知识后,我们接下来的任务是告诉大家如何用 ASP 访问数 据库,因为一个系统不可能没有数据呀,所以我们就必须让 ASP 采用一个高效的方法通过 Internet 或Intranet 来访问、操作数据库。我们知道在传统的 HTML页面中,访问数据库一 般是通过公用网关接口(CGI)来实现,这种方式不仅开发困难,而且在出现大量并发请求 时会显著地降低服务器的运行效率,而采用 ASP 实现数据库访问可以说能较好地解决这个 问题。 在ASP 脚本中可以通过三种方式访问数据库: ● IDC(Internet Database Connector)方式 ● ADO(ActiveX Data Objects)方式 ● RDS(Remote Data Service)方式 从概念上来讲,这三种访问方式对数据库的访问是由 Internet Information Server 来完成的。 Web 浏览器用 HTTP 协议向 Internet 信息服务器(IIS)递交请求。Internet 信息服务器执行 访问数据库的操作,并以一个 HTML格式的文档作为回答。 1.Internet 数据库接口(IDC) IDC 是一个传统的数据库查询工具,用来定义和执行数据库查询的 SQL 命令,并向浏览器 返回一个指定数据格式的页面。使用 IDC 访问数据库最大的特点是简单,几乎不需要编程 就能实现对数据库的访问。 2.ActiveX 数据对象(ADO) 与IDC 不同,用 ADO 访问数据库更类似于编写数据库应用程序,ADO 把绝大部分的数据 库操作封装在七个对象中,在 ASP 页面中编程调用这些对象执行相应的数据库操作。ADO 是ASP 技术的核心之一,它集中体现了 ASP 技术丰富而灵活的数据库访问功能。 ADO 建 立了基于 Web 方式访问数据库的脚本编写模型,它不仅支持任何大型数据库的核心功能, 而且支持许多数据库所专有的特性。ADO 使用本机数据源,通过 ODBC 访问数据库。这些 数据库可以是关系型数据库、文本型数据库、层次型数据库或者任何支持 ODBC 的数据库。 ADO 的主要优点是易用、高速、占用内存和磁盘空间少,所以非常适合于作为服务器端的 数据库访问技术。相对于访问数据库的 CGI 程序而言,它是多线程的,在出现大量并发请 求时,也同样可以保持服务器的运行效率,并且通过连接池(Connection Pool)技术以及对 数据库连接资源的完全控制,提供与远程数据库的高效连接与访问,同时它还支持事务处理 (Transaction),以开发高效率、高可靠性的数据库应用程序。 正是因为使用 ADO 需要编写脚本程序,所以 ADO 能够实现更复杂、更灵活的数据库访问 逻 辑 。目前 ,ADO 包括 Command、Connection、Recordset 等七个对象和一个动态的 Properties 集合,绝大部分的数据库访问任务都可以通过它们的组合来完成。 1.3 ODBC 与ADO 对象 1.3.1 ASP 访问数据库的几种方式 3.远程数据服务(RDS) RDS 是IIS 1.0 中新提出的概念,它是由 ASP 中原来的 Advanced Data Connector(ADC)发 展而来的。在IIS 1.0 中,RDS 与ADO 集成到一起,使用同样的编程模型,提供访问远程数 据库的功能。 ADO 虽然能够提供非常强大的数据库访问功能,但是它不支持数据远程操作 (DataRemoting)。换句话说,ADO 只能执行查询并返回数据库查询的结果,这种结果是静 态的,服务器上的数据库与客户端看到的数据没有“活的连接关系”。假如,客户端需要修 改数据库中的数据,就必须构造修改数据的 SQL 语句,执行相应的查询动作。而RDS 就比 ADO 更进一步,它支持数据远程操作。它不仅能执行查询并返回数据库查询结果,而且这 种结果是“动态的”, 服务器上的数据库与客户端看到的数据保持“活的连接关系”。即把 服务器端的数据搬到客户端,在客户端修改数据后,调用一个数据库更新命令,就可以将客 户端对数据的修改写回数据库,就象使用本地数据库一样。 由于 RDS 与ADO 集 成 ,RDS 的底层是调用 ADO 来完成的,所以也可以将 RDS 理解为 ADO 的RDS,即ActiveX 数据对象的远程数据服务。RDS 在ADO 的基础上通过绑定的数据显示 和操作控件,提供给客户端更强的数据表现力和远程数据操纵功能。可以说 RDS 是目前基 于Web 的最好的远程数据库访问方式。 以上就是 ASP 访问数据库的三种方式,它们三者各有各的特色。 IDC 十分简单,使用 .idc 文件和.htx 文件分别完成数据库的访问与输出任务,但是使用起来不灵活。ADO 是ASP 中 推荐使用的方式,它功能强大,使用方便,是 ASP 的核心技术之一,但是它在提供用户远 程操作数据库的功能时,比较复杂,实现起来有一定的难度。而 RDS 是基于 ADO 的,并 提供远程操作数据库的强大工具。所以在需要提供高性能、高可靠性的远程数据操作功能时 , RDS 是更为理想的选择。 而在以上的三种方式中,微软推荐的与现在常采用的都是通过 ADO 的方式访问数据库,因 此接下来,我们就来讲述一下有关 ADO 的方案。 1.3.2 创建和配置 ODBC 数据源 ADO 可以与 ASP 结合,以建立提供数据库信息的主页内容,在主页画面执行 SQL 命 令 , 让用户在浏览器画面中输入,更新和删除站点服务器的数据库信息; ADO 使用 RecordSets 对象,作为数据的主要接口;ADO 可使用 Vbscript,JavaScript 语言来控制数据库的访问,与 查询结果的输出显示画面;ADO 可连接多种的数据库,包括 SQL Server、Oracle、Informix 等支持 ODBC 的数据库。因此,在使用 ADO 访问数据库之前我们还有一项重要的工作要做 , 那就是创建和配置 ODBC 数据源。 1. ODBC 的定义 首先,还是也让我们来解释一下有关 ODBC 的概念,这将有利于下面内容的理解。 ODBC (Open Database Connectivity 开放式数据库互联)是微软推出的一种工业标准,一种开放的 独立于厂商的 API 应用程序接口,可以跨平台访问各种个人计算机、小型机以及主机系统。 ODBC 作为一个工业标准,绝大多数数据库厂商、大多数应用软件和工具软件厂商都为自己 的产品提供了 ODBC 接口或提供了 ODBC 支持,这其中就包括常用的 SQLSERVER、 ORACAL、INFORMIX 等,当然也包括了 Access。 数据库驱动程序使用 Data Source Name (DSN) 定位和标识特定的 ODBC 兼容数据库,将信 息从 Web 应用程序传递给数据库。典型情况下,DSN 包含数据库配置、用户安全性和定 位信息,且可以获取 WindowsNT 注册表项中或文本文件的表格。通过 ODBC,我们可以 选择希望创建的 DSN 的类型:用户、系统或文件。 为了更好地让大家理解上一段话,我们接下来来解释一下其中的几个名词: ● DSN:根据 MICROSOFT 的官方文档,DSN 的意思是“应用程序用以请求一个连到 ODBC 数据源的连接(CONNECTION)的名字”,换句话说,它是一个代表 ODBC 连接的符号。它隐 藏了诸如数据库文件名、所在目录、数据库驱动程序、用户 ID、密码等细节。因此,当建 立一个连接时,你不用去考虑数据库文件名、它在哪儿等等,只要给出它在 ODBC 中的 DSN 即可。 ● FILEDSN: 当我们讨论这个问题时,先看看其他的 DSN 类型 ● SYSTEMDSN:这种 DSN 可以被任何登录到系统中的用户使用。 ● USERDSN:这是为特定用户建立的 DSN。只有建立这个 DSN 的用户才能看到并使用 它。在上面的两种情况中,DSN 的细节都储存在系统的注册表中。 2.配置 ODBC 数据源 接下来我们就讲述一下系统 DSN 的配置过程。 首先在 Windows 的“开始”菜单打开“控制面板”,双击“ODBC”图1.标,然后选择“文 件 DSN”属性页,单击“添加”,如图 1.17 所示。接下来的操作将视我们要配置的数据库 系统的不同而有不同的操作,由于我们介绍的主要是基于 Access数据库和 SQL Server 数据 库的,所以接下来的两个部分我们讲分别讲述 Access数据库系统 DSN 和SQL Server 数据 库系统 DSN 的配置方法。 图1.17 配置系统 DSN (1)Access数据库系统 DSN 的配置方法 Step1:单击添加后弹出如图 1.18 所示的对话框,选择数据源为 Driver do Microsoft Access (*.mdb)单击完成。 Step2:这时弹出一个 “ODBC MicrosoftAccess安装”的对话框,在对话框的数据源名文本 输入框中输入配置的 DSN 文件名,如果 test_dsn然后单击 “选择”按钮。如图 1.19 所 示 。 Step3:这时将弹出一个如图 1.20 所示的对话框,在对话框的数据库名中输入 “c:\test.mdb” (该数据库的建立方法请参看前边的章节 ),或是从右边的目录浏览器中选择 “驱动器 C”- > “test.mdb”。选择数据库完成后,单击确定按钮将回到图 1.19 的界面。 Step4:单击“确定”,这时出现的界面如图 1.21 所示,请注意,这时在系统数据源列表框中 出现了“test_dsn” 项。Access数据库系统 DSN 配置完成。 图1.18 选择配置 Access数据库 DSN 图1.19 ODBC Microsoft Access 安装对话框 图1.20 选择 Access数据库 图1.21 完成对 test.mdb 数据库系统 DSN 的配置 ((( ( 七)ODBC )ODBC )ODBC )ODBC 与ADO ADO ADO ADO 对象222 2 1.3 ODBC 与ADO 对象 1.3.2 创建和配置 ODBC 数据源 2.配置 ODBC 数据源 (2)SQL Server 数据库系统 DSN 的配置方法 Step1:在图 1.17 所示的对话框中单击“添加”按钮,在弹出的对话框中的驱动程序中选择 SQL Server 项。如图 1.22 所示。 图1.22 选择配置 SQL Server 数据库 DSN Step2:单击“完成”,这时将弹击一个对话框,在对话框的名称文本输入框中输入要配置的 DSN 文件名如“test_dsn_sql”在服务器文本输入框中输入 SQL Server 的服务器名或 IP地址 , 如果 SQL Server 也是本机的话则输入“127.0.0.1”。如图 1.23 所示。 图1.23 建立数据源连接到 SQL Server (1) Step3:单击“下一步”,这时弹出一个如图 1.24 的对话框,此时我们如果在第二步时选择的 是通过 IP地址连接服务器,请选择客户端配置选项,调出如图 1.25 所图示配置对话框。 图1.24 建立数据源连接到 SQL Server (2) 2.配置 ODBC 数据源 (2)SQL Server 数据库系统 DSN 的配置方法 Step5:单击“下一步”,进入到如图 1.26 所示的对话框,在“改变默认的数据库”的复选框 中打勾,并选择 test数据库(该数据库的建立方法请参看前边的章节),如图所示。 图1.26 建立数据源连接到 SQL Server (3) Step6:单击“下一步”,弹出如图 1.27 所示的对话框。 Step7:单击“完成”,弹出如图 1.28 所示的对话框。 Step8:通常,在设置完连接 SQL Server 数据库的 DSN 的时候都要进行数据源测试,所以我 们要单击“测试数据库”按钮以进行测试,如果测试成功则会出现如果图 1.29 所示的对话 框,否则请检查请边各步骤是否正确完成。 图1.27 建立数据源连接到 SQL Server (4) 图1.28 建立数据源连接到 SQL Server (5) 图1.29 测试数据源 Step9:单击“确定”,这时在系统数据源列表框中出现了 “test_dsn_sql” 项,SQL Server 数据库系统 DSN 配置完成。 注意,在配置 ODBC 数据源以前,请确定数据库已建立完成,如果是配置 SQL Server 数据 源的话还得确定 SQL Server 在运行状态。 1.3.3 用ADO 实现访问数据库 前面我们已经谈过有关 ADO 的概念,现在我们要开始讲述如何使用 ADO 来访问数据库, 首先,让我们来看一下在服务器端所需要的 ADO 执行环境: ● 安装 WindowsNT/2000 Server 或是 Personal Web Sever ● 安装 Internet Information Server(IIS)3.0(含)以上版本 ● 在用户端所需要的 ADO 执行环境,只需要一般的浏览器即可。 接下来我们来看一下 ADO 包括的七个对象: ● Command:定义对数据源进行操作的命令; ● Connection:建立一个数据源的连接; ● Error:提供数据访问错误的细节; ● Field:表示一般数据类型的字段; ● Parameter:表示 Command 对象的参数; ● Property:表示由数据源定义 ADO 对象的动态特性; ● Recordset:数据库命令结果集对象。 灵活运用上述对象的属性、方法可以达到许多很好的效果。但通过 ADO 访问数据库的基本 步骤通常都是以下五步: ● 创建数据库源名 ● 创建数据库链接 ● 创建数据对象 ● 操作数据库 ● 关闭数据对象和链接 (1)创建数据库源名,即创建和配置 ODBC 数据源,该步骤在上一节我们已详细讲述 。 (2)创建数据库链接: ASP 文件中如果要访问数据,必须首先创建与数据库的链接,其语法如下: Set Conn = Server CreateObject (“ADOBD.CONNECTION”) 这条语句创建了链接对象 Conn,接下来: Conn.Open “dsn_name”,“username”,“password” 这条语句打开链接,用到了 DSN,本例中 DSN 名为“dsn_name”。其后的两个参数分别是 访问数据库的用户名和口令,为可选参数。 如我们前边对系统 DSN 的设置,这一段代码可以写为: 访问 Access数据库系统 DSN: Set Conn = Server CreateObject (“ADOBD.CONNECTION”) Conn.Open “test_dsn” 访问 SQL Server 数据库系统 DSN: Set Conn = Server CreateObject (“ADOBD.CONNECTION”) Conn.Open “test_dsn_sql”,“sa”,“passwd” 其中的“sa”为访问 SQL Server 数据库的帐号,“passwd”为该帐号的访问口令,具体的内 容创建数据库时的设定。 在ADO 中还可以不通过 ODBC 而直接与 Access数据相连,这种方法在个人主页中大量使 用(因为其用户无法进行服务器 ODBC 设置操作),我们这里只简单提一下方法: Connection.Open “driver = {Microsoft Access Driver (*.mdb) }; dbq=c:\test.mdb” (3)创建数据对象: RecordSet 保存的是数据库命令结果集,并标有一个当前记录。以下是创建方法: Set RecordSet = Conn.Execute(sqtStr) 这条语句创建并打开了对象 RecordSet,其中 Conn 是先前创建的链接对象,SqlStr 是一个串 , 代表一条标准的 SQL 语句,例如: SqlStr = “SELECT*FROM authors” Set RecordSet=Conn.Execute (SqlStr) 这条语句执行后,对象 RecordSet 中就保存了表 authors 中的所有记录。 (4) 操作数据库: Execute 方法的参数是一个标准的 SQL 语句串,所以我们可以利用它方便地执行数据插入、 修改、删除等操作,例如: qlStr = "DELETEFROM authors" Conn.Execute (SqlStr) /执行删除操作 SqlStr = "UPDATE authors SET salary=3 WHERE id= ‘FZ0001’" Conn.Execute (SqlStr) /执行修改操作 (5) 关闭数据对象和链接: 在使用了 ADO 对象之后,一定要记住关闭它,因为它使用了服务器的资源,如果不释放的 话将导致服务器资源浪费并影响服务器性能。通过调用方法 close实现关闭,然后再释放它 , 例如: Conn.Close
还剩49页未读

继续阅读

下载pdf到电脑,查找使用更方便

pdf的实际排版效果,会与网站的显示效果略有不同!!

需要 10 金币 [ 分享pdf获得金币 ] 2 人已下载

下载pdf

pdf贡献者

libredmine

贡献于2012-05-19

下载需要 10 金币 [金币充值 ]
亲,您也可以通过 分享原创pdf 来获得金币奖励!
下载pdf