MS 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
GROUP BY A1.store_name
查询结果显示为:
Store Total Sales
Los Angeles $1800
San Diego $250
Boston $700
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)
介绍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 命令:
CREATE TABLE
ALTER TABLE
DROP TABLE
CREATE INDEX
DROP INDEX
DCL 命令用于创建关系用户访问以及授权的对象。下面是几个DCL 命令:
ALTER PASSWORD
GRANT
REVOKE
CREATE SYNONYM
为了让你对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)
表的基础知识
关系数据库通常包含多个表。数据库实际上是表的集合,数据库的数据或者信息都是存
储在表中的。表是对数据进行存储和操作的一种逻辑结构,每一个表都代表一个对用户意义
的对象。例如,一个公司数据库中,会有雇员表、部门表、库存表、销售表、工资表等等。
我们经常见到的成绩表就是一种表,它是有行和列组成的,我们并且可以通过名字来识别数
据。列包含了列的名字、数据类型以及列的其它属性;行包含了列的记录或者数据。下面给
出一个成绩单,其中姓名、语文、数学、英语都是列,而行包含了这个表的数据,即每个人
的各科成绩:
(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)
创建表
这个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)
插入数据到表
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)
删除表
Drop table 命令用于删除一个表格或者表中的所有行。其语法格式为:
drop table "tablename"
下面举个例子:
drop table employee;
为了删除整个表(包括所有的行),可以使用drop table 命令后加上tablename。Drop table
命令跟从表中删除所有记录是不一样的:
删除表中的所有记录是留下表格(只是它是空的)以及约束信息;而drop table 是删除
表的所有信息,包括所有行、表格以及约束信息等等。
(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)
删除记录
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
语句
在上面的教程中已经有用到SELECT 语句。在本节教程中将详细对它进行阐述。
SELECT 语句是SQL 的核心,在你的SQL 语句中可能用的最多的就是SELECT 语句了。由
于大量的选项可以用于SELECT 语句,所以整个教程好象就是围这SELECT 语句转。当我
们构造SQL 查询语句(利用了SELECT 语句)的时候,认识所有的可能选项和最好的或者
最有效率的方法来实现是很有用的。这个教程将为你提供这些技能。
SELECT 语句用于查询数据库并检索匹配你指定条件的选择数据。SELECT 语句有五个
主要的子句子你可以选择,而FROM 是唯一必须的子句。每一个子句有大量的选择项、参
数等等。这些子句将罗列在下面,而且它们每一个都将在以后的教程有更为详细的描述。
以下是SELECT 语句的格式:
SELECT [ALL | DISTINCT] column1[,column2]
FROM table1[,table2]
[WHERE "conditions"]
[GROUP BY "column-list"]
[HAVING "conditions]
[ORDER BY "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 指定的列复制的记录,
比如:
SELECT DISTINCT age
FROM employee_info;
这条语句将返回所有在employee_info 表中单一的age 数据。
而ALL 就将显示所有指定的类,包括所有的复制数据。在没有指定的时候,这个ALL 关键
字是缺省的。
(10)
合计函数
所有的合计函数如下表所示:
= 等于
> 大于
< 小于
>= 大于等于
<= 小于等于
<> 不等于
LIKE 字符串比较测验
MIN 返回一个给定列中最小的数值
MAX 返回一个给定列中最大的数值
合计函数用于从SELECT 语句中计算一个”返回列的数据”。它们是总结了所选数据
列的结果。虽然它们需要"GROUP BY"子句(后面一个教程介绍),但是这些函数也可以在
不用使用"GROUP BY"子句的情况被使用,比如:
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
BY
子句
GROUP BY 子句
首先讲讲GROUP BY 子句语法:
SELECT column1, SUM(column2)
FROM "list-of-tables"
GROUP BY "column-list";
这个GROUP BY 子句将集中所有的行在一起,它包含了指定列的数据以及允许合计函数来
计算一个或者多个列。当然最好解释的方法是给出一个例子啦:
假设我们将从employee 表中搜索工资最高的列,可以使用以下的SQL 语句:
SELECT max(salary), dept
FROM employee
GROUP BY dept;
这条语句将在每一个单独的部门中选择工资最高的工资。结果他们的salary 和dept 将被返
回。
SUM 返回一个给定列中所有数值的总和
AVG 返回一个给定列中所有数值的平均值
COUNT 返回一个给定列中所有数值的个数
COUNT(*) 返回一个表中的行数
(12)HAVING
子句
HAVING 子句
下面先给出HAVING 子句的语法:
SELECT column1, SUM(column2)
FROM "list-of-tables"
GROUP BY "column-list"
HAVING "condition";
这个HAVING 子句允许你为每一个组指定条件,换句话说,可以根据你指定的条件来选择
行。如果你想使用HAVING 子句的话,它应该处再GROUP BY 子句之后。
下面将以一个例子来解释HAVING 子句。假设我们的employee 表中包含雇员的name、
departmen、salary 和age。如果你想为每个部门中每个雇员选择平均工资的话,你可以使用
下面的SQL 语句:
SELECT dept, avg(salary)
FROM employee
GROUP BY dept;
当然,如果你还想只计算和显示salary 大于20000 的平均工资的话,你还可以加上HAVING
子句:
SELECT dept, avg(salary)
FROM employee
GROUP BY dept
HAVING avg(salary) > 20000;
(13)ORDER
BY
子句
ORDER BY 子句
ORDER BY 子句的语法为:
SELECT column1, SUM(column2)
FROM "list-of-tables"
ORDER BY "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'
ORDER BY 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'
ORDER BY salary, age DESC;
(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.00 AND 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
和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 运算符时语句会更加简短并且容易读,特别是在你测试两个或者三
个数值以上的时候尤为突出。
当然你也可以使用NOT IN 来在你的列表中排除行的。
而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;
当然,你也可以类似于NOT IN 的方法,使用NOT BETWEEN 来排除一些数据。
(16)
数学运算符
标准的ANSI SQL-92 支持下面四个基本的算术运算符:
+ 加
- 减
* 乘
/ 除
其中求余运算符决定除法的余数。这个运算符不是ANSI SQL 支持的,但是,绝大多数
的数据库支持他。下面是一些有用的数学函数,因为可能要用到它,所以我这里要集中提一
下。在ANSI SQL-92 中不支持这些函数,但是它们可能对于某些特殊的RDBMS 是有效的。
然而它们对于几个主要的数据库系统都是有效的。下面就说说这些数学函数吧:
下面举个例子:
SELECT round(salary), firstname
FROM employee_info
上面这条语句将从employee_info 表中选择salary 最接近的数以及firstname 列。
(17)JOIN
子句
不知你有没有发现直到现在我们利用SELECT 语句来检索的时候只能从一个表中进行。
如果你想从两个表或者更多的表中进行检索,该怎么办呢?好在我们可以使用SQL 和关系
数据库系统的一个很有用的特性,即"Join"。为了简单说明,实际上"Join"就是使得关系数据
库系统相关的东东。"Join"允许你从两个表或者更多的表连接数据进行数据检索,而只需要
利用一个SELECT 语句。如果在FROM 关键字之后有多个表的话,"Join"可以在SQL SELECT
语句中识别它们。
下面举个例子:
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 语法规范中的
INNER JOIN):
SELECT customer_info.firstname, customer_info.lastname, purchases.item
FROM customer_info INNER JOIN 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)
索引
索引允许DBMS 更快地访问数据。系统创建了这个内部地数据结构(即索引),它导致
当查询以列为索引的时候搜索行,这样查询会快得多。这个索引对于给定列索引数值的时通
知DBMS 找到表中某一行,这有点象书的索引,它告诉你对于给定的字你能找到哪一页。
下面让我们在AntiqueOwners 列中为OwnerID 创建索引:
CREATE INDEX OID_IDX ON ANTIQUEOWNERS (OWNERID);
下面语句是为名字创建所以:
CREATE INDEX NAME_IDX ON ANTIQUEOWNERS (OWNERLASTNAME,
OWNERFIRSTNAME);
为了删除索引,你可以利用DROP:
DROP INDEX OID_IDX;
就象前面教程中,我们也可以"drop"(删除)一个表。上面第二个例子中,是在两列上
创建索引的。
有些DBMS 不强迫要求主键,换句话说就是,类的唯一性不会自动强制。这是什么意
思呢,好象听起来云里雾里的。好吧,再给你举个例子,如果你象插入另外一行到
AntiqueOwners 表中,比如这个OwnerID 是02,有些系统可以让你这样做即使我们要求所
有行的数值都要是不同的。为了避免两行有相同的值,我们有一种方法来克服,就是在列上
创建唯一的索引,而在这个列上我们需要它成为主键,这样就可以系统不会出现复制的情况:
CREATE UNIQUE INDEX OID_IDX ON ANTIQUEOWNERS (OWNERID);
(19)DISTINCT
和排除复制
假如你象列出所有买过古董的ID 和名字,很明显,你可能会将所有的顾客都列出来而
没有考虑有些顾客是买过多讲古董的,所以这时你会发现有些数据是重复的。这就意味着你
需要通知SQL 来排除复制的行,而不管这个顾客买过多少个古董只需要列出一次即可。为
了实现这个目的,你可以使用DISTINCT 关键字。
首先我们需要为AntiqueOwners 表来一个equijoin 以得到顾客的LastName 和First 的详
细数据。但是,你要考虑到Antiques 表中的SellerID 列是AntiqueOwners 表的一个外码,所
以顾客只能在AntiqueOwners 表列出ID 和名字的行才被列出。我们还想在列的数据中排除
SellerID 复制的发生,所以我们要在发生重复的列上使用DISTINCT 。
为了防止复制的发生,我们还想将LastName 以字母顺序排列,然后在按字母顺序排列
FirstName 最后排列OwnerID,因此我们还必须使用ORDER BY 子句,具体语句如下:
SELECT DISTINCT SELLERID, OWNERLASTNAME, OWNERFIRSTNAME
FROM ANTIQUES, ANTIQUEOWNERS
WHERE SELLERID = OWNERID
ORDER BY OWNERLASTNAME, OWNERFIRSTNAME, OWNERID
在这个例子中,因为每个人都买都一个件古董,所以我们将Lasname 以字母顺序列出
所有的古董拥有者。
(20)Aliases
、In
以及子查询
在本节教程中,我们将要介绍Aliases、In 以及子查询的用法。首先我们看一下一个查
询语句,它搜索所有已经定货的顾客的LastName 以及他们定什么货,语句如下:
SELECT OWN.OWNERLASTNAME Last Name, ORD.ITEMDESIRED Item Ordered
FROM ORDERS ORD, ANTIQUEOWNERS OWN
WHERE ORD.OWNERID = OWN.OWNERID
AND ORD.ITEMDESIRED IN
(SELECT ITEM
FROM ANTIQUES);
这条查询语句的结果为:
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)
更多的子查询
我们可以使用在SELECT 查询语句中再包括一个SELECT 子查询语句。举个例子吧,
首先我们列除所有购买贵重物品的顾客,贵重物品的标准是比所有卖出的物品价钱的平均值
多100 元的物品。具体语句如下:
SELECT OWNERID
FROM ANTIQUES
WHERE PRICE >
(SELECT AVG(PRICE) + 100
FROM ANTIQUES);
上面子查询语句是计算物品的平均价格再加100 元,并搜索所有在ANTIQUES 表中
PRICE 大于这个数值的OWNERID。这里你可以使用DISTINCT OWNERID 来排除复制的
现象。
下面的语句列出了所有在AntiqueOwners 表中的有买过物品的人的LastName:
SELECT OWNERLASTNAME
FROM ANTIQUEOWNERS
WHERE OWNERID =
(SELECT DISTINCT BUYERID
FROM ANTIQUES);
这个子查询返回了一系列的顾客,当且仅当物品拥有者的ID 出现在子查询的列表中,
古董的拥有者的LastName 才会显示出来。
为了更新这个例子,我们假设有一个买过bookcase 的顾客,他的FirstName 在数据库中
出错了,应该为John:
UPDATE ANTIQUEOWNERS
SET OWNERFIRSTNAME = 'John'
WHERE OWNERID =
(SELECT BUYERID
FROM ANTIQUES
WHERE ITEM = 'Bookcase');
上面的语句中的子查询首先搜索买过bookcase 的顾客的BuyerID,然后在外层的查询中
来更新他的FirstName。
(22)EXISTS
和ALL
EXISTS 使用了一个子查询作为条件,只有当子查询返回行的时候这个条件才为真,如
果子查询不返回任何的行条件就为假。如果商店在处理Chair 的时候,有个顾客想看看所有
拥有者的列表,就可以使用EXSIST,语句如下:
SELECT OWNERFIRSTNAME, OWNERLASTNAME
FROM ANTIQUEOWNERS
WHERE EXISTS
(SELECT *
FROM ANTIQUES
WHERE ITEM = 'Chair');
如果在Antiques 列中有Chair,那么子查询就会返回一行或者多行,就使得EXISTS 子
句为真,然后让SQL 列出拥有者来。如果没有搜索到Chair,则没有行被返回,条件就为假。
ALL 是另外一个不寻常的关键字,因为ALL 查询通常可以用不同的方法来进行,并且
可能是一种更为简单的方法。举个例子来说明吧:
SELECT BUYERID, ITEM
FROM ANTIQUES
WHERE PRICE >= ALL
(SELECT PRICE
FROM ANTIQUES);
上面这条语句将返回最高价格的Item 以及它的买方。子查询返回了Antiques 表中的所
有的Price 列,而外层的查询逐行查询Antiques 表,并且如果它的Price 大于等于(或者ALL)
列中的Prices,它就会被列出,它就是最好价格的Item。这里必须使用">="的原因是最高价
格的Item 要等于列表中的最高价格,因为这个Item 在Price 列中。
(23)UNION
和外部连接
有些时候,你可以想一起看多个查询的结果、组合它们的输出,你可以使用UNION 关
键字。为了合并以下两个查询的输出:显示所有买方的ID 和已经有定货的顾客,你可以使
用以下语句:
SELECT BUYERID
FROM ANTIQUEOWNERS
UNION
SELECT OWNERID
FROM ORDERS;
这里要注意SQL 要求SELECT 的列表必须匹配,即列于数据类型匹配。在本例子中,
BuyerID 和OwnerID 都是相同的数据类型,同为Interger(整型)。同时还有一提的是,SQL
但使用UNION 的使用会进行自动复制排除。而在单一的查询中,你就必须使用DISTINCT。
Outer Join (外部连接)通常是在JOIN 查询被联合,而行没有包括到JOIN 中的时候使
用,特别是在常量文本"flags"被包括的时候尤为有用。下面我们看看这个查询先:
SELECT OWNERID, 'is in both Orders & Antiques'
FROM ORDERS, ANTIQUES
WHERE OWNERID = BUYERID
UNION
SELECT BUYERID, 'is in Antiques only'
FROM ANTIQUES
WHERE BUYERID NOT IN
(SELECT OWNERID
FROM ORDERS);
第一个查询做了一个连接以列出两个表中的每个owener,并且在ID 后面放置一个标记
线来重复引用。这个UNION 合并了这个列表以及以下第二个的列表。第二个列表是列出不
是在Orders 表的ID,这样就产生了在JOIN 查询之外的ID 列表,它是利用引用标签列出的。
这可能是一种最容易的方法来产生这个列表。
这个概念对于主键跟外码有关的状况是很有用的,但是有些主键的外码值是NULL。比
如,在一个表中,主键是salesperson,而在其它的表中主键是customers,并且它们的
salesperson 列在相同的行。然而,如果salesperson 没有customers 的时候,这个人的名字就
不会出现在customer 表中。如果所有salespersons 的列表要显示出来,那么就要外部连接了。
(24)
嵌入式SQL
为了更好的理解嵌入式SQL,本节利用一个具体例子来说明。嵌入式SQL 允许程序连
接数据库并且包括SQL 代码到程序中,这样在程序中就可以对数据库进行使用、操作以及
处理数据等等。以下是用C 语言编写的使用嵌入SQL 的例程,它将打印一个报告;这个程
序必须在普通的编译之前先预编译SQL 语句。嵌入SQL 对于不同系统是不一样的,所以在
不同的系统中对以下的程序稍作修改,特别是变量的声明以及过程记录等。在嵌入SQL 时,
考虑网络、数据库管理系统、操作系统是相当重要的。
以下是详细的代码:
#include <stdio.h>
/* 以下这部分是声明主机变量,它将使用于程序中*/
EXEC SQL BEGIN DECLARE SECTION;
int BuyerID;
char FirstName[100], LastName[100], Item[100];
EXEC SQL END DECLARE SECTION;
/* 以下包括SQLCA 变量,它可以用来进行错误检查*/
EXEC SQL INCLUDE SQLCA;
main()
{
/* 以下连接数据库*/
EXEC SQL CONNECT UserID/Password;
/* 以下是连接数据库并检查是否有错误产生T */
if(sqlca.sqlcode)
{
printf(Printer, "Error connecting to database server.\n");
exit();
}
printf("Connected to database server.\n");
/* 下面声明一个"Cursor"。它将在查询结果多于一行的时候使用*/
EXEC SQL DECLARE ItemCursor CURSOR FOR
SELECT ITEM, BUYERID
FROM ANTIQUES
ORDER BY ITEM;
EXEC SQL OPEN ItemCursor;
/* 你可以在这里还可以加入另外一些错误检查的内容,这里就省略了*/
/* 当这个CURSOR 没有数据, sqlcode 将被产生以允许我们退出循环。这里注意,为
了简单起见,我们使程序遇到错误的时候就退出任何的sqlcode。*/
EXEC SQL FETCH ItemCursor INTO :Item, :BuyerID;
while(!sqlca.sqlcode)
{
EXEC SQL UPDATE ANTIQUES
SET PRICE = PRICE + 5
WHERE ITEM = :Item AND BUYERID = :BuyerID;
EXEC SQL SELECT OWNERFIRSTNAME, OWNERLASTNAME
INTO :FirstName, :LastName
FROM ANTIQUEOWNERS
WHERE BUYERID = :BuyerID;
printf("%25s %25s %25s", FirstName, LastName, Item);
EXEC SQL FETCH ItemCursor INTO :Item, :BuyerID;
}
/* 关闭CURSOR,提交变化并退出程序。*/
EXEC SQL CLOSE DataCursor;
EXEC SQL COMMIT RELEASE;
exit();
}
在SQL
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.
保存images
进SQL
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
("INSERT INTO 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 在另一硬盘或
分区上,利用镜像文件快速还原。
针对SQL
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 ”,进入注册向导,输入目标SQL Server
的计算机名后,填写登录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 语言的基础以及如
何使用MS ACCESS 和MS SQL 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
语言及其优点
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
语言的分类及语法
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 指明返回数据必须满足的标准
GROUP BY 指明返回的列数据通过某些条件来形成组
HAVING 指明返回的集合必须满足的标准
ORDER BY 指明返回的行的排序顺序
● 添加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 ‘
ORDER BY id
这样,这条SQL 语句返回的结果将id 列的升序排序。
1.1.2 SQL 语言的分类及语法
2.INSERT 语句语法
表1.4 INSERT 语句的组件
● 一个简单的INSERT 语句:
INSERT INTO authors
操作符说明
= 等于
> 大于
< 小于
>= 大于等于
<= 小于等于
<> 不等于
IN 位于指定列表值中,或者指定的子查询的结果中
BETWWEEN..AND 位于两个值之间
LIKE
包含与指定串相同的模式。此模式将与一个或多个通
配符的串相比较
组件说明
INSERT INTO
指明要向哪个表中加入行
同时列出指定加入的列,如未指定的对象为表中
的每一列
VALUES 指明在列表中各列的填充值
SELECT SELECT 语句返回被加到表中的各行
VALUES
(‘FZ1234 ’,’张三’,’1234567’,’深圳幸运计算机公司’,’350002’,’本文作者’)
这样,便向表中加入了一条记录。
我们也可以指明用哪几列来填充,看下面的例子;
● 一个简单的INSERT 语句:
INSERT INTO authors(id,name,phone)
VALUES (‘FZ3456 ’,’李四’,’7654321’)
通过上面两个例子的方法,我们就可以往数据库中添加内容了,需要注意的是,我们插入值
(包含在VALUES 部分中的)要按照INSERT INTO 部分中指明的列的顺序,或是在未指
明的条件下按照数据库原始各列的顺序。
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 语句的组件
● 删除一个表中的所有值:
DELETE FROM authors
这条语句的执行结果是删除authors 表中的所有行。
● 删除一个表中的指定的行
DELETE FROM authors
WHERE id = ‘FZ1234 ’
这条语句的执行结果是删表authors 中id 为FZ1234 的行。
在前面的一部分内容中我们讲述了最常用的SQL 语句的基本方法,但这只是SQL 语句的一
组件说明
UPDATE 指明要更新的表
SET 指明用来更新的列和分配给那些列的新值
FROM 指明UPDATE 语句所以处理的对象表
WHERE 指明要更新的数据所满足的标准
组件说明
DELETE FROM 指明要执行删除操作的表
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 等,现在个人用户比较常用的主要是基于
中小型数据库MS SQL Server 和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
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
与ADO
对象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 支持,这其中就包括常用的SQL SERVER、
ORACAL、INFORMIX 等,当然也包括了Access。
数据库驱动程序使用Data Source Name (DSN) 定位和标识特定的ODBC 兼容数据库,将信
息从Web 应用程序传递给数据库。典型情况下,DSN 包含数据库配置、用户安全性和定
位信息,且可以获取Windows NT 注册表项中或文本文件的表格。通过ODBC,我们可以
选择希望创建的DSN 的类型:用户、系统或文件。
为了更好地让大家理解上一段话,我们接下来来解释一下其中的几个名词:
● DSN:根据MICROSOFT 的官方文档,DSN 的意思是“应用程序用以请求一个连到ODBC
数据源的连接(CONNECTION)的名字”,换句话说,它是一个代表ODBC 连接的符号。它隐
藏了诸如数据库文件名、所在目录、数据库驱动程序、用户ID、密码等细节。因此,当建
立一个连接时,你不用去考虑数据库文件名、它在哪儿等等,只要给出它在ODBC 中的DSN
即可。
● FILE DSN: 当我们讨论这个问题时,先看看其他的DSN 类型
● SYSTEM DSN:这种DSN 可以被任何登录到系统中的用户使用。
● USER DSN:这是为特定用户建立的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
与ADO
对象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 执行环境:
● 安装Windows NT/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 = "DELETE FROM authors"
Conn.Execute (SqlStr) /执行删除操作
SqlStr = "UPDATE authors SET salary=3 WHERE id= ‘FZ0001 ’"
Conn.Execute (SqlStr) /执行修改操作
(5) 关闭数据对象和链接:
在使用了ADO 对象之后,一定要记住关闭它,因为它使用了服务器的资源,如果不释放的
话将导致服务器资源浪费并影响服务器性能。通过调用方法close 实现关闭,然后再释放它,
例如:
Conn.Close
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值