职业IT人-IT人生活圈

 找回密码
 成为会员
搜索
查看: 3790|回复: 6

数据库系统与应用——第四章

[复制链接]
cayean 发表于 2007-1-23 10:24 | 显示全部楼层 |阅读模式
4.1.1 SQL语言的发展
  SQL是结构化查询语言(Structured Query Language)的缩写,是关系数据库的标准语言。SQL是1974年在IBM的关系数据库SYSTEM R上实现的语言。它提供给用户一种表示方法说明要查询的结果特性,至于如何查询、以及查询结果的形式都由DBMS来完成。这种语言由于其功能丰富、方便易学受到用户欢迎。1986 年由美国国家标准局(ANSI)及国际标准化组织(ISO)公布作为关系数据库的标准语言。
  SQL名为结构化查询语言, 实际功能包括数据定义、数据操纵和数据控制。目前新的SQL标准是1992年制定的SQL-92,简称SQL2。它的全名是\"International Standard,ISO/IEC9075: 1992Database Language SQL\"。
  在SQL2基础上,又增加了许多新特征,称为SQL3。SQL标准的制定使得几乎所有的数据库厂家都采用SQL语言作为其数据库语言。但各家又在SQL标准的基础上进行扩充,形成自己的语言。
  SQL Server扩充SQL标准称为Transact-SQL,简称T-SQL。
4.1.2 SQL语言的特点:
 1 语言功能的一体化:
  集数据定义DDL、数据操纵DML、数据控制DCL功能为一体。并且它不严格区分数据定义和数据操纵,在一次操作中可以使用任何语句。
  SQL语言具有数据定义、数据操纵和数据控制功能,这为数据库应用开发提供了良好的环境。用户在数据库行以后,可以修改模式,不影响数据库的运行。不象非关系数据库系统,修改模式需要先停止数据库运行,转储数据,修改模式,编译修改了的模式以后再重新装入数据库,使得修改模式非常不方便。
 2 模式结构的一体化:
  关系模型中唯一的结构类型就是关系表,这种数据结构的单一性,使得对数据库数据的增、删、改、查询等操作都只须使用一种操作符。
 3高度非过程化的语言
  使用SQL语言操作数据库,只须提出\"做什么\"无须指明\"怎样做\"。用户不必了解存取路径。存取路径的选择和SQL语句的具体执行由系统自己完成,从而简化了编程的复杂性,提高了数据的独立性。
 4 面向集合的操作方式
  SQL语言在元组集合上进行操作,操作结果仍是元组集合。查找、插入、删除和更新都可以是对元组集合操作。
 5 两种操作方式、统一的语法结构
  SQL语言既是自含式语言,又是嵌入式语言。作为自含式语言,可作为联机交互式使用,每个SQL语句可以独立完成其操作;作为嵌入式语言,SQL语句可嵌入到高级程序设计语言中使用。
 6 语言简洁、易学易用:
  SQL是结构化的查询语言,语言非常简单,完成数据定义、数据操纵和数据控制的核心功能只用了9个动词: Create; Drop;Alter; Select; Delete; Insert; Update; Grant; Revoke。
  SQL的语法简单,接近英语口语,因此容易学习,使用方便。
  SQL语言作为数据库语言,有它自己的词法和语法结构,并有其专用的语言符号,不同的系统稍有差别,主要的符号都相同。下面给出主要的语言符号:
  大括号{ }:大括号中的内容为必选参数,其中可有多个选项,各选项之间用竖线分隔,用户必须选择其中的一项。
  方括号[ ]:方括号中的内容为可选项,用户根据需要选用。
  竖线| :表示参数之间\'或\'的关系。
  省略号\"…\":表示重复前面的语法单元。
  尖括号< >:表示下面有子句定义。
  方括号和省略号[,…n]:表示同样选项可以重复1到n遍;
4.1.3 SQL语言的数据类型      
   1 整数类型:
  整数存储的数字是精确的。在每个整数类型允许的取值范围内,不管多大的数字,存储的空间大小总是一样的。
 · BIGINT 8字节的整型
  BIGINT 可以存储-2EXP(63)到2EXP(63)的所有正负整数,范围从-9223372036854775808到9223372036854775807。每个BIGINT类型占8字节(64BIT),其中63BIT表明数的大小。1BIT表示符号位(正或负)。
 · INT 4字节的整型
  INT 是几种整数类型中常用的一种。可以存储-2EXP(31)到2EXP(31)的所有正负整数,范围从-2147483648到2147483647。每个INT类型占4字节(32BIT),其中31BIT表明数的大小。1BIT表示符号位(正或负)。
 · SMALL INT 2字节的整型
  SMALL INT可以存储-2EXP(15)到2EXP(15)的所有正负整数,范围从-32768到32767。每个SMALL INT类型占2字节(16BIT),其中15BIT表明数的大小。1BIT表示符号位(正或负)。
 · TINY INT 1字节的整型
  可以存储-2EXP(7)到2EXP(7)的所有正负整数,范围从-255到255。每个TINY INT类型占1字节(8BIT),其中7BIT表明数的大小。1BIT表示符号位(正或负)。
 · BIT 1位的整型
  只能表示0或1,一般不用来存储整数,而用来表示真假逻辑关系(TRUE/FALSE)。
 2.浮点数据类型:
  浮点数据类型用来存储十进制小数,但是由于存储位数的限制,有些小数不能精确的表示,这样会存在舍入误差。例如:精确位是15,这样超过15位的数字虽然也能被存储,但是只能用前15位表示,例如,分数 1/3 表示成小数形式为 0.333333(循环小数),该数字不能以近似小数数据精确表示。因此,从 SQL Server 获取的值可能并不准确代表存储的原始数据。
 · FLOAT[(N)]
  从-1.79E+308到1.79E+308之间的浮点数字数据。n为用于存储科学记数法float数尾数的位数,同时指示其精度和存储大小。n必须为从1到53之间的值。如下表4-1。
  · REAL 4字节的浮点数型
  REAL类型的表示范围在-3.40E+38到3.40E+38之间,存储使用4个字节,可以精确到第7位的正负小数。在SQL Server中,real的同义词为float(24)。
 · NUMERIC(n,s) 实型,最大精度n,s为小数位数
  SMALL INT可以存储-2EXP(15)到2EXP(15)的所有正负整数,范围从-32768到32767。每个SMALL INT类型占2字节(16BIT),其中15BIT表明数的大小。1BIT表示符号位(正或负)。
   3.日期/时间类型
  日期和时间数据类型由有效的日期或时间组成。例如,有效日期和时间数据既包括\"4/01/98 12:15:00:00:00 PM\",也包括\"1:28:29:15:01 AM 8/17/98\"。在 Microsoft SQL Server 2000 中,日期和时间数据使用 datetime 和 smalldatetime 数据类型存储。
 · 使用datetime数据类型存储从1753年1月1日至9999年12月31日的日期(每个数值要求8个字节的存储空间)。
  SQL Server用两个4字节的整数内部存储datetime数据类型的值。第一个4字节存储base date(即1900年1月1日)之前或之后的天数。基础日期是系统参考日期。不允许早于1753年1月1日的datetime值。另外一个4字节存储以午夜后毫秒数所代表的每天的时间。精确度为百分之三秒。即使用datetime的数据的尾数总会被调整为靠近尾数的000、003或007。
  例如:01/01/98 23:59:59.999 会被调整为1998-01-02 00:00:00.000
 · 使用 smalldatetime 数据类型存储从 1900 年 1 月 1 日至 2079 年 6 月 6 日的日期(每个数值要求 4 个字节的存储空间)。
  smalldatetime数据类型存储日期和每天的时间,但精确度低于datetime。SQL Server将 smalldatetime的值存储为两个2字节的整数。第一个2字节存储1900年1月1日后的天数。另外一个2字节存储午夜后的分钟数。日期范围从1900年1月1日到2079年6月6日,精确到分钟。29.998秒或更低的smalldatetime值向下舍入为最接近的分钟,29.999秒或更高的 smalldatetime值向上舍入为最接近的分钟。例如12:35:29.998会变为12:35,而12:35:29.999会变为12:36。
 4.字符数据类型:
  大多数情况下存储结构会用字符类型定义。因为字符类型比其它数据类型可以存储更广泛的符号,它可以用来存储字母符号、数字符号、以及各种特殊字符。
 · CHAR(n) :n个字节,具体值由n决定。
  CHAR类型存储的每一个字符占用一个字节,括号内的n指明了要存储长度为n个字节的固定长度且非Unicode的字符数据。n必须是一个介于1和8,000之间的数值。存储大小为n个字节。如果实际输入不足n个字节,SQL Server会自动在后面添加空格来填满设定的空间。
 · NCHAR(n) :2n个字节。具体值由n决定。
  nchar(n)包含 n 个字符的固定长度Unicode字符数据。n 的值必须介于 1 与 4,000 之间。存储大小为 n 字节的两倍。由于unicode采用两个字节表示一个字符,所以存储相同长度的字符,nchar所占的空间是char(n)的两倍。
 · varchar(n):最大为n个字节。
  最大长度为 n 个字节的可变长度且非 Unicode 的字符数据。n 必须是一个介于 1 和 8,000 之间的数值。存储大小为输入数据的字节的实际长度,而不是 n 个字节。所输入的数据字符长度可以为零。一般情况下,使用varchar(n)可以节省不少使用空间。
 · Nvarchar(n):最大为2n个字节。
  包含 n 个字符的可变长度 Unicode 字符数据。n 的值必须介于 1 与 4,000 之间。字节的存储大小是所输入字符个数n的两倍。所输入的数据字符长度可以为零。
 5.数字数据类型:
  包括decimal(p,s)和numeric(p,s)两种数据类型。
  在这两种数据类型中可以精确指定小数点两边的总位数。(精度,precision简写为p)和小数点右边的位数(刻度,scale简写为s)。
 · p(精度):
  指定小数点左边和右边可以存储的十进制数字的最大个数,即整数部分最大的取值范围从-10exp(p)+1到10exp(p)-1,而实际情况取值范围从-10exp(p-s)+1到10exp(p-s)-1。精度必须是从1到最大精度之间的值。最大精度为38。缺省值为18.
 · s(小数位数):
  指定小数点右边可以存储的十进制数字的最大个数。小数位数必须是从 0 到 p 之间的值,因而 0 <= s <= p。缺省值为0。
  Numeric型数据的存储空间随精度的不同而不同。如表4-2所示。
4.2 数据库的建立、修改和删除:
4.2.1 SQL Server的数据库文件
    数据库是SQL Server用于存储对象(如表、索引、触发器、视图、存储过程等)的逻辑实体。SQL Server的数据库由一套操作系统文件组成。数据库中的所有对象都存储在这些操作系统文件中。这些文件可以组成一个文件组,称为数据库文件组。使用的操作系统文件包括主数据文件、辅助数据文件、日志文件三大类。
 · 主数据文件:
  存储指向其他数据库文件的指针和启动信息。每个数据库必须包含一个也只能包含一个主数据文件。主数据文件的扩展名是.mdf。
 · 辅助数据文件:
  所有不适合存储在主数据文件中的数据都存储在辅数据文件中。如果主数据文件可以包含所有的数据,可不用辅助数据文件。大规模的数据库可以有分布在多个磁盘驱动器上的辅助数据文件。辅助文件的扩展名为.ndf。
 · 日志文件:存储数据库的事务日志信息。必要时利用日志恢复数据库。每个数据库至少需要一个日志文件,日志文件的扩展名为.ldf。SQL Server通常是先写日志再进行数据库修改。因此如果数据库系统崩溃,只要保留有完整的日志文件,仍然可以完成对数据库的修复和重建。
  由于数据文件是实际存放数据、索引等数据库对象的地方,因此产生数据库时要认真考虑实际使用时对数据量的需求,以便为将来增加数据库对象存放提供更大的空间。当然,数据文件也不宜设置过大,巨大的数据文件会让SQL Server花费大量空间管理,从而降低使用效率。
 · 数据存储单位:
  SQL Server 数据库文件按照系统定义的存储单位调整文件的大小,SQL Server 数据库使用的数据存储单位有:
 (1) 存储页(page):是SQL Server的基本数据存储单位,每页8KB
 (2) 范围(extent):一个范围是8个连续的存储页,是存储表或索引的基本单位。
 (3) SQL Server可以自动调整数据库和日志文件的大小。
 (4) 划分文件组:SQL Server把数据库文件在逻辑上分成组,把相关文件放入特定文件组中。文件组的类型分为:
 · 缺省组:存放主文件和其他文件。
 · 用户定义的组:由Create命令中的File Group命令定义的数据文件。

[ 本帖最后由 cayean 于 2007-1-23 10:30 编辑 ]
4-21.gif
4-22.gif
 楼主| cayean 发表于 2007-1-23 10:37 | 显示全部楼层
4.2.2. 创建数据库:
  用户必须拥有创建数据库的权限才能在SERVER端创建数据库。在SQL Server中创建数据库有三种途径:
  ①用企业管理器创建数据库;
  ②用创建数据库向导创建数据库;
  ③用Transact_SQL语句创建数据库。

 ① 用企业管理器创建数据库:
  进入企业管理器(Enterprise Manager)界面后,操作步骤如下:选择要建立的数据库的服务器节点,双击并展开该节点,
 · 选中"数据库"节点,打开"操作"菜单或点击鼠标右键,在弹出的快捷菜单中选择"新建数据库"命令,如图4-1。 图4-1.gif  
   · 在弹出的"数据库属性"中,先输入数据库名称,再切换到"数据文件",如图4-2所示。 图4-2.gif
 · 在"数据文件"页输入正确的数据文件名字、位置、大小。SQL Server默认情况下自动为用户输入的文件名后面增加下划线和Data字样,并设置相应的文件扩展名。可以增加一个或多个数据库文件。并分别为每个数据库文件设置存放路径、初始大小和文件组等,如图4-3。 图4-3.gif
  在左下角的文件属性栏中可以选择该数据库文件的增长情况。当存储的数据容量超过初始设置的数据库大小时,SQL Server会自动增加容量。这里有两种方法进行自动增加。一种是"按兆字节",例如输入"1",一次增加1MB。另一种方法是"按百分比",例如输入10,一次增加当前数据库容量的10%。
  同时还可以设置数据文件的最大容量。在右下角"最大文件大小"中设置。可以设置数据文件的容量无限大,也可以把数据文件限制在某一范围之内。
  接下来切换到"事务日志"页,在这里设置日志文件与前面类似,如图4-4。单击"确定"按钮,就可以将新的数据库添加到数据库服务器中了。 图4-4.gif
  创建数据库时,系统自动复制model数据库的内容,model数据库的所有选项和设置都复制到新数据库中。SQL Server中的每个数据库信息存放在master数据库的sysdatabases表中。
 ② 用"创建数据库向导"创建数据库:
  在"企业管理器"中的"工具"栏中选择"向导",如图4-5,选择"创建数据库向导"。大部分选项与上面用企业管理器创建数据库类似。 图4-5.gif
 ③用T-SQL语句创建数据库:
  用T-SQL语句创建数据库,可以在程序中使用,或在查询分析器中使用。语法格式如下:
   CREATE DATABASE database_name
    [ ON [PRIMARY]
    [ <filespec>[,…n] ][, <filegroup>[,…n] ] ][ LOG ON { <filespec> [,…n] } ]
    [ FOR LOAD ∣ FOR ATTACH ]
   <filespec>:: = (
    [ NAME = logical_file_name,]
    FILENAME = 'os_file_name'
    [,SIZE = size]
    [,MAXSIZE = {max_size|UNLIMITED}]
    [,FILEGROWTH = growth_increment]) [,…n]

   <filegroup>:: =
    FILEGROUP filegroup_name <filespec>[,…n]

  参数说明:
 · database_name
  新建数据库的名称。数据库名称在服务器中必须唯一,并且符合标识符的规则。database_name最多可以包含128个字符。如果没有指定日志文件的逻辑名,则SQL Server会通过向 database_name追加后缀来生成逻辑名。该操作要求database_name在123个字符之内,以便生成的日志文件逻辑名少于128个字符。
 · ON
  显式定义用来存储数据库数据部分的数据文件。该关键字后跟以逗号分隔的 <filespec> 项列表,<filespec> 项用以定义主文件组的数据文件。主文件组的文件列表后可跟以逗号分隔的 <filegroup> 项列表,<filegroup> 项用以定义用户文件组及其文件。
 · LOG ON
  显式定义用来存储数据库日志的磁盘文件(日志文件)。该关键字后跟以逗号分隔的 <filespec> 项列表,<filespec> 项用以定义日志文件。如果没有指定 LOG ON,将自动创建一个日志文件,它使用系统生成的名称,大小为数据库中所有数据文件总大小的25%。
 · FOR LOAD
  支持该子句是为了与早期版本的 SQL Server 兼容。表示将备份数据直接装入新建的数据库。但从SQL Server7.0开始就可以使用RESTORE语句完成相同的功能。
 · FOR ATTACH
  指定从现有的一组操作系统文件中建立数据库。必须有指定第一个主文件的 <filespec> 条目。
 · PRIMARY
  定义数据库的主数据文件。相应<filespec>列表的第一个<filespec>条目成为主数据文件,该文件包含数据库的逻辑起点及其系统表。一个数据库只能有一个主数据文件。如果没有指定PRIMARY,那么CREATE DATABASE语句中列出的第一个文件将成为主数据文件。
 · NAME
  为由<filespec>定义的文件指定逻辑名称。如果指定了FOR ATTACH,则不需要指定 NAME参数。
 · logical_file_name
  用来在创建数据库后执行的 Transact-SQL 语句中引用文件的名称。logical_file_name 在数据库中必须唯一,并且符合标识符的规则。
 · FILENAME
  为 <filespec> 定义的文件指定操作系统文件名。
 · 'os_file_name'
  操作系统创建 <filespec> 定义的物理文件时使用的路径名和文件名。os_file_name 中的路径必须指定 SQL Server 实例上的目录。os_file_name 不能指定压缩文件系统中的目录。
  如果文件在原始分区上创建,则 os_file_name 必须只指定现有原始分区的驱动器字母。每个原始分区上只能创建一个文件。原始分区上的文件不会自动增长;因此,os_file_name 指定原始分区时,不需要指定 MAXSIZE 和 FILEGROWTH 参数。
 · SIZE
  指定<filespec>中定义的文件的大小。如果主文件的<filespec>中没有提供SIZE参数,那么SQL Server将使用model数据库中的主文件大小。如果辅助文件或日志文件的 <filespec>中没有指定SIZE参数,则SQL Server将使文件大小为1MB。
 · size
  <filespec> 中定义的文件的初始大小。可以使用千字节 (KB)、兆字节 (MB)、千兆字节 (GB) 或兆兆字节 (TB) 后缀。默认值为 MB。指定一个整数,不要包含小数位。size 的最小值为 512 KB。如果没有指定 size,则默认值为 1 MB。为主文件指定的大小至少应与 model 数据库的主文件大小相同。
 · MAXSIZE
  指定 <filespec> 中定义的文件可以增长到的最大大小。
 · max_size
  <filespec> 中定义的文件可以增长到的最大大小。可以使用千字节 (KB)、兆字节 (MB)、千兆字节 (GB) 或兆兆字节 (TB) 后缀。默认值为 MB。指定一个整数,不要包含小数位。如果没有指定 max_size,那么文件将增长到磁盘变满为止。

  说明:在磁盘即将变满时,Windows NT 系统日志会警告 SQL Server 系统管理员。
 · UNLIMITED
  指定 <filespec> 中定义的文件将增长到磁盘变满为止。
 · FILEGROWTH
  指定 <filespec> 中定义的文件的增长增量。文件的 FILEGROWTH 设置不能超过 MAXSIZE 设置。
 · growth_increment
  每次需要新的空间时为文件添加的空间大小。指定一个整数,不要包含小数位。0 值表示不增长。该值可以 MB、KB、GB、TB 或百分比 (%) 为单位指定。如果未在数量后面指定 MB、KB 或 %,则默认值为 MB。如果指定 %,则增量大小为发生增长时文件大小的指定百分比。如果没有指定 FILEGROWTH,则默认值为1MB;
例1,在查询分析器中创建数据库示例如图4-6,其中相应的c:\mssql\data目录一定要事先存在。创建数据库的T-SQL语句如下: 
 CREATE DATABASE my_libraryON PRIMARY( --数据主文件
 NAME = my_library_data, --逻辑文件名
 FILENAME ='c:\mssql\data\my_library.mdf', --数据主文件存储路径,操作系统文件名
 SIZE = 10 MB, --10 MB的主要数据库文件
 MAXSIZE = 15 MB, --最大容量15MB
 FILEGROWTH = 20 % ) --当主数据文件满了,自动增大20%的容量
 LOG ON( --日志文件
 NAME = my_library_log, --日志文件逻辑文件名
 FILENAME ='c:\mssql\data\my_library.ldf',
       --日志文件存储路径,操作系统文件名
 SIZE = 3 MB , --3MB的日志文件
 MAXSIZE = 5 MB , --最大容量5MB
 FILEGROWTH = 1 MB ) --当日志文件满了,自动增大1MB。

[ 本帖最后由 cayean 于 2007-1-23 10:58 编辑 ]
图4-6.gif
 楼主| cayean 发表于 2007-1-23 11:09 | 显示全部楼层
4.2.3.删除数据库
 删除数据库可以使用企业管理器或SQL语句删除,一次可以删除多个数据库。
 (1)用企业管理器删除数据库:
展开数据库服务器上的数据库节点,选择要删除的数据库,从快捷菜单中选择"删除"命令,并确认即可。
 (2)使用SQL语句删除数据库:
 删除数据库的语法格式:
 DROP DATABASE database_name[1,….n]
   参数说明:
   ● database_name:要删除的数据库名称,可指定要删除的n个数据库。
说明:
 ● 如果要删除数据库,该数据库必须存在于数据库服务器中。
 ● 无法除去系统数据库(msdb、model、master、tempdb)。
 ● 在删除某数据库之前,确保该数据库的"ReadOnly"选项被置为"False"。
 ● 只有数据库拥有者和sysadmin服务器角色的成员可以执行删除数据库的操作。
 ● 在删除了数据库之后,其中的所有数据库对象和数据都会被删除,所有日志文件和数据文件也会被删除,释放空间给操作系统。
4.2.4.修改数据库:
 1.数据库改名:
  使用系统存储过程sp_renamedb可以修改数据库的名称,语句格式:
   sp_renamedb old_dbname, new_dbname
   例如:sp_renamedb 'zzg', 'zzg1'注意:
 ● 只有属于sysadmin服务器角色的成员可以给数据库更名。
 ● 在给数据库更名前,必须在企业管理器中设置该数据库为单用户状态。在单用户状态下,只能有一个用户使用该数据库,因此,这时不能同时打开企业管理器和查询分析器。

 2.修改数据库选项:
  (1) 可以在企业管理器中修改数据库属性,如图4-8 图4-8.gif
  (2)使用SQL语句来修改数据库的属性,添加数据库数据文件,改变其大小等。语法如下:
   ALTER DATABASE database
   {
   ADD FILE < filespec > [ ,...n ] [ TO FILEGROUP filegroup_name ]
   | ADD LOG FILE < filespec > [ ,...n ]
   | REMOVE FILE logical_file_name
   | ADD FILEGROUP filegroup_name
   | REMOVE FILEGROUP filegroup_name
   | MODIFY FILE < filespec >
   | MODIFY NAME = new_dbname
   | MODIFY FILEGROUP filegroup_name {filegroup_property | NAME =
   new_filegroup_name }
   | SET < optionspec > [ ,...n ] [ WITH < termination > ]
   | COLLATE < collation_name >
   }
  其大部分语法成分与CREATE DATABASE相同。其他参数说明如下:
   ADD FILE…… 表示向指定文件组中添加新的数据文件。
   ADD LOGFILE…… 增加新的日志文件。
   REMOVE FILE…… 表示删除一个操作系统文件。
   ADD FILEGROUP…… 增加一个文件组。
   MODIFY FILE…… 修改某操作系统文件属性。
   MODIFY FILEGROUP…… 修改某文件组的属性。
  文件组的属性有三种:
 ● READONLY:只能读取该文件组中的数据,不能修改。
 ● READWRITE:既可以读取又可以修改该文件组中的数据。
 ● DEFAULT: 设置该文件组为默认文件组。
  注意:
 ● 如果操作系统文件中有任何数据或数据库对象存在,则该操作系统文件无法被删除。
 ● 一次只能修改一个文件属性。如果修改大小,则只能增加文件长度。
 ● PRIMARY文件组属性不能设置为READONLY。   例1,下例更改该数据库以添加一个 5 MB 大小的新数据文件。
  ALTER DATABASE Test1
  ADD FILE (
  NAME = Test1dat2,
  FILENAME = 'c:\Microsoft SQL Server\MSSQL\Data\t1dat2.ndf',
  SIZE = 5MB,
  MAXSIZE = 100MB,
  FILEGROWTH = 5MB)
 例2,使用查询分析器如图4-9 图4-9.gif
 例3,更改数据库并添加一个名为"Company"的文件组,并将一个5MB的新数据库文件添加到该Company文件组中。
  ① ALTER DATABASE zzg1
    ADD FILEGROUP Company1 添加 "Company"的文件组  
  ②ALTER DATABASE zzg1 添加一个数据库文件
    ADD FILE (
    NAME = Test1dat3,
    FILENAME = 'c:\MSSQL\Data\t1dat3.ndf',
    SIZE = 5MB,
    MAXSIZE = 100MB,
    FILEGROWTH = 5MB)
    TO FILEGROUP Company1 新文件放入"Company"的文件组

[ 本帖最后由 cayean 于 2007-1-23 11:12 编辑 ]
 楼主| cayean 发表于 2007-1-23 11:18 | 显示全部楼层
4.3 数据定义
4.3.1表的创建、修改和删除

 1. 创建表:
  在SQL Server中,可以使用SQL语句或SQL企业管理器来创建数据库表。在创建表的时候最主要的工作是定义各列的数据类型及约束。
 (1) 用企业管理器创建表。
  展开企业管理器上的数据库节点,从中选择一个要建立表的数据库,在鼠标右键单击出来的快捷菜单中选择"新建",子菜单,选择"表"命令。如图4-11。 4-11.gif
      弹出窗口如图4-12。 4-12.gif
  在该窗口中,对表的内容进行定义:
  指定列名:在创建一个新列的时候,首先输入列名,列名在表中必须唯一,列的命名遵守SQL Server的数据库对象命名规则。
  指定数据类型:接下来选择该列的数据类型,这里有不同的数据类型,包括你创建的用户定义的数据类型,显示在"数据类型"下拉清单对话框中。其长度取决于你选择的数据类型。当然有些数据类型的长度,如char,可以进行改变。
  指定其他特性:在指定完某一列的数据类型之后,可以为每种数据类型指定附加特性--数据的长度和是否允许空等。如果一列允许空,则在输入数据的时候,可以省略输入该列的值。若定义了一列不允许空,则在输入数据的时候,必须输入该列的值。可以说,允许空实际上提供了一种数据的校验。
  对于INT,SMALLINT,TINYINT,NUMERIC(P,0)等数据类型可以指定为标识列(identity)特性。当用identity特性定义一个列,可以指定该列初始值和每次添加的增量。在往表中增加元组的时候,系统自动为该列赋值,第一行使用初始值,以后每一行增加增量。如果这一列允许为空,则不能指定为identity特性。
  设置主键:选择要建立主键的列,单击鼠标右键,选择"设置主键"即可。
  关闭和保存新建的表时,系统会弹出对话框让你输入该表的名称。
(2) 用SQL语句创建表:
  使用SQL创建表的语法如下:
   CREATE TABLE 表名
   ( <列名><数据类型> [<列级完整性约束条件>]
   [,<列名><数据类型> [<列级完整性约束条件>]]… [,取唯一值的列(列名[,列名]….)]
   [,关键字列(列名[,列名]…)]
   [,外部关键字列 (列名[,列名]…)
   引用的外部表名(列名[,列名]…)]
   [,< 表级完整性约束条件 >] );
   CREATE TABLE 表名
   (
   列名 数据类型[缺省值][NOT NULL]
   [,列名 数据类型[缺省值][NOT NULL]]….
   [,UNIQUE(列名[,列名]….)]
   [,PRIMARY KEY(列名[,列名]…)]
   [,FOREIGN KEY (列名[,列名]…)REFERENCES 表名(列名[,列名]…)]
   [,CKECK (条件)]
   )
  参数说明:缺省值(DEFAULT):指定列的缺省值;
  NOT NULL:列值不能为空值;
  UNIQUE:取值唯一的列名;
  PRIMARY KEY:主关键字(主码)列名;
  FOREIGN KEY:外部码列名;
  REFERENCES:引用的外部码的表名和列名
  CKECK :指定表级约束条件。
 例1,定义一个表DEPT,包括4列。其中deptno为主键。
 CREATE TABLE DEPT( deptno CHAR(8) NOT NULL,
 Deptname CHAR(20) NOT NULL,
 Deptphno CHAR(12),
 Deptadd CHAR(40)
 PRINARY KEY (deptno)
 )

 例2,定义表student,包括5列,其中sno为主键,sclass为外键码,sclass为表classname的主键。Ppt37CREATE TABLE student( sno CHAR(8) NOT NULL,
  Sname CHAR(20) NOT NULL,
  Ssex CHAR(1),
  Sage INT,
  Sclass CHAR(8)
  PRINARY KEY (sno)FOREIGN KEY(sclass)
  REFERENCES class(classname)
  )

 例3,产生表student,与例2基本相同,但需要通过check约束学生年龄大于等于14岁,如下定义。ppt38CREATE TABLE student( sno CHAR(8) NOT NULL,
  Sname CHAR(20) NOT NULL,
  Ssex CHAR(1),
  Sage INT CHECK (sage >= 14),
  Sclass CHAR(8)
  PRINARY KEY (sno)FOREIGN KEY(sclass)
  REFERENCES class(classname)
  )

 例4,产生表couse,设计要求:开课系必须是已有的系,授课教师必须是本校的教师。CREATE TABLE couse
  (cno CHAR(6) NOT NULL,
  cname CHAR(20) NOT NULL,
  credit INT,
  cdept CHAR(8),
  ctno CHAR(8)
  )
 注意:例4产生的表不能满足设计要求,必须对该表进行修改,增加约束外部关键字约束说明,满足设计要求。

[ 本帖最后由 cayean 于 2007-1-23 11:20 编辑 ]
 楼主| cayean 发表于 2007-1-23 11:31 | 显示全部楼层
   2. 修改表
  SQL语言提供对设计好的表进行补充和修改的功能,包括增加,修改和删除某些列等。在SQL Server中,可以使用SQL语句或SQL企业管理器来修改数据库表。
 (1) 使用企业管理器修改表格。
  从树形结构展开要修改定义的表所在数据库,并选中该数据库节点下面的表节点,在企业管理器右侧显示出该数据库下全部表格。选择要修改的表,单击鼠标右键,从弹出的快捷菜单中选择"设计表"命令,其余操作和最初建立表格时一样,如图4-15。 4-15.gif
(2) 使用SQL语句修改表
  使用SQL语句,可以在更大范围修改表格。包括增加、删除、修改列定义或完整性约束条件,其格式:
   ALTER TABLE 表名
   [ADD子句]          增加新的列定义或列说明
   [ALTER COLUMN子句]     修改表中列定义或列说明
   [DROP子句]         删除表中的列或列说明
   [ADD CONSTRAINT子句]    增加约束
   [DROP CONSTRAINT子句]    删除约束

 例1,修改表COUSE。上面的例4产生的表不能满足设计要求,必须对该表进行修改,增加约束外部关键字约束说明,满足设计要求,语句如下: ALTER TABLE COUSE
  ADD FOREIGN KEY (cdept) REFERENCES DEPT [deptno]
  ADD FOREIGN KEY (ctno) REFERENCES TEACHER [tno]  

 例2,修改学生的年龄为出生日期(日期类型)。
  ALTER TABLE STUDENT
  ALTER COLUMN sage DATETIME

 例3:增加学生的电话属性:
  ALTER TABLE STUDENT
  ADD sphno CHAR(12)
 例4,增加学生的国家属性
  ALTER TABLE STUDENT
  ADD country CHAR(30)
 3. 删除表:
  删除表,将基本表的定义、表中的数据、索引,以及由此表导出的视图定义都被删除,而且所有的内容被删除后无法恢复。只有有权限的人员才能删除表。删除操作不能删除正在用于外键码约束引用的表,要删除此类表,必须先删除引用的外键码约束或删除引用的表。
  在SQL Server中,表格的删除既可以用企业管理器完成,也可以用SQL语句完成。只有表的拥有者(db_ownwer)或sysadmin这样的服务器角色成员有权力删除表格,而且不能删除系统表。
 (1) 使用企业管理器删除表格。
  使用企业管理器删除表格很简单,只要展开被删除表所在的数据库,选择该数据库的表节点,选择表格并单击鼠标右键,从弹出的快捷菜单中选?quot;删除"命令即可,可以同时选择多个表格一起删除。
(2) 使用SQL语句删除表格
  语法如下:
   DROP TABLE table_name
 例1:删除表student1
  DROP TABLE student1  
 例2,删除表 DEPT
  DROP TABLE DEPT
  使用查询分析器删除表,注意首先选择数据库zzg1,使用SQL语句use zzg1。或者输入DROP TABLE zzg1.dbo.student1,可在任何数据库中对其删除。
  4.3.2 索引的创建、修改和删除:
  索引是数据库的对象之一,它对数据库的操作效率有着很重要的影响。好的索引可以大大提高对数据库的检索效率,在检索数据时起到了至关重要的作用。
  定义在某关系属性上的索引是一个数据结构,采用编排表中数据的内部特定方法,可显著提高依据该属性值的查询效率。可在表的一个列或多个列上建立索引,列名之间用逗号分开;并可指定索引中索引值的排列顺序,缺省值为升序。
  没有索引时,当一个关系的记录数很大时,为查询符合条件的元组要对整个关系进行顺序扫描。例如,有查询语句如下:
   SELECT * FROM student
   WHERE sname='赵微'
  假定学生关系包含20000个记录,要查找的元组刚好在最后,为查询一个记录,要对20000个记录逐一检查核对。如果为student表的sname属性建立了索引,在查询student表中符合sname的条件时,系统将不再按条件逐条检查记录,而是利用索引来定位符合条件的元组。
  索引的使用是有代价的。因为维护索引是一个复杂的算法,需要一定的时间。当对基表进行插入、删除和修改记录操作时,同时要对索引进行维护。因此,索引的存在会影响基表更新操作的效率,但提高了查询效率,这是用户需要的。
  索引有两种形式,一种是簇集索引(Clustered),另一种是非簇集索引(Nonclustered)。
  簇集索引根据建立索引的属性值对行进行排序,正如簇集索引的字面意思一样,表中的数据会以该属性值作为排序根据,按照排序的结果把数据物理地存放在一起,所以每个表只能有一个簇集索引。
  非簇集索引不根据键值排序,索引数据结构和数据行分开。由于非簇集索引的表没有按顺序进行排序,所以查找速度明显低于查找带簇集索引的表。
  当表中有Primary Key或Unique等约束时,系统会自动建立索引,建立簇索引还是非簇索引就要由Clustered或Nonclustered指定。
 1. 索引的创建:
  在SQL Server中,可以用企业管理器或用SQL语句完成索引的创建。
 (1) 使用企业管理器创建索引:
  在设计表格的时候,选择列的快捷菜单"属性",切换到"属性"页对表格的索引进行添加。如图4-19,在表student1为列sno中添加簇集索引IX_TABLE1。
 (2) 使用SQL语句创建索引
  语法格式如下:
   CREATE [UNIQUE] [CLUSTER|NONCLUSTERED] INDEX index_name
   ON table_name(column_name[ASC/DISC]
   [,column_name[ASC/DISC]]….])
  参数说明:
   UNIQUE:表示创建的索引是唯一索引,每个索引只对应一个元组值。
   CLUSTERED:表示创建的索引是簇集索引。
   NONCLUSTERED:表示创建的索引是非簇集索引。
   Index_name:创建的索引名。
   Table_name:创建索引所在的表名。
   Column_name:创建索引使用的列名。由ntext、text或image数据类型组成的列不能指定为索引列。
   ASC|DESC:确定具体某个索引列的升序或降序排列。默认设置为ASC。   例1,为TEACHER表建立唯一索引tnamex,升序排列。不管教师是否有重名,每个索引值只对应一个教师名字。
  CREATE UNIQUE INDEX tnamex ON TEACHER(tname)

 例2,在SC表上按学号sno建立聚集索引scinx。
  CREATE CLUSTER INDEX scinx ON SC(sno)
 在选课表中建立聚集索引scinx之后,同一个学生的所有选课成绩记录物理地排在一起。所以,查询某个学生的学习成绩或打印某个学生的成绩单速度就比较快。如表4-3。
 1. 索引的创建:
  在SQL Server中,可以用企业管理器或用SQL语句完成索引的创建。
 (1) 使用企业管理器创建索引:
  在设计表格的时候,选择列的快捷菜单"属性",切换到"属性"页对表格的索引进行添加。如图4-19,在表student1为列sno中添加簇集索引IX_TABLE1。 4-19.gif

 (2) 使用SQL语句创建索引
  语法格式如下:
   CREATE [UNIQUE] [CLUSTER|NONCLUSTERED] INDEX index_name
   ON table_name(column_name[ASC/DISC]
   [,column_name[ASC/DISC]]….])
  参数说明:
   UNIQUE:表示创建的索引是唯一索引,每个索引只对应一个元组值。
   CLUSTERED:表示创建的索引是簇集索引。
   NONCLUSTERED:表示创建的索引是非簇集索引。
   Index_name:创建的索引名。
   Table_name:创建索引所在的表名。
   Column_name:创建索引使用的列名。由ntext、text或image数据类型组成的列不能指定为索引列。
   ASC|DESC:确定具体某个索引列的升序或降序排列。默认设置为ASC。   例1,为TEACHER表建立唯一索引tnamex,升序排列。不管教师是否有重名,每个索引值只对应一个教师名字。
  CREATE UNIQUE INDEX tnamex ON TEACHER(tname)

 例2,在SC表上按学号sno建立聚集索引scinx。
  CREATE CLUSTER INDEX scinx ON SC(sno)
 在选课表中建立聚集索引scinx之后,同一个学生的所有选课成绩记录物理地排在一起。所以,查询某个学生的学习成绩或打印某个学生的成绩单速度就比较快。如表4-3。 4-3.gif

例3:为student表建立索引,NONCLUSTERED为隐含值,可以省略。
    CREATE NONCLUSTERED INDEX stu_index ON student(sname)  

 (3) 在两个或更多属性上建立索引:
  假如查询经常涉及到多个列值的检索条件,可在一个关系表上建立多个属性的索引,提高查询效率。否则会降低查询效率。
  例如,选课关系sc,主码(sno, cno),经常查询某学号的同学选修某课程的成绩。为两个属性建立索引的语句如下:
   CREATE INDEX Scidx ON sc(sno, cno);

 (4) 使用索引的原则:
   要不要建索引以及如何建索引,当属于内模式的概念,这是数据库设计中一个很重要的问题。设计人员要仔细考虑实际应用中修改与查询的频率,权衡建索引的利弊。例如,若一关系的经常性操作是数据的修改,则不宜建索引。但有些修改语句可能包含着查询操作。
  一般来说,建索引有几项参考原则:
 ● 值得建索引:记录有一定规模,而查询只局限于少数记录。
 ● 索引用得上:索引列在where子句中应频繁使用。先装数据,后建索引:对于大多数基本表,总是有一批初始数据需要装入。该原则是说,建立关系后,先将这些初始数据装入基表,然后再建索引,这样可加快初始数据的录入。如果建表时就建索引,那么在输入初始数据时,每插入一个记录都要维护一次索引。当然,索引早建晚建都是允许的。
 ● 在下列三种情况下,有必要建立簇索引:
 (1)查询语句中采用该字段作为排序列
  例如,我们经常执行下列语句:
   SELECT * FROM authors ORDER BY au_id
  这时候有必要考虑在该表格上建立以au_id为关键字的簇索引。
   CRATE CLUSTERED INDEX au_index On authors (au_id)

 (2)需要返回局部范围的大量数据
  例如,我们要做如下的查询:
   SELECT * FROM authors
   WHERE zip BETWEEN 94618 AND 96214
  这时就有必要在zip列上建立簇索引。
   CRATE CLUSTERED INDEX zip_index On authors (zip)

 (3)表格中某字段内容的重复性比较大例如,student表中dno(系号)一列有大量重复数据,当在dno列上建立了簇索引后,下面的连接查询速度会加快。
   SELECT * FROM student,dept
   WHERE student.dno=dept.dno
  对以上情况,建立簇索引会提高访问数据库的效率。建立簇索引的语句如下:
   CRATE CLUSTERED INDEX dept_index On student(dep_id)
  注意:当在同一表格中建立簇索引和非簇索引时,先建立簇索引后建非簇索引比较好。因为如先建非簇索引的话,当建立簇索引时,SQL Server会自动将非簇索引删除,然后重新建立非簇索引。每个表仅可以有一个簇索引,最多可以有249个非簇索引。它们均允许以一个或多个字段作为索引关键字(Index Key),但最多只能有16个字段。
  SQL Server只对那些能加快数据查询速度的索引才能被选用。如果利用索引检索还不如顺序扫描速度快,SQL Server仍用扫描方法检索数据。建立不能被采用的索引只会增加系统的负担,降低检索速度。因此,可利用性是建立索引的首要条件。
 2. 修改索引
  用ALTER INDEX可以将一个聚集索引改为一个非聚集索引,或将可以将一个非聚集索引改为一个聚集索引。缺省为非聚集索引。
  修改索引语句格式: ALTER INDEX 索引名 TO [NOT]CLUSTER   例1,把tnamex改为一个聚集索引,该表的元组的物理位置要从新排列,原有的非聚集索引需要全部删除,而后重建。
   ALTER INDEX tnamex TO CLUSTER

 例2,把scinx改为一个非聚集索引
   ALTER INDEX scinx TO NOT CLUSTER
 这里只介绍用SQL语句修改索引,使用企业管理器修改索引与添加索引大致相同,在此不再赘述。

 3.删除索引: 
  删除索引的语句格式:
   DROP INDEX table_name. index_name
  参数说明:
   Table_name:要删除索引所在的表。
   Index_name:要删除索引的名称。
  例如:将teacher表中的索引tnamex删除:
   DROP INDEX teacher.tnamex
  执行 DROP INDEX 后,将重新获得以前由索引占用的空间。此后可将该空间用于任何数据库对象。
 使用索引的一点说明:
 (1) 使用SQL语言,用户可以随时在基本表上建立索引、增加新索引、删除索引。用户根据具体应用环境需要的情况,可动态地调整索引结构,达到较高的查询性能。
 (2) 用户只能建立、修改和删除索引,不能在数据操作中引用索引,在数据操作执行中如何使用索引完全由系统决定。从而保证了增加和删除索引时不必修改应用程序,支持数据的物理独立性。
 (3)不能用DROP INDEX删除在系统表上的索引。
 (4) 若要删除为实现 PRIMARY KEY 或 UNIQUE 约束而创建的索引,必须先除去约束,因为许多DBMS系统自动为PRIMARY KEY和UNIQUE属性列建立索引。
 (5) 只有表的所有者和sysadmin有权删除表的索引。

[ 本帖最后由 cayean 于 2007-1-23 12:15 编辑 ]
 楼主| cayean 发表于 2007-1-23 12:51 | 显示全部楼层
4.4 数据更新
  创建表的目的是为了存储和管理、查询数据,实现数据存储的前提是向表格中添加数据;实现表格的管理经常要修改、删除表格中的数据。SQL提供了数据更新功能,包括INSERT、DELETE、UPDATE分别完成对表的插入、删除和更新操作。
4.4.1插入语句INSERT
  在SQL中,最常用的向表格中添加数据的方法是使用INSERT语句。但是,用INSERT语句每次只能插入一个元组。用带子查询插入语句,一个次可以插入一个或多个元组。
 ● 插入一个元组的语句格式:
   INSERT INTO 表名[(列名[,列名]…)]
   VALUES(值[,值]…..)
  插入单个元组,按顺序在表名后给出表中每个列名,在VALUES后给出对应的每个列值。插入一个完整的新元组时,可省略表的列名。插入部分列值,必须在表名后给出要输入值的列名。   例1,插入单个元组,按顺序给出表中每个列值。
  INSERT INTO DEPT VALUES( "CS","计算机","888", "10区" )

 例2,插入一个学生的部分列值,必须在表名后给出要输入值的列名。
  INSERT INTO STUDENT (sno ,sname)
  VALUES( "J20045", "刘琉")

  在使用INSERT语句的时候,VALUES列表中的值或表达式必须匹配表中的列数,并和相应各列数据类型兼容。如果表格中存在某些列定义为NOT NULL,那么在插入时该列必须要出现在VALUES的列表中,否则插入会失败。

 ● 用子查询插入多个元组值的语句格式:
   INSERT INTO 表名[(列名[,列名]…)]
  子查询
  注意:在使用子查询的结果插入元组时,子查询的结果必须匹配待插入表中的列数,并和相应各列数据类型兼容。如果表格中存在某些列定义为NOT NULL,那么子查询的结果在该列上必须有值,否则插入会失败。   例3,建立一个新表,存放每个学生的学号、姓名和平均成绩。把子查询结果插入新表中。
  CREATE TABLE savg( sno CHAR(8),sname CHAR(20), avage REAL )
  INSERT INTO savg (sno,sname,avage)
  ( SELECT sno,sname,AVG(grade)
  FROM SC,STUDENT
  WHERE SC.sno = STUDENT.sno
  GROUP BY sno )

 例4,在表Studio中插入属性name,这些name是在表Movie中提到,但没有在表Studio中出现的studioName。
  INSERT INTO Studio(name)
  SELECT DISTINCT studioName
  FROM Movie
  WHERE studioName NOT IN
  (SELECT name FROM Studio);  
4.4.2更新语句UPDATE
  从某种意义上来说,更新语句UPDATE比插入语句INSERT,删除语句DELETE更接近于"修改"的具体意义。当需要修改数据库表中某一列的数据的时候,使用UPDATE语句可以指定要修改的列和想要赋予的新值。通过给出查询匹配数据行的WHERE子句,还可以指定要更新的列必须符合的条件。
  单个更新操作可修改指定表中满足条件的一行或多行元组中的一个或多个列值。
  语句格式: UPDATE 表名
   SET 列名={表达式|(子查询)} [, 列名={表达式|(子查询)}]….
   [WHERE 条件表达式]
  WHERE子句中的条件表达式给出被修改元组应满足的条件;
  SET子句指定要修改的列和修改后的值。
 例1,把 DEPT 中的计算机系的电话号码改为"9888"。
  UPDATE DEPT SET deptphno = "9888" WHERE deptno = 'cs'  

 例2,有课程的学分都加1
  UPDATE COUSE
  SET credit = credit+1

 例3,数据库课程的成绩提高10%。
  UPDATE SC
  SET grade = grade*110%
  WHERE cno = "g008"

 例4,将JS2001斑学生的成绩提高10%。
  UPDATE SC
  SET grade = grade*110%
  WHERE "JS2001"=
  SELECT sclass
  FROM STUDENT
  WHERE STUDENT.sno=SC.sno)
4.4.3删除语句DELETE
  DELETE 语句从表中删除一个或多个满足条件的元组。语句格式:
  DELETE FROM 表名 [WHERE 条件表达式]
  WHERE子句中的条件表达式给出被删除元组应满足的条件;若不写WHERE子句,表示删除表中的所有元组,但表的定义仍存在。
 例1,只涉及单个元组,从数据库中删除某个学生李楷:
   DELETE FROM STUDENT
   WHERE sname = "李楷"

 例2,删除操作涉及多个元组,从数据库中删除某门课程的所有元组:
   DELETE FROM SC
   WHERE cno = "E001"
   
  4.5 数据查询语句SELECT
  SQL语言的核心是表达查询的SELECT 语句。 SELECT语句的基本结构是由SELECT -FROM-WHERE组成的查询块,实现对数据的查询操作。
4.5.1 简单查询
  简单查询是指实现对单表的选择或投影操作,查询满足条件的全部列或部分列。语句格式:
   SELECT <目标列名字表>
   FROM <关系表名>
   WHERE <查询条件表达式>
  参数说明:
  SELECT子句中的目标列名字表:指出查询结果中的列名;
  FROM子句中的关系表:指定查询有关的表名;
  WHERE子句中的条件表达式:给出选择元组应满足的条件。
1. 单表查询操作
  (1) 查询指定的列和全部的列
 例1,查询指定的列,列出所有学生的名字和学号:
  SELECT sname, sno FROM STUDENT  
 例2,查询全部的列,列出计算机系所有学生的信息:
  SELECT *
  FROM STUDENT
  WHERE sclass = "JS%"

 2. SELECT语句的基本格式:
   SELECT [UNIQUE/DISTINCT]<目标列名字> 
  FROM 表名[,表名]….
  [ WHERE 条件表达式] [ GROUP BY 分组的列名 ]
  [ HAVING 对组再选择的条件表达式] [ORDER BY 排序列名[ASC/DESC]]
  参数说明:
  GROUP BY子句:指出用于把查询结果分组的列名,该列属性值相同的元组被划分为一组。
  HAVING子句:与GROUP BY子句配合使用, HAVING子句给出对分组进行再选择的条件表达式。
  ORDER BY字句:指定对查询结果进行排序(升序/降序)的列名。该列必须出现在结果集中。ASC为升序,DESC为降序,缺省为升序。
  UNIQUE/DISTINCT:指名查询结果中去掉重复行。
(2) 没有重复值的查询
例如:从表COUSE中查询当前任课教师的编号(名单),去掉重复值。
  select distinct ctno from couse

输出结果:
ctno
T001
T020
T012
(3) 查询结果排序
例如:从表COUSE中查询当前认课教师的编号(名单),去掉重复值,结果排序。
select distinct ctno from couse order by ctno

输出结果:
ctno
T001
T012
T020
(4) 指定别名查询
例如:假如希望得到查询的结果具有与原来的属性不同的列标题名,可在SELECT语句中指定别名来实现。
select distinct ctno 教师编号 from couse order by ctno

输出结果:
ctno
T001
T020
T012
 3. 查询中使用表达式运算符
  (1) SQL中使用的表达式运算符包括:
 ◆ 算术运算符:+,-,*,/
 ◆ 比较运算符:=,<>,>=,>,<,<=
 ◆ 逻辑运算符:NOT,AND,OR
 ◆ 测试空值:IS NULL,IS NOT NULL
 ◆ 集合运算符:IN,NOT IN,ANY,ALL
 ◆ 模糊查询: LIKE(_ 或 %), NOT LIKE
 ◆ 判断列值是否在指定的区间内:
  BETWEEN … AND …
  NOT BETWEEN … AND …
  (2) 算术运算符和比较运算符的例子
 例1:搜索pubs数据库中的title表,返回书的价格打了8折后仍然大于12美元的书名、书的类型和价格。
  USE pubs
  Go
  SELECT title_id , type , price
  FROM titles
  WHERE price * 0.8 >12
  Go

  (3) 使用集合运算符的例子灵活的使用IN,NOT IN,ANY,ALL这些关键字,可以用简洁的语言实现较为复杂的查询,同时整个程序的可读性也会变得更好。
 例2:
  Use pubs
  Go
  SELECT au_id, au_lname, au_fname
  FROM authors
  WHERE state IN ('CA','KS','MI','IN')
  Go

 例3,查询籍贯是北京、天津和上海来的学生:
  SELECT *FROM student
  WHERE 籍贯 IN ('北京','天津','上海')ORDER BY 籍贯

 例4,查询年龄大于35岁的学生:
  SELECT *FROM student
  WHERE 年龄 >= 35

  (4) 测试空值的查询的例子使用IS操作符测试空值的例子,例如,从STUDENT表中查找学生电话是空值的学生名字和班级号码: SELECT sname, sclass
    FROM STUDENT
    WHERE sphno IS NULL;
  输出结果如下:
   sname sclass
   王 者 JS2001
   赵 良 DZ2001
  (5) 使用逻辑运算符的例子查询所有在美国加利福尼亚州的出版社
   Use pubs
   Go
   SELECT pub_id, pub_name, city, state, country
   FROM publishers
   WHERE country='USA' and state='CA'
   Go
  (6) 进行模糊查询的例子
  在实际的应用中,如果无法给出精确的例子,只能根据较为模糊的情况来查询数据,比如:只知道数据中含有某几个特定的字符,在这种情况下,SQL提供了LIKE子句和通配符进行模糊查询。
  通配符的使用:
 %:表示从0到n个任意字符。
 _:表示单个的任意字符。
 [ ]:表示方括号里面列出的任意一个字符。
 [^]:表示任意一个没有在方括号里面列出的字符

例1,查询所有以D开头的作家的名字
use pubs
go select au_lname+','+au_fname from authors
where au_fname like'D%'
go

+','+   --------表示在lname和fname之间加一个逗号。

输出结果:
Straight, Dean
Stringer,Dirk


  例2,查询电话号码本中含有5737的电话号码:
   SELECT *FROM calltable
   WHERE callno LIKE '%5735%' ;

  例3,查询电话号码本中最后一位数是8的电话号码:
   SELECT *FROM calltable
   WHERE callno LIKE '%8' ;  

  例4,查询所有满足au_id的前两个字母为'72',第四个字母为'-'的作家的姓名和电话号码:
   Use pubs
   Go
   SELECT au_lname ,au_fname, phone, au_id
   FROM authors
   WHERE au_id LIKE'72_-%'
   Go
  如果在LIKE表达式中包含字符%或_,可以采用加上换码字符的方法解决。

  例5,下面的例子将匹配所有以'%'开始并以'%'结束的任意字符串:
  s LIKE 'x%%x%' ESCAPE 'x'ESCAPE 'x' 声明:x作为'x%%x%'的换码字符,x%指的是单独的字符%,x只起标记作用,不再表示字符。

  例6,在SQL中用两个连续的单引号"'"表示一个单独的单引号,下面的例子表示电影名中含有's的电影。
  Title LIKE '%''s%'(7) 指定范围查询的例子例1,查询年龄在20至30之间的学生:
   SELECT *FROM student
   WHERE 年龄 BETWEEN 20 AND 30 ;

  例2,查询年龄不在20至30之间的学生:
   SELECT *FROM student
   WHERE 年龄 NOT BETWEEN 20 AND 30 ;
 4. SQL中表达式使用的聚合函数
 (1) SQL允许对列值进行统计,也可以按给定的条件对关系元组进行分组,再对每个组进行统计操作。
 ◆ COUNT([DISTINCT∣ALL ]<列名>):统计某个列中值的个数(计数)
 ◆ COUNT(([DISTINCT∣ALL]*):统计满足条件的元组个数。
 ◆ SUM([DISTINCT∣ALL]<列名>):对某个列的值求和
 ◆ MIN ([DISTINCT∣ALL]<列名>):求某个列的最小值
 ◆ MAX ([DISTINCT∣ALL]<列名>):求某个列的最大值
 ◆ AVG ([DISTINCT∣ALL]<列名>):求某个列的平均值
  其中:
  DISTINCT:表示计算时要取消指定列中的重复值。
  ALL: 指所有的值。缺省为ALL
.
 (2) 使用聚合函数查询,统计某个列中值的个数
  例如1,查询学生的总人数,
   SELECT COUNT(*)
   FROM student;
  例如2,查询选修了课程的学生总人数,
   SELECT COUNT(DISTINCT sno)
   FROM sc;
例2:求每个班级男生的人数,必须按班号分组,而后按班统计学生人数
select 班号 count(*) from student where 性别='男'group by 班号

输出结果:
班号,  count(*)
js9901  21
js9902  22
js9903  23

只有出现在GROUP By子句中的属性才能与聚合操作并列出现在SELECT子句中。
(3) 使用聚合函数查询,求列的最大最小值
 例1 :列出所有学生的最小和最大年龄
select min(sage),max(sage)from student

输出结果:
min(sage) 20  max(sage) 25

(4) 使用聚合函数查询,查询结果分组
 例2:统计各科成绩的最低、最高分和平均成绩 。
select cno,min(grade),max(grade),avg(grade) from sc group by cno

输出结果:
cno min(grade) max(grade) avg(grade)
G006  60          92                  75
G007  65          90                  78
G006  60          94                  72
 (5) 聚合查询示例,对列的值进行求和
  例如,查询学分不到20分的学生的学号和学分总数。
   SELECT 学号,SUM(credit)
   FROM SC,COURSE
   WHERE grade >= 60 AND grade NOT NULL
   AND SC.cno = COURSE.cno
   GROUP BY 学号
   HAVING SUM(credit) < 20
 楼主| cayean 发表于 2007-1-23 13:28 | 显示全部楼层
4.5.2多表连接查询操作
  当一条查询涉及到多个表时,称为连接查询。连接查询在FROM子句中要写上所有有关的表名,在SELECT和WHERE子句中可引用任意有关表的属性名。当不同的表有相同的列名时,为了区分,可以在列名的前面加注表名(表名.属性名)。
1. 相等连接和非相等连接
  连接查询是从两个表中查询两个表的对应列值相等或不相等(进行大于、小于比较)的元组,进行并(UNION)操作后生成一张新表。连接运算的一般格式如下:
  [<表1>.]<列名i> <比较运算符> [<表2>.]<列名j>
  当比较运算符为相等时,称为等值连接。其他为非等值连接。连接条件中的进行连接运算的两个列必须是同类型的,必须是可比较的数据类型。
  连接操作实际是先在两个关系之间实现广义笛卡儿积,再根据条件选择满足条件的元组组成新关系。
  在图4-21中,有关系表A和B,如图4-21a)和b),二者相等连接的条件是A.Y = B.U,相等连接产生的结果如图4-21c)。

列出所有任课教师的名字,去掉重复值:
select distinct tname 任课教师 from couse,teacher where couse.tno=teacher.tno

输出结果:
任课教师
王学
李力
张三

2.自然连接  
  在等值连接中,如果把目标列中重复的属性去掉,称为自然连接。

 例:查询js2001班的学生和其选修课程情况:
select student.sno,sname,ssex,sage,sclass,cno,grade
from sc,student where student.sno=sc.sno and sclass="js2001"

输出结果:
j20001  李大  M  19  JS2001  G001  78
j20002  张三  F  20  JS2001  G002  85
j20003  王五  M  20  JS2001  G003  86

本查询中,Sno属性在两个表中都有,查询结果只取一个,但是在WHERE子句中,为了区分二者,在Sno前面要加上表名前缀。
3. 多元连接
 (1) 对两个以上的表进行连接查询。
  例如,有学生表student,学生选课表sc,课程表course。查询数据结构课不及格的学生的学号、名字和成绩。SQL语句如下:
   SELECT student.sno,student.sname,grade FROM student, sc, course
   WHERE cname = 'DATA STRUCTURE' AND grade < 60
   AND course.cno = sc.cno
   AND sc.sno = student.sno;
  由于该查询的目标列分布在两个关系表中,学生的学号和名字在学生表student中,成绩在学生选课表sc中,课程名称在课程表course中,因此要用到三个表连接查询。
 (2) 使用别名查询
  SQL语言中,允许对关系表使用别名,简化表名的书写。例如,前面的例子中,可以使用student的别名为 s,course的别名为 c,改写其如下:
   SELECT s.sno, s.sname,sc.grade FROM student s, sc, course c
   WHERE sc.cname = 'DATA STRUCTURE' AND sc.grade < 60
   AND c.cno = sc.cno
   AND sc.sno = s.sno;使用JOIN和ON的连接查询
  使用JOIN连接不同的表,使用ON给出两个表之间的连接条件。这是ANSI92标准进行多表查询的书写方式。
 例1,前面的例子可以改写如下:
  SELECT s.sno, s.sname, sc.grade FROM student s JOIN sc ON sc.sno = s.sno
  JOIN course c ON c.cno = sc.cno
  WHERE sc.cname = 'DATA STRUCTURE' AND sc.grade < 60

 例2:选择出大于平均销售数量的书的名字和价格:
  SELECT titles.title, titles.price
  FROM titles JOIN sales ON sales_id = titles_id
  WHERE sales.qty > (SELECT AVG(qty) FROM sales)  

 4. 自身连接(同一个表内)
 自身连接是指使用同一个表的相同列进行比较连接。这时,对于同一个表应给出不同的别名。例如,查询每门课程的先修课程的先修课。可以在课程表中增加直接先修课属性,但是没有先修课程的先修课属性。查询必须先找到直接先修课程,再在同一个课程表中查找先修课程的先修课。构成对COURSE表的自身连接查询。
 

 例1,自身连接示例:有课程表如图4-22:为课程表取两个别名:Acourse和Bcourse. 
 自身连接查询SELECT Acourse.cno 课程号, Bcourse.cpno 先修课程的先修课
  FROM course Acourse , course Bcourse
  WHERE Acourse.cpno = Bcourse.cno输出结果如下:
 课程号, 先修课程的先修课程号
  1       3
  4
  5  

 例2,选择具有相同价格的书
  SELECT DISTINCT t1.price, t1.title
  FROM titles t1 JOIN titles t2
  ON t1.price = t2.price
  AND t1.title_id <> t2.title_id

 5. 外连接
  (连接表中有空值的情况)在前面连接中,返回到查询结果集中的仅是符合查询条件(WHERE搜索条件或HAVING条件)和连接条件的行。而采用外连接时,它返回到查询结果集中的不仅包含符合连接条件的行,而且还包括在左表(左外连接)、右表(右外连接)或两个连接表(全外连接)中的所有为空值的数据行。外连接分为左外连接,右外连接和全外连接。可以使用left outer join 、 right outer join 和full outer join分别表示左外连接、右外连接和全外连接。
 例1,查询每个学生的选课情况:学号、姓名、班级、课程号和成绩;假如某个学生没有选课,只输出学生的基本情况:学号、姓名、班级。
  SELECT s.sno, sname, sclass, cno, grade
  FROM student s , sc
  WHERE s.sno = sc.sno(*)
 其中,在连接谓词的某边加符号* (SQL Server中使用 + 号)。在加*号的一边为空值的也作为查询结果输出。学生王者没有选课,查询结果如下:
  s.sno sname sclass cno grade
  J20001 李楷 Js2001 G001 78
  J20002 张会 Js2001 G002 85
  J20003 王者 JS2001

 例2 左外连接示例。假设在 city 列上连接 authors 表和 publishers 表。结果只显示在出版商所在城市居住的作者;
 若要在结果中包括所有的作者,而不管出版商是否住在同一个城市,使用左外连接。
  USE pubs
  SELECT a.au_fname, a.au_lname, p.pub_name
  FROM authors a LEFT OUTER JOIN publishers p
  ON a.city = p.city
  ORDER BY p.pub_name ASC, a.au_lname ASC, a.au_fname ASC
    不管是否与 publishers 表中的 city 列匹配,LEFT OUTER JOIN 均会在结果中包含 authors 表的所有行。注意:结果中所列的大多数作者都没有相匹配的数据,因此,这些行的 pub_name 列包含空值。

 例3,右外连接示例。若要在结果中包括所有的出版商,而不管城市中是否还有作者居住,使用右外连接。下面是右外连接的查询语句:
  USE pubs
  SELECT a.au_fname, a.au_lname, p.pub_name
  FROM authors AS a RIGHT OUTER JOIN publishers AS p
  ON a.city = p.city
  ORDER BY p.pub_name ASC, a.au_lname ASC, a.au_fname ASC

[ 本帖最后由 cayean 于 2007-1-23 13:30 编辑 ]
您需要登录后才可以回帖 登录 | 成为会员

本版积分规则

QQ|手机版|小黑屋|网站帮助|职业IT人-IT人生活圈 ( 粤ICP备12053935号-1 )|网站地图
本站文章版权归原发布者及原出处所有。内容为作者个人观点,并不代表本站赞同其观点和对其真实性负责,本站只提供参考并不构成任何投资及应用建议。本站是信息平台,网站上部分文章为转载,并不用于任何商业目的,我们已经尽可能的对作者和来源进行了通告,但是能力有限或疏忽造成漏登,请及时联系我们,我们将根据著作权人的要求立即更正或者删除有关内容。

GMT+8, 2024-5-15 20:20 , Processed in 0.165741 second(s), 23 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表