网站导航网学 原创论文 原创专题 网站设计 最新系统 原创论文 论文降重 发表论文 论文发表 UI设计定制 论文答辩PPT格式排版 期刊发表 论文专题
返回网学首页
网学原创论文
最新论文 推荐专题 热门论文 论文专题
当前位置: 网学 > 交易代码 > SQL语法 > 正文

大学SQLServer2000复习资料(辛苦整理)

论文降重修改服务、格式排版等 获取论文 论文降重及排版 论文发表 相关服务

【网学网提醒】:网学会员,鉴于大家对大学SQLServer2000复习资料(辛苦整理)十分关注,会员在此为大家搜集整理了“大学SQLServer2000复习资料(辛苦整理)”一文,供大家参考学习!


    第一章
    一、SQLServer2000版本:
    1.企业版(具备所有功能)
    ---作为生产数据库服务器使用。支持SQLServer2000中的所有可用功能。
    2.个人版(安装个人数据库)
    ---一般供移动的用户使用。
    3.开发版(适用于我们安装,支持企业版的所有功能)
    ---供程序员用来开发将SQLServer2000用作数据存储的应用程序。
    4.标准版(适用于简洁开发)。
    ---作为小工作组或部门的数据库服务器使用。
    注意:企业版和标准版只能安装在服务器版本的操作系统中,如(2000Server、NT4.0Server等)。
    二、SQLServer2000安装组件
    1.安装数据库服务器(我们选择该组件)
    ---启动SQLSERVER安装程序。
    2.安装AnalysisServices
    ---在处理OLAP(联机分析处理)多维数据集的计算机上安装AnalysisServices。
    3.安装EnglishQuery
    ---可通过英语查询数据库。
    三、目录路径:
    1.\ProgramFiles\MicrosoftSQLServer\MSSQL\Binn
    ---置放程序文件。包含程序文件及通常不会更改的文件,需要的空间不大。
    2.\ProgramFiles\MicrosoftSQLServer\MSSQL\Data
    ---置放数据文件。包含数据库和日志文件、系统日志、备份数据、复制数据所在的目录文件夹,需要的空间大。
    3.\ProgramFiles\MicrosoftSQLServer\80
    ---置放一些共享工具和com组件。比如联机丛书、开发工具等组件。
    四、自带的系统和示例数据库
    1.系统数据库
    a.master数据库
    ---记录SQLServer系统的所有系统级别信息。它记录所有的登录帐户和系统配置设置。b.model数据库
    ---用作在系统上创建的所有数据库的模板。充当所有数据库的原始模板
    c.tempdb数据库
    ---保存所有的临时表和临时存储过程。在SQLServer每次启动时都会重新创建该数据库,也就说该数据库在每次启动服务器时是没有任何数据的,是干净的。
    d.msdb数据库
    ---供SQLServer代理程序调度警报和作业以及记录操作员时使用。
    2.示例数据库
    a.pubs数据库
    ---以一个图书出版公司为模型。可以演示SQLServer数据库中的许多操作。
    b.NorthwindTraders数据库
    ---包含一个名为NorthwindTraders的虚构公司的销售数据,该公司从事世界各地的特产食品进出口贸易。
    五、各种主要SQLServer工具1.查询分析器---创建查询和其它SQL脚本,并针对SQLServer数据库执行它们等功能。2.企业管理器---管理和配置SQLServer,复制、导入、导出和转换数据等所有功能。3.服务管理器---启动、关闭服务器。4.事件探查器---查找并诊断有问题、运行慢的查询,监视SQLServer的性能以精细地调整工作负荷。5.导入和导出数据6.联机丛书六、SQLServer2000的特性
    1.Internet集成
    ---SQLServer2000程序设计模型与WindowsDNA构架集成,用以开发Web应用程序。
    2.可伸缩性和可用性
    ---同一个数据库引擎可以在不同的平台上使用
    3.企业级数据库功能
    4.易于安装、部署和使用
    5.数据仓库
    ---析取和分析汇总数据以进行联机分析处理(OLAP)
    *********************************************************
    第二章
    结构化查询语言(SQL---StructuredQueryLanguage):
    通过SQL我们可以与数据库交互(访问、修改、删除数据等操作),MSSQLServer2000在SQL-92基础上加入了一些特有的性质,称之为Transact-SQL(T-SQL)。
    (SQL是由国际标准化组织(ISO)和美国国家标准学会(ANSI)发布的标准的主题)
    一、T-SQL数据类型:
    1.字符串
    a.char---固定长度的非Unicode字符数据,最大长度为8,000个字符
    b.varchar---可变长度的非Unicode数据,最长为8,000个字符。
    c.text---可变长度的非Unicode数据,最大长度为2^31-1(2,147,483,647)个字符。
    2.Unicode字符串
    a.nchar---固定长度的Unicode字符数据,最大长度为4,000个字符
    b.nvarchar
    c.ntext
    3.整数
    a.bigint---从-2^63(-9223372036854775808)到2^63-1(9223372036854775807)的整型数据(所有数字)。
    b.int---从-2^31(-2,147,483,648)到2^31-1(2,147,483,647)的整型数据(所有数字)。
    c.smallint---从-2^15(-32,768)到2^15-1(32,767)的整数数据。
    d.tinyint---从0到255的整数数据。
    e.bit---1或0的整数数据
    f.decimal和numeric---从-10^38+1到10^38–1的固定精度和小数位的数字数据。
    g.money---货币数据值介于-2^63(-922,337,203,685,477.5808)与2^63-1
    (+922,337,203,685,477.5807)之间,精确到货币单位的千分之十。
    h.smallmoney---货币数据值介于-214,748.3648与+214,748.3647之间,精确到货币单位的千分之十。
    4.浮点精度数字
    a.float---从-1.79E+308到1.79E+308的浮点精度数字。
    b.real---从-3.40E+38到3.40E+38的浮点精度数字。
    5.日期
    a.datetime---从1753年1月1日到9999年12月31日的日期和时间数据,精确到百分之三秒(或3.33毫秒)。
    b.smalldatetime---从1900年1月1日到2079年6月6日的日期和时间数据,精确到分钟。
    6.二进制字符串
    a.binary---固定长度的二进制数据,其最大长度为8,000个字节。
    b.varbinary---可变长度的二进制数据,其最大长度为8,000个字节。
    c.image---可变长度的二进制数据,其最大长度为2^31-1(2,147,483,647)个字节。
    7.其它
    a.timestamp---数据库范围的唯一数字,每次更新行时也进行更新。
    b.sql_variant---种存储SQLServer支持的各种数据类型(text、ntext、timestamp和
    sql_variant除外)值的数据类型。
    c.cursor---游标的引用。
    二、SQL语句:
    1.DML
    ---SQL语句的子集,用于检索和操作数据。
    2.DCL
    ---用于控制对数据库对象的权限的SQL语句的子集。使用GRANT和REVOKE语句来控制权限
    3.DDL
    ---一种语言,通常是数据库管理系统的一部分,用于定义数据库的所有特性和属性,尤其是行布局、列定义、键列(有时是选键方法)、文件位置和存储策略。
    DQL
    三、DML:
    1.Select子句
    用于将数据返回给应用程序或另一个Transact-SQL语句、或者用以填充游标的
    Transact-SQL语句。SELECT语句返回一个表格格式的结果集,它通常由从一个或多个表中析取的数据组成。
    语法:
    SELECT[ALL|DISTINCT]select_column_list
    [INTO[new_table_name]]
    [FROM{table_name|view_name}[(optimizer_hints)][[,{table_name2|view_name2}[(optimizer_hints)][WHEREclause][GROUPBYclause][HAVINGclause][ORDERBYclause][COMPUTEclause][FORBROWSE]简单语法:
    SELECTselect_column_list
    [FROM{table_name}]
    (所有例子及练习均使用pubs数据库)例1:检索Shippers表中的所有书籍信息:SELECT*FROMShippers“*”代表所有的表字段,即所有列。例2:检索所有作者的姓:(authorstable)SELECTau_lnameFROMauthors可以在SELECT之后接我们所要查找的所有作者的姓字段。例3:检索所有作者的姓和名:(authorstable)SELECTau_lname,au_fnameFROMauthors可以得知,在SELECT之后我们可以接一个到多个表字段(列)。练习:
    1.打印所有员工的职位ID。(employeetable)
    2.打印所有出版图书的种类、标题、发行日期。(titlestable)
    例4:
    分析:
    通过上面的学习,我们得知,显示的结果表格的列名都是默认的取查询表的对应列名。但我们发现,为了简洁方便,我们一般将部分表列名缩写,比如作者姓---au_lname,可是对客户来说就不怎么友好了,客户可能希望以上格式的结果,因此,SQL提供了一种“用户自定义标题”的功能,从而实现客户友好化。
    解答1:
    SELECTau_lname'作者姓',au_fname'作者名'FROMauthors
    解答2:
    SELECT'作者姓'=au_lname,'作者名'=au_fnameFROMauthors
    解答3:
    SELECTau_lnameas'作者姓',au_fnameas'作者名'FROMauthors
    例5:需求1:检索所有员工详细信息。需求2:检索所有名为’Helen’的员工详细信息(如员工ID、职位ID、受雇日期等)。解答1:通过以上所学,我们可以很快得出解决方案:SELECT*FROMemployee解答2:这是一个带条件的需求了,客户只想看到名为’Helen’的员工信息,也就是说其余的员工信息不是他所关心的,光靠以上所学我们是满足不了客户的需求的,SQL提供了带条件查询的解决方案:SELECTlnamefromemployeeWHEREfname=‘Helen’WHERE子句语法:
    SELECTselect_column_list
    [FROM{table_name}]
    [WHERE]
    该子句用于返回满足搜索条件的特定行。
    例6:
    检索员工ID为’F-C16315M’的员工的职位ID以及雇用日期。
    解答:
    SELECTjob_id,hire_dateFROMemployee
    WHEREemp_id=‘F-C16315M’
    练习:
    1.
    2.打印订单ID为’10253’的订单中订购的所有产品ID及每种产品数量。*********************************************************第三章一、算术运算符:可以在数据类型为数字的列或者数字常量上进行加、减、乘、除、求模。1.+(加)两个数相加。这个加法算术运算符也可以将一个以天为单位的数字加到日期中。例1:需求:计算客户可订购的总单元数解答:useNorthwindSELECTProductName,UnitsInStock+UnitsOnOrderFROMProducts例2:
    需求:打印订单号为’10248’的订单签订日期后10天的具体日期
    解答:
    useNorthwind
    SELECTorderdateas‘10天之前日期’,
    orderdate+10as’10天之后日期’
    FROMorders
    WHEREOrderID=‘10248’
    2.-(减)
    两个数相减。该减法算术运算符也可以从日期中减去一个以天数为单位数值。
    3.*(乘)
    例1:
    需求:检索现代食谱图书的标识号和价格,并将价格乘以1.15。
    解答:
    USEpubs
    SELECTtitle_id,price*1.15ASNewPrice
    FROMtitles
    WHEREtype='mod_cook'
    4./(除)
    例:
    需求:打印编写商务图书的作者应得的版税
    解答:
    USEpubs
    SELECT((ytd_sales*price)*royalty)/100AS'RoyaltyAmount'
    FROMtitles
    WHEREtype='business'
    5.%(求模)
    模是两个整数相除后剩余的整数。
    例:SELECT20%6结果为2
    SELECT20%2结果为0
    运算符优先级:
    优先级分别为先乘(*),除(/),求模(%),后为减(-)和加(+)
    二、赋值运算符:
    ‘=’
    例:
    USENorthwind
    GO
    SELECTFirstColumnHeading='xyz',
    SecondColumnHeading=ProductID
    FROMProducts
    GO
    请大家预测一下结果?
    三、比较运算符:
    测试两个表达式是否相同。
    一般用于WHERE子句中。
    =,>,<,<>,>=,<=
    例:
    需求:检索折扣大于10的所有折扣类型。
    解答:
    SELECTdiscounttype
    FROMdiscounts
    WHEREdiscount>10
    四、逻辑运算符:
    多个查找条件可以通过用以下的逻辑运算符的结合来做:
    OR当任何一个指定查找条件是真时返回结果
    trueorture返回true
    trueorfalse返回true
    falseorfalse返回false
    两个条件之一成立。
    例1:
    需求:检索类型为商业书籍或心理学书籍的书名
    解答:
    SELECTtitle,type
    FROMtitles
    WHEREtype='business'ORtype='psychology'
    例2:
    需求:检索标题ID为’BU2075’或价格大于20的书名。
    解答:
    SELECTtitle
    FROMtitles
    WHEREtitle_id=‘BU2075’ORprice>20
    AND当所有指定的查找条件是真时返回结果
    trueorture返回true
    trueorfalse返回false
    falseorfalse返回false
    两个条件必须同时成立。
    例:
    需求:检索标题ID为’BU2075’且价格大于20的书名。
    解答:
    SELECTtitle
    FROMtitles
    WHEREtitle_id=‘BU2075’ANDprice>20
    请大家预测一下结果。
    NOT否定其后的表达式
    反转搜索条件的结果
    例:
    需求:检索除德国出版商以外的其余出版商的名称。
    解答:
    SELECTpub_name,country
    FROMpublishers
    WHERENOT(country=‘Germany’)
    五、范围运算符:
    1.between,notbetween
    语法:test_expression[NOT]BETWEENbegin_expressionANDend_expression
    例1:
    需求:检索年度至今单位销售额为4095到12000之间的书标题ID。
    解答:SELECTtitle_id,ytd_salesFROMtitlesWHEREytd_salesBETWEEN4095AND12000请大家思考以下语句执行结果:SELECTtitle_id,ytd_salesFROMtitlesWHEREytd_sales>4095ANDytd_sales<12000分析以下语句执行结果:
    SELECTtitle_id,ytd_sales
    FROMtitles
    WHEREytd_salesNOTBETWEEN4095AND12000
    六、列表运算符:确定给定的值是否与子查询或列表中的值相匹配。如果匹配则显示匹配的结果集。例:需求:列出所有居住在加利福尼亚、印地安纳或马里兰州的作者。解答1:SELECTau_lname,stateFROMauthorsWHEREstateIN('CA','IN','MD')解答2:大家思考!NOTIN正好相反。
    七、串联运算符:
    可以通过’+’运算符将字符串串联起来。
    例:
    需求:打印完整的作者,并按特定格式显示(姓名),比如姓为joe,名为zhou,则应显示命名格式为’joezhou’。
    解答:
    SELECT(au_lname+‘’+au_fname)‘name’
    FROMauthors
    上机练习:1.打印为’SmithAnn’的员工信息。(pubs--employee)2.查找姓为Carson、Carsen、Karson或Karsen的作者所在的行。(使用通配符)3.查找所有员工的ID(pubs--employee)4.打印食品种类的ID、名称、描述。(northwind--Categories)5.打印所有居住在西雅图的客户的电话号码。(northwind--customers)6.打印所有装运所在城市为France,且运费大于30的订单详细资料。(northwind--orders)7.打印产品ID为1到10之间的所有产品名称。(northwind--products)8.打印产品供应商ID为2或者产品种类ID为2的产品名称。(northwind--products)9.检索订单日期为1996年7月19日的所有订单。(northwind--orders)10.打印产品单价为12.75、16.75、20的所有产品名称。(northwind--products)11.
    |州|城市(pubs--publishers)
    *********************************************************
    第四章
    一、通配符:
    通过关键字LIKE来查找带通配符机制的字符串。
    LIKE关键字用来选择那些与字符串的指定部分匹配的行
    例1:查找出版商名称以字符串’books’结束的所有出版商信息。解答:selectpub_namefrompublisherswherepub_namelike'%books'思考:如果改成’%books%’,会返回什么结果?思考:查找出版商名称以字符串’books’开始的所有出版商信息。例2:查找出版商名称第二个字符为’i’的所有出版商信息。
    解答:
    selectpub_namefrompublishers
    wherepub_namelike'_i%'
    思考:如果改成’_i_’会返回什么结果?
    例3:查找出版商名称包含字符’a’或’b’或’c’的所有出版商信息。
    解答:
    selectpub_namefrompublishers
    wherepub_namelike'%[a-c]%'
    思考:’%[abc]%’,结果
    思考:’%[^abc]%’,结果
    二、ISNULL和ISNOTNULL关键字:
    在SQL中,NULL是一个未知值,或者是一个尚未提供数据的值。注意:NULL和零意义不相同
    例:查找stor_id为NULL的所有折扣类型
    解答:
    SELECT*
    FROMdiscountsWHEREstor_idISNULLISNOTNULL意义和ISNULL相反。ISNULL系统函数---使用指定的替换值替换NULL
    语法:ISNULL(check_expression,replacement_value)
    例:检索书名、类型及价格,当价格为null时应显示0.00。
    解答:
    SELECTtitleASTitle,typeASType,
    ISNULL(price,0.00)ASPrice
    FROMtitles
    三、ORDERBY关键字:指定结果集的排序。语法:SELECTselect_column_listFROMtable_name[ORDERBYcolumn_name|select_list_number|expression[ASC|DESC][,column_name|select_list_number|expression[ASC|DESC]...]其中ASC代表升序(缺省值),从最低值到最高值对指定列中的值进行排序。DESC代表降序,从最高值到最低值对指定列中的值进行排序。例1:打印所有员工的资料,并按员工的雇用日期的升序排列。解答:SELECT*FROMemployeeORDERBYhire_dateASC例2:按pub_id的降序排列来打印所有图书的标题信息。解答:SELECT*FROMtitlesORDERBYpub_idDESC注意:ORDERBY不仅可以对单列进行排序,同时也可对多列排序(其排序是嵌套的)。
    例3:打印出版图书标题相关的出版商id、图书类型、图书价格,并且按照出版商id升序排列,同一出版商对应的出版图书类型按降序排列,同一出版商的同一出版图书类型的价格也按降序排列。
    分析:需求比较复杂,得实现嵌套查询,首先id升序排列,而同一id对应得出版图书类型则按降序,价格一样降序。因此,我们可以通过ORDERBY来实现该嵌套排序。
    解答:
    SELECTpub_id,type,title_id,price
    FROMtitles
    ORDERBYpub_id,typeDESC,priceDESC
    四、TOP关键字:用于限制返回到结果集中的行数语法:TOPn[PERCENT]n代表返回的行数,如果使用了PERCENT,则代表返回结果集的n%。TOP一般和ORDERBY结合使用。例1:打印最后加入公司的三名员工的ID。解答:SELECTTOP3*FROMemployeeORDERBYhire_dateDESC注意:TOP关键字紧跟在SELECT关键字之后使用!SELECTTOP10PERCENT*FROMemployeeORDERBYhire_date假设employee表共有43行记录,那么以上语句返回几行数据?例2:打印发行日期在1991/6/9和1991/6/30之间的图书预付款最高的三种图书的ID。
    解答:
    SELECTTOP3title_id,pubdate,advanceFROMtitles
    WHEREpubdate>='6/9/1991'andpubdate<='1991/6/30'
    ORDERBYadvanceDESC
    五、ALL和DISTINCT关键字:
    用于去除冗余行。
    例:检索所有已出版书籍的作者ID。
    解答:
    SELECTALLau_idFROMtitleauthor
    通过以上语句我们可以解决问题,但是,大家可以发现,有的作者ID重复出现,而客户只想知道哪些作者,并不愿看到重复数据,因此,我们得去掉冗余行,通过DISTINCT关键字就能做到。
    SELECTDISTINCTau_idFROMtitleauthor
    现在,冗余行没有了!
    注意:DISTINCT关键字一般和聚合函数一起使用,下面将讲解聚合函数。
    对于DISTINCT关键字来说,各空值将被认为是相互重复的内容。当SELECT语句中包括
    DISTINCT时,不论遇到多少个空值,在结果中只返回一个NULL。
    SELECTALLau_idFROMtitleauthor
    等同于
    SELECTau_idFROMtitleauthor
    也就是说,SQL缺省的是查找所有记录(包括冗余行)。
    六、聚合函数:用于在查询结果集中生成汇总值。
    例1:计算所有书籍的平均价格。
    分析:通过AVG聚合函数可以求平均值。
    解答:
    SELECTAVG(price)FROMtitles
    例2:计算商务书籍的平均价格(不包括重复价格值)。解答:SELECTAVG(DISTINCTprice)FROMtitlesWHEREtype='business'对比以下语句执行结果:SELECTAVG(price)FROMtitlesWHEREtype='business'例3:计算titles表中所有书籍的本年度截止到目前的销售总额
    解答:
    USEpubs
    SELECTSUM(ytd_sales)
    FROMtitles
    分析:通过使用SUM聚合函数来汇总列ytd_sales所有值的和,从而得到销售总额。
    例4:计算商务书籍的预付款平均值和year-to-date的销售额总和。解答:USEpubsSELECTAVG(advance),SUM(ytd_sales)FROMtitlesWHEREtype='business'目的:聚合函数可以一起使用。每一个聚合函数生成一个汇总值。例5:查找产品的最高单价。解答:SELECTMAX(unitprice)FROMproducts请大家分析以下语句:SELECTproductname,MAX(unitprice)FROMproducts例6:查找titles中的书籍总数
    解答:
    USEpubs
    SELECTCOUNT(*)FROMtitlesCOUNT(*)返回符合查询中指定的搜索条件的行的数目,而不消除重复值和NULL值。例7:查找作者所居住的不同城市的数量。
    解答:
    USEpubs
    GO
    SELECTCOUNT(DISTINCTcity)
    FROMauthors
    GO
    例8:计算现有员工的总人数。解答:USEpubsGOSELECTcount(emp_id)FROMemployeeGO请大家思考在?处应填写什么内容?可以得知,COUNT(ALL|DISTINCTexpression)和COUNT(*)功能相似,但不包括NULL值。其中ALL选项会计算重复值,而DISTINCT选项不会计算重复值。例9:对比分析下列两条语句执行结果。
    语句1:SELECTCOUNT(DISTINCTcity)
    FROMauthors
    语句2:SELECTCOUNT(ALLcity)
    FROMauthors
    聚合函数小结:
    1.SUM、AVG、COUNT、MAX和MIN忽略空值,而COUNT(*)不忽略。
    2.可选关键字DISTINCT可以与SUM、AVG和COUNT一同使用,以便在应用聚合函数之前
    消除重复值(默认为ALL)。
    3.SUM和AVG只能对数字列使用。MIN和MAX不能对bit数据类型使用。除COUNT(*)外,其它聚合函数均不能对text和image数据类型使用
    4.查询列不能和聚合函数一起使用,除非使用分组函数(后面内容)。
    5.对NULL值的计算其返回结果为NULL值。
    注意:SUM和COUNT的区别。
    七、GROUPBY分组函数以及CUBE运算符:使用聚合函数把结合集归纳为在询问中定义的分组语法:SELECTcolumn_list
    FROMtable_name
    WHEREcondition_expression
    GROUPBY[ALL]expression[,expression]
    [HAVINGsearch_condition]
    例1:计算每种类型书籍的平均价格并显示。分析:我们先看看以下语句:SELECTAVG(price)FROMtitles该语句可以得出所有书籍(包括所有类型的书籍)的平均价格,显而易见,该语句并不能满足客户需求,客户要看的是每种类型书籍的平均价格。即分类别的查看数据,通过我们即将学习的GROUPBY分组函数就能解决客户需求。解答:SELECTtype,AVG(price)FROMtitlesGROUPBYtype注意:在该语句中,查询列可以和聚合函数一起使用,是因为对出现的查询列使用了分组函数!由此可见,GROUPBY将对其后紧接的列进行分组,比如现代烹调书籍是一组,商业书籍是一组。通过和聚合函数的一起使用,我们就能对每组进行聚合运算,从而得到正确结果。
    例2:计算版税为10%的每种类型书籍的平均价格并显示。解答:SELECTtype,AVG(price)FROMtitlesWHEREroyalty=10GROUPBYtype例3:执行以下语句:
    SELECTtype,AVG(price)
    FROMtitles
    WHEREroyalty=10
    GROUPBYALLtype
    查看结果并对比例2,分析ALL关键字在这里的作用。
    例4:按类型和出版商ID分组,得到平均价格和year-to-date的销售额总和。解答:USEpubsSELECTtype,pub_id,'avg'=AVG(price),'sum'=SUM(ytd_sales)FROMtitlesGROUPBYtype,pub_id提示:GROUPBY也可以对多列的组合进行分组。例5:打印本年度截止到目前的销售总额超过$40,000的出版商。
    分析:按照需求,大家可能很快就给出了答案,答案如下:
    SELECTpub_id,total=SUM(ytd_sales)
    FROMtitles
    WHERESUM(ytd_sales)>40000
    GROUPBYpub_id
    但是,很遗憾,以上语句是错误的,在WHERE子句中是不允许使用聚合函数的,因此,子句就能派上用场了!用法如下:
    SELECTpub_id,total=SUM(ytd_sales)
    FROMtitles
    GROUPBYpub_id
    HAVINGSUM(ytd_sales)>40000
    HAVING
    注意:HAVING子句可以结合GROUPBY子句一起使用,也可以单独使用。当结合GROUPBY子句时,HAVING子句将对分组后的结果进行条件筛选,显示筛选后的结果集;如单独使用则和WHERE子句功能基本类似,区别就是可以在HAVING子句中使用聚合函数!
    练习:显示本年度截止到目前的销售总额超过$10,000的前两位出版商。(提示:GROUPBY可以与ORDERBY子句结合使用)
    例6:按类型和出版商ID分组,得到平均价格和year-to-date的销售额总和,并分别打印每一类型和每一个出版商的平均价格和销售额总和。
    解答:
    USEpubs
    SELECTtype,pub_id,'avg'=AVG(price),'sum'=SUM(ytd_sales)
    FROMtitles
    GROUPBYtype,pub_idWITHCUBE
    输出的结果集如下:
    ---------------------------------------------
    typepub_idavgsum
    business07362.990018722
    business138917.310012066
    businessNULL13.730030788
    mod_cook087711.490024278
    mod_cookNULL11.490024278
    popular_comp138921.475012875
    popular_compNULL21.475012875
    psychology073611.48259564
    psychology087721.5900375
    psychologyNULL13.50409939
    trad_cook087715.963319566
    trad_cookNULL15.963319566
    UNDECIDED0877NULLNULL
    UNDECIDEDNULLNULLNULL
    NULLNULL14.766297446
    NULL07369.784028286
    NULL087715.410044219
    NULL138918.976024941---------------------------------------------由此可见,CUBE运算符在SELECT语句的GROUPBY子句中指定,对每组数据进行数据汇总。八、日期、数字、字符函数:
    DATEPADD语法:DATEADD(datepart,number,date)---datepart:指定应向日期的哪一部分添加值。number:增加值date:被操作的日期DATEDIFF语法:DATEDIFF(datepart,startdate,enddate)---datepart:指定应向日期的哪一部分进行减运算。startdate:开始日期enddate:结束日期DATEPART语法:DATEPART(datepart,date)---datepart:指定日期的哪一部分。date:被操作日期DATENAME语法和DATEPART语法一致。功能也相似,唯一区别就是DATENAME函数返回字符串,而
    DATEPART返回整数。
    SQLSERVER2000中的日期部分以及缩写:
    例1:SELECTGETDATE()‘当前日期’
    返回结果集:
    当前日期
    ------------------------------------------------------
    2006-05-1719:14:51.050
    (所影响的行数为1行)
    例2:假设当前日期为2006-05-17SELECTDATEADD(day,10,GETDATE())返回结果:10天之后的日期------------------------------------------------------2006-05-2720:56:32.517(所影响的行数为1行)
    例3:打印出版书籍的已出版天数
    解答:
    SELECTDATEDIFF(day,pubdate,getdate())'出版天数'
    FROMtitles
    返回结果:
    出版天数
    -----------
    5453
    5456
    5435
    5443
    5456
    5447
    2110
    5435
    4357
    2110
    5322
    5450
    5338
    5453
    5453
    5322
    5453
    5453
    (所影响的行数为18行)
    例4:以字符串的格式打印当天所在月份?。解答:SELECTDATENAME(yy,GETDATE())+'年'+DATENAME(mm,GETDATE())返回结果:
    ---------------------------------------------------------
    +'月'
    2006年05月(所影响的行数为1行)
    例5:返回当前的月份。解答:SELECT'第'+CONVERT(CHAR(1),MONTH(GETDATE()))+'月'返回结果:-----第5月(所影响的行数为1行)
    补充:SQL提供了两种数据类型转换的方法,分别如下:1.CAST语法:CAST(expressionASdata_type)例:SELECT2.CONVERT语法:CONVERT(data_type[(length)],expression[,style])教材214页。B.字符串函数
    例1:SELECTSUBSTRING('abcdef',1,3)
    分析:从第一个字符’a’开始提取3个字符’abc’。
    例2:SELECTASCII('a')分析:返回字符’a’的ASCII码。例3:SELECTLEFT('abcde',2)分析:返回表达式'abcde'左边开始指定的2个字符。例
    4:SELECTLEN('abcde')分析:返回字符串'abcde'的长度例5:SELECTUPPER('abcde')分析:返回字符串'abcde'的大写格式例6:SELECTRTRIM(LTRIM('abce'))分析:去除字符串'abce'的左右空格并返回结果。例7:SELECTREPLACE('abcde','cd','ef')
    分析:将字符串'abcde'中的部分字符串'cd'替换为'ef'
    例1:SELECTROUND(123.9994,0),ROUND(123.9995,3),ROUND(123.45,-2)
    分析:当第二个参数值为正数时从数字表达式(第一个参数)的小数位往后移动3位,从该处进行四舍五入。负数则移动方向相反。
    例2:SELECTFLOOR(123.45),FLOOR(-123.45),FLOOR($123.45)预测结果。D.其余函数1.DATALENGTH()返回指定的表达式所用的字节数2.USER_NAME()返回当前用户名*********************************************************第五章一、联接查询:在前面,我们都是对单张表查询,而在现实中,客户有时查看的数据将会涉及到多张表的内容(比如:?),因此,数据库提供了一种对一张以上的表进行查询的功能,我们称之为联接查询!联接可被定义一个操作,包括一次从多个表中检索数据注意:对于实现联接查询的多张表之间需满足一些特定条件,在下面我们将会详细掌握。联接条件可在FROM或WHERE子句中指定,建议在FROM子句中指定联接条件各种联接类型:
    1.内联接(innerjoin)
    内联接使用比较运算符根据每个表共有的列的值匹配两个表中的行
    结合比较运算符使用。语法:
    SELECTselect_column_list
    FROMtable_name1[INNER]JOINtable_name2
    ONtable_name1.ref_column_name
    join_operator
    table_name2.ref_column_name
    通过join关键字将两张表联接起来,on关键字指出两张表之间的联接公共列!其中join_operator可以是=、<>这样的比较运算符。例1:检索同一个城市中的作者和出版商的详细资料
    分析:我们已知,作者的相关资料存储在authors表,出版商信息存储在publishers表中。因此,客户查看的资料来自于两张不同的表。客户要求作者和出版商必需在同一城市,也就是理解为,authors表中的city列和publishers表中的city列中都出现的城市所在的行记录都得检索出来,从而涉及到检索多张表中数据。而authors表与publishers表都有列--city,且两张表的city列数据类型兼容,因此我们可以在这两张表上进行联接查询操作!
    解答:
    USEpubs
    SELECT*
    FROMauthorsINNERJOINpublishers
    ONauthors.city=publishers.city
    以上语句将从authors和publishers中查找居住城市相同的作家和出版商的信息,其中通过INNERJOIN将两张表联接起来,接着再通过ON指出两张表的公共列,authors.city=
    publishers.city表示只搜索两张表中都存在的city所在的行记录。
    注意:在返回结果集中我们发现city列出现了两次,其中一列属于authors表,一列属于publishers表,数据是冗余的,没有任何意义,这种通过*查找所有列的联接查询我们称之为相等联接。因此,为了去掉多余的列,我们可以更改选择列表来消除两个相同列中的一个,将*改为特定的表列名。通过指定表列名的联接查询我们称之为自然联接!例2:执行以下语句,对比例1结果:
    USEpubs
    SELECTpublishers.pub_id,publishers.pub_name,
    publishers.state,authors.*
    FROMauthorsINNERJOINpublishers
    ONauthors.city=publishers.city
    例3:查找折扣为5折的所有折扣类型和商铺名称。分析:首先,折扣类型相关资料存储在discounts表中,其次商铺名称信息存储在stores中,涉及到了多表查询,因此我们得通过联接查询来实现需求。解答:SELECTstores.stor_name,discounts.discounttype,discounts.discountFROMdiscountsJOINstoresONdiscounts.stor_id=stores.stor_idWHEREdiscounts.discount=5请大家执行下面语句,将结果和例3执行结果对比一下:SELECTs.stor_name,d.discounttype,d.discountFROMdiscountsdJOINstoressONd.stor_id=s.stor_id补充:在之前,我们都知道怎样自定义标题,可上面语句discountsd难道是给表定义标题?实际上意思差不多,这种方式我们称之为给discounts表定义一个别名’a’,同样,storess即给stores表定义别名’p’。通过别名我们可以查找表中任何列。别名的作用实际上就是提供更简洁的语法,对比上面两个语句,我们可以明显发现第二条语句更为简洁,特别是当查询列名比较多时其作用更明显。
    例4:查找住在MassachusettsMA之后(按字母顺序排列)的州的NewMoon作家相关资料。Massachusetts是书籍出版商NewMoonBooks的所在地。
    分析:涉及到publishers和authors表的多表查询,但是,不再是查找条件相等的记录,而是查找居住州大于(按字母顺序排列)Massachusetts的作家及出版商相关资料。
    解答:
    USEpubs
    SELECTp.pub_name,p.state,a.au_lname,a.au_fname,a.state
    FROMpublisherspINNERJOINauthorsaONa.state>p.stateWHEREp.pub_name='NewMoonBooks'注意:ON后面所接语句是a.state>p.state,即作家居住地应大于出版商NewMoonBooks所在居住地Massachusetts。因此,最终显示结果就是例题的需求结果。
    例5:查找类型为’trad_cook’的所有书名和相应的作者名。分析:涉及到表titles和表authors中的数据,可是我们发现这两张表没有公共列!!而内联接查询是基于公共列的,也就是说我们不能直接对该两张表进行联接查询,幸运的是,在pubs数据库中存在表titleauthor,我们不难发现,该表既和titles有公共列title_id,又何authors表有公共列au_id,因此,我们可以通过表titleauthor将titles表和authors联接起来,从而达到联接的目的,表titleauthor在这里充当是中间表的角色。解答:USEpubsSELECTa.au_lname,a.au_fname,t.titleFROMauthorsaINNERJOINtitleauthortaONa.au_id=ta.au_idJOINtitlestONta.title_id=t.title_idWHEREt.type='trad_cook'ORDERBYt.titleASC结果:我们可以通过联接实现多表查询。2.外联接()上面我们已经学习了内联接,已知内联接是查找多张表中的匹配行(即满足特定条件的行),而外联接则有所不同,如果结果集包含来自一个表的所有行和另一个表中的匹配行的话,那么这种连接称为外联接。语法:
    SELECTselect_column_list
    FROMtable_name1[LEFT|RIGHT]OUTERJOINtable_name2
    ONtable_name1.ref_column_namejoin_operator
    table_name2.ref_column_name
    左向外联接
    例1:修改内联接中例1的需求,既在结果中包括所有的作者,而不管出版商是否住在同一个城市
    解答:
    USEpubs
    SELECTa.au_fname,a.au_lname,p.pub_name
    FROMauthorsaLEFTOUTERJOINpublishersp
    ONa.city=p.city
    返回结果分析:不管是否与publishers表中的city列匹配,LEFTOUTERJOIN均会在结果中包含authors表的所有行。注意:结果中所列的大多数作者都没有相匹配的数据,因此,这些行的pub_name列包含空值。
    当使用左向外联接时,联接符左边的表所有行和右边表的匹配行显示匹配数据,而右表不匹配行则显示NULL值。
    右向外联接:
    与左向正好相反。
    语句:
    USEpubs
    SELECTa.au_fname,a.au_lname,p.pub_name
    FROMpublisherspRIGHTOUTERJOINauthorsa
    ONa.city=p.city
    与左向例1语句结果一样。
    完整外部联接:
    进一步修改上面需求,既结果中包括所有作者和出版商,而不管城市中是否有出版商或者出版商是否住在同一个城市。
    解答:
    USEpubs
    SELECTa.au_fname,a.au_lname,p.pub_name
    FROMauthorsaFULLOUTERJOINpublishersp
    ONa.city=p.city
    3.交叉联接
    将两张表进行笛卡儿积运算,第一个表的行数乘以第二个表的行数等于笛卡尔积结果集的大小。
    注意:满足交叉联接的两张表必须完全兼容,既列数、列数据类型、列顺序等一致。
    例1:USEpubs
    SELECTau_fname,au_lname,pub_name
    FROMauthorsCROSSJOINpublishers
    假设authors表有23行,publishers表有9行,那结果集有多少行?
    二、子查询:子查询可被定义作返回单值的SELECT查询。子查询是嵌套在SELECT,INSERT,UPDATE或DELETE语句中子查询可以用来从多表中检索数据和可以用作一个连接的候选子查询也可以用在SELECT,INSERT,UPDATE,和DELETE语句的WHERE或HAVING子句中一般结合EXISTS、IN、SOME(ANY)、ALL使用。例1:打印作者和出版商共同居住的城市的集合分析:使用EXISTS,其主要是用于指定一个子查询,检测行的存在,行存在返回true,不存在返回false。由EXISTS引入的子查询将返回两个查询(父、子查询)的交集,而NOTEXISTS返回差集。解答:USEpubsSELECTDISTINCTcityFROMauthorsWHEREEXISTS(SELECT*FROMpublishersWHEREauthors.city=publishers.city)结果分析:放在EXISTS括号中的查询语句我们称之为子查询,最终结果就是取两个语句结果集的交集,即满足作者和出版商居住城市相同的条件的所有行记录的集合。以上语句等同于:USEpubs
    SELECTDISTINCTa.cityFROMauthorsaJOINpublisherspONa.city=p.city例2:检索所有曾出版过商业书籍的出版商的名称
    解答:
    USEpubs
    SELECTpub_name
    FROMpublishers
    WHEREpub_idIN
    (SELECTpub_id
    FROMtitles
    WHEREtype='business')
    分析:数据库首先执行子查询语句SELECTpub_idFROMtitlesWHEREtype='business',接着将所得结果放入IN子句中,实际上我们就可以认为最后执行的就是一句使用IN运算符的普通查询语句。
    等同于:
    SELECTpub_name
    FROMpublisherspJOINtitlest
    ONp.pub_id=t.pub_id
    WHEREtype='business'
    SOME(ANY)、ALL结合比较运算符一起使用:=SOME(ANY)运算符与IN等效,以下两语句是等效的:语句1:USEpubsSELECTau_lname,au_fnameFROMauthorsWHEREcityIN(SELECTcityFROMpublishers)语句2:USEpubs
    SELECTau_lname,au_fname
    FROMauthors
    WHEREcity=ANY
    (SELECTcity
    FROMpublishers)
    分析语句:SELECTau_lname,au_fnameFROMauthorsWHEREcity=ALL(SELECTcityFROMpublishers)>ALL表示大于子查询返回的每一个值,即大于最大值
    >ANY表示至少大于一个值,也就是大于最小值
    其余的运算符以此类推。
    子查询的限制:a.由比较运算符引入的子查询的SELECT语句的列表只可包含一个列b.外层查询在WHERE子句中用到的列应该和内层查询SELECT列表中用到的列兼容c.当=,!=,<,<=,>,或>=用在主查询中,ORDEREDBY子句和GROUPBY子句不能用在内层查询中,因为内层查询返回的一个以上的值不可被外层查询处理3将查询结果保存到表中
    P137
    三、创建、更改、删除表:
    1.CREATETABLE
    表是一种用于存储数据的数据库对象
    表中的数据以行和列方式组织
    表中的每一行表示一个唯一的记录,每一列表示记录的一个属性
    简单语法:
    CREATETABLEtable_name
    (column_namedatatype[NULL|NOTNULL],[IDENTITY(SEED,INCREMENT)],column_name
    datatype…)
    例1:
    其中varchar(20),age为int,phone为varchar(30),score为float。
    s_id、sname、age不允许有空值,phone、score允许有空值。
    s_id应为自动增长列,以1开始每次加2。
    解答:
    CREATETABLESTUDENT
    (
    s_idintnotnullidentity(1,2),
    snamevarchar(20)notnull,
    ageintnotnull,
    phonevarchar(30),
    scorefloat
    )
    分析:所有列字段的定义均放在小括号中,其中每个列声明语句之间用逗号隔开。根据语法我们得知,列名在最前,紧接是该列的数据类型,接着是声明该列是否能存储NULL值(默认为能存储NULL值)。
    Identity属性:为表创建一个自动标识列,值以自动增长的方式添加。参数一是指表中的第一个行所使用的值,参数二指增量值。
    比如:s_idintnotnullidentity(1,2)就代表s_id列值将会自动增长,第一条记录将是初始值1,以后每增加一条记录就加2。
    验证表是否创建:
    通过SP_HELP命令来查看表的结构(表名、表的所有者、创建日期等)
    比如:
    SP_HELPSTUDENT
    查看STUDENT表结构。
    2.ALTERTABLE例:修改表STUDENT1.加入新列join_date,数据类型为datetime,可以为空2.修改score列,使其默认值为’0.00’3.删除phone列解答:1.ALTERTABLESTUDENTADDjoin_datedatetimenull2.ALTERTABLESTUDENTADDDEFAULT0.00FORscore3。AlTERTABLESTUDENTDROPCOLUMNphone3.插入数据至表中--INSERTINTO
    表结构被创建后,数据就能插入到表中。你可使用INSERT命令把数据插入到表中
    语法:
    INSERT[INTO]table_name[column_list]
    VALUES(values_list)
    例:学生A数据:
    name:Smith
    age:23
    score:90
    join_date:2005/05/01
    学生B数据:
    name:John
    age:26
    score:取默认值
    join_date:当前日期
    解答:
    INSERTINTOSTUDENT
    VALUES('Smith',23,90,'2005/05/01')
    --注意s_id的值
    INSERTINTOSTUDENT
    VALUES('John',26,DEFAULT,GETDATE())
    3.TRUNCATETABLE(截断表)和DROPTABLE(删除表)a.TRUNCATETABLE删除表中的所有行,而不记录单个行删除操作。表结构及其列、约束、索引等保持不变语法:TRUNCATETABLEtable_nameb.DROPTABLE删除表定义及该表的所有数据、索引、触发器、约束和权限规范语法:DROPTABLEtable_name4.主、外键表中经常有一个列或列的组合,其值能唯一地标识表中的每一行。这样的一列或多列称为表的主键(PK)。主键保证了数据的实体完整性实体完整性:数据库中的所有行都具有一个非空的主键值,所有表都具有主键,且没有具有重复的主键值的表。这确保数据库中所代表的任何事物均不存在重复的条目。可通过定义PRIMARYKEY约束来创建主键。作为主键的列必须保证该列的值唯一且不能为NULL值!语法:PRIMARYKEY(col_name[,col_name[,col_name[,…]]])例:为STUDENT表设置主键
    分析:由于s_id列中不能为NULL,以及值唯一(自动增长列),因此可以将s_id列设为主键。
    解答:
    ALTERTABLESTUDENT
    ADDPRIMARYKEY(s_id)
    外键(FK)是用于建立和加强两个表数据之间的链接的一列或多列。可用于避免这两个表的不一致性,如果一个表的数据依赖于另一个表的数据一般,通过主、外键我们可以将两张表联系起来,产生一种父子关系,主键表为父实体,外键表为子实体,只有当某一个实体的存在依赖于另一个实体时,这两个实体才能建立主、外键关系,比如学员和班级之间的父子关系。
    可通过定义FORIEGNKEY约束来创建外键。
    FOREIGNKEY约束不允许空值。
    语法:
    FOREIGNKEY(col_name[,col_name[,…]])
    REFERENCEStable_name(column_name[,column_name[,…]])
    提示:FOREIGNKEY指定作为外键的单列或者是多列的组合,REFERENCES指定外键所对应的主键表及其主键列。
    例:创建班级表,其中
    5.更新、删除行数据a.UPDATE语句更改表中的现有数据。语法:UPDATEtable_nameSETcolumn_name=value[,column_name=value][FROMtable_name][WHEREcondition]例1:所有出版社将总部搬迁到佐治亚州的亚特兰大市,请更新publishers表。解答:UPDATEpublishersSETcity='Atlanta',state='GA'例2:所有出版书籍价格翻倍,请更新titles表
    解答:
    UPDATEtitles
    SETprice=price*2
    例3:北加利福尼亚州更名为Pacifica(缩写为PC),而奥克兰的市民投票决定将其城市的名字改为BayCity,请更新authors表
    解答:
    UPDATEauthors
    SETstate='PC',city='BayCity'
    WHEREstate='CA'ANDcity='Oakland'
    例4:将表authors的前十个作者的state列进行更新为’GZ’.解答:UPDATEauthorsSETstate='GZ'FROM(SELECTTOP10*FROMauthorsORDERBYau_lname)tWHEREauthors.au_id=t.au_idb.DELETE语句从表中删除行语法:DELETE[FROM]table_name[FROMtable(s)][WHEREcondition]例1:删除au_lname是McBadden的所有行解答:DELETEFROMauthorsWHEREau_lname='McBadden'例2:从authors表中删除前10个作者。解答:DELETEauthorsFROM(SELECTTOP10*FROMauthors)ASt1WHEREauthors.au_id=t1.au_id例3:删除authors表的所有数据。解答:DELETEAUTHORS由此可见,不带where子句的DELETE功能类似于TRUNCATE
    如果要删除在表中的所有行,则TRUNCATETABLE比DELETE快。DELETE以物理方式一次删
    除一行,并在事务日志中记录每个删除的行。TRUNCATETABLE则释放所有与表关联的页。因此,TRUNCATETABLE比DELETE快且需要的事务日志空间更少。
    *********************************************************
    第六章
    一、索引:
    索引是SQLServer使用的一种内部表结构,它基于表中一个或多个列的值,提供对表中行的快速存取。
    索引是对数据库表中一个或多个列的值进行排序的结构
    索引的使用与书的目录很相似,没有索引的表就象没有目录的书,一旦创建索引后,就等于给书创建了目录,我们可以通过目录快速地找到特定记录。
    优点:1.提高执行查询的速度2.实施数据唯一性3.加速了表之间的连接缺点:1.创建索引要花不少时间2.占用磁盘空间,需要额外的磁盘空间来存储索引列数据3.由于每次对表更新、添加、删除行时,数据库都要重新对该表上的索引进行更新,因此额外的操作导致速度降低。虽然索引有不少缺点,但在大多数情况下,索引所带来的数据检索速度优势大大查过其不足之处,因此,适当使用索引还是会提高性能的。索引类型:1.聚簇索引表中各行的物理顺序与键值的逻辑(索引)顺序相同,数据被物理地排序.每个表只可创建一个簇索引CREATECLUSTEREDINDEX……ON…….注意:聚集索引一般在不被经常修改的列上以及包含数量有限的唯一值的列上创建。聚集
    索引通常可加快UPDATE和DELETE操作的速度,因为这两个操作需要读取大量的数据聚集索引比非聚集索引有更快的数据访问速度。2.主键索引为表定义一个主键时将自动创建主键索引,主键索引是唯一索引的特殊类型。主键索引要求主键中的每个值是唯一的。3.非聚簇索引行的物理顺序不同于索引的顺序非簇索引一般在用于连接和WHERE子句的列上创建,且它的值可能被经常地修改每个表可多达249个非簇索引CREATEINDEX命令缺省的创建非聚集索引。索引的特性:
    1.索引加速了连接表的询问、执行排序和分组
    2.索引可用来实施行的唯一性
    3.索引对数据大多数是唯一的列很有用
    4.当你修改索引列的数据时,相关索引会被自动更新
    5.你需要时间和资源来维护索引。你不应创建不被经常性使用的索引
    6.最好不要在一个表中创建大量的索引。
    7.簇索引应在非簇索引之前被创建。簇索引改变了行的顺序。如果非簇索引在簇索引之前被创建,那么它需要被重新构造,典型地,非簇索引在外键上创建。
    8.索引可以在一列或多列的组合上创建
    语法:
    CREATE[CLUSTERED|NONCLUSTERED]INDEXindex_name
    ONtable_name(column_name[,column_name]…)
    例1:我们经常要根据作者姓和名来查询作者信息,但是查询速度比较慢,希望提高执行效率。
    分析:由于作者信息会不断更新,新的作者信息会不断加入,姓和名两列都会经常更改,其次,该两列一般都是用在WHERE子句中作为查询条件,因此,我们决定在这两列上创建非聚簇索引来提高查询速度。
    解答:
    CREATE[NONCLUSTERED]INDEXidx_l_f_nameONauthors(au_lname,au_fname)当执行以下语句时:SELECT*FROMauthorsWHEREau_lname=‘…’andau_fname=‘…’我们会发现速度明显提高(前提是该表中的数据非常多)例2:以下语句经常被执行,但速度不快,请提高执行速度。
    SELECT*
    FROMtitlestjoinsaless
    ONt.title_id=s.title_id
    分析:涉及到联接查询,索引可以提高多表查询的速度,title_id是两表联接的公共列,因此我们得在该公共列上创建索引才能提高联接速度。title_id为sales表的外键,因此我们可以在sales表的该列上创建非聚族索引。
    解答:
    CREATE[NONCLUSTERED]INDEXidx_title_id
    ONsales(title_id)
    使用sp_helpindex命令查看特定表上的相关索引信息。语法:sp_helpindex[@objname=]'name'比如:查看表sales上的索引---sp_helpindex删除索引:语法:DROPINDEXindex_name补充:索引优化向导为选择和创建可能最好的关于数据库的一组索引和信息,可以使用SQLServer提供的索引调节向导(IndexTuningWizard)。sales
    二、SQLServer编程:
    1.批量批量是一起提交SQLServer执行的一组SQL语句也称之为批处理。一般结合GO使用,GO表示批处理语句的结束。注意:GO命令和Transact-SQL语句不可在同一行上。但在GO命令行中可包含注释。例:USEpubsSELECT*FROMauthorsSELECT*FROMpublishersGODELETEFROMauthorsGO以上语句可以分为两个批处理语句,分别以GO结束。2.变量
    用于存储临时值
    语法:
    DECLARE@variable_name
    data_type
    例:DECLARE@tmpint--声明一个类型为整型的变量两种变量:临时变量和全局变量临时变量的生存周期是在批量中,当批量语句结束时该变量也会被丢失!例:DECLARE@tmpint………GO当GO语句执行后,@tmp临时变量也就丢失。例:DECLARE@tmpint
    SET@tmp=10
    PRINT@tmp
    GO
    PRINT@tmp
    以上语句会打印出什么结果?
    全局变量是那些由服务器声明的、通常由服务器赋值的变量
    3.注释多行注释包含在/*和*/之中。单行注释以--开始。4.控制流语句
    控制流语言控制批量、存储过程、触发器和事务中SQL语句的执行流程。
    a.IF…ELSE如果条件满足(布尔表达式返回TRUE时),则在IF关键字及其条件之后执行Transact-SQL语句。可选的ELSE关键字引入备用的Transact-SQL语句,当不满足IF条件时(布尔表达式返回FALSE),就执行这个语句。语法:
    IFboolean_expression
    {sql_statement|statement_block}
    [ELSEboolean_expression
    {sql_statement|statement_block}]
    补充:BEGIN…END语句如果有多行T-SQL语句,那么这些语句必须包含在关键字BEGIN和END中例1:如果当前日期为全年第二季度则将字符串--’第二季度’保存到一个临时变量中并打印,否则将字符串--’其他季度’保存到临时变量中并打印。
    分析:当当前日期为全年第二季度--条件为真时就打印消息’第二季度’,条件为假时就打印其他消息,在这里有了条件判断,因此我们可以使用IF…ELES语句来实现。
    解答:
    DECLARE@messagenvarchar(5)
    IFDATENAME(qq,GETDATE())=‘2’
    BEGIN
    SET@message=‘第二季度’
    END
    ELSE
    BEGIN
    SET@message=‘其他季度’
    END
    PRINT@message
    GO
    例2:如果现代烹调书的平均价格于$15,则显示文本’现代烹调书廉价实惠’,并打印所有现代烹调书籍的标题。否则显示文本’现代烹调书价格昂贵’
    解答:???
    b.WHILE
    重复执行SQL语句或语句块。
    只要while后面指定的条件为真,就重复执行语句。可以使用BREAK和CONTINUE关键字在循环内部控制WHILE循环中语句的执行。
    语法:
    WHILEBoolean_expression
    {sql_statement|statement_block}
    [BREAK]
    {sql_statement|statement_block}
    [CONTINUE]
    例:循环打印1至100,如果打印值为20则不打印该值并继续循环,当值为30则结束循环。
    解答:
    DECLARE@aint
    SET@a=1
    WHILE(@a<=100)
    BEGIN
    IF(@a=20)
    BEGIN
    SET@a=@a+1
    CONTINUE
    END
    IF(@a=30)BREAKPRINT@aSET@a=@a+1END例:如果书籍平均价格少于$30,WHILE循环就将价格加倍,然后选择最高价。如果最高价少于或等于$50,WHILE循环重新启动并再次将价格加倍。该循环不断地将价格加倍直到最高价格超过$50,然后退出WHILE循环并打印一条消息
    解答:
    USEpubs
    GO
    WHILE(SELECTAVG(price)FROMtitles)<$30
    BEGIN
    UPDATEtitles
    SETprice=price*2
    SELECTMAX(price)FROMtitles
    IF(SELECTMAX(price)FROMtitles)>$50
    BREAK
    ELSE
    CONTINUE
    END
    PRINT'Toomuchforthemarkettobear'
    GO
    c.CASE语句
    在有多个条件需要求值的情况下使用。
    语法:
    CASE
    WHENboolean_expressionTHENexpression
    [[WHENboolean_expressionTHEN[ELSEexpression]
    END
    expression][...]]
    例:显示每个作者所居住州的全名
    解答:
    SELECTau_fname,au_lname,
    CASEstate
    WHEN'CA'THEN'California'
    WHEN'KS'THEN'Kansas'
    WHEN'TN'THEN'Tennessee'
    WHEN'OR'THEN'Oregon'
    WHEN'MI'THEN'Michigan'
    WHEN'IN'THEN'Indiana'
    WHEN'MD'THEN'Maryland'
    WHEN'UT'THEN'Utah'
    ENDASStateName
    FROMauthors
    三、存储过程(procedure):存储过程是T-SQL语句和控制流语言的一个集合或批量,它在一个名称下存储,按独立单元方式执行也可以定义存储过程是保存起来的可以接受和返回用户提供的参数的Transact-SQL语句的集合。可以创建一个过程供永久使用,或在一个会话中临时使用(局部临时过程),或在所有会话中临时使用(全局临时过程)。其好处:
    1.减轻网络拥塞
    2.改善安全机制
    3.分担应用服务器负载
    4.提高整体性能
    可以创建一个过程供永久使用,或在一个会话中临时使用(局部临时过程),或在所有会话中临时使用(全局临时过程)。
    因此,存储过程可分为以下几个类型:
    1.系统
    ---以sp开始的由系统预定义的具备特有功能的存储过程。
    如:sp_help、sp_helpindex等
    2.用户定义
    ---通过CREATEPROCEDURE语句创建的存储过程。
    3.临时
    临时过程用#和##命名,可以由任何用户创建
    a.局部临时存储过程
    ---局部临时过程只能由创建该过程的连接使用,
    即在当前会话结束时自动除去
    b.全局临时存储过程
    ---全局临时过程则可由所有连接使用,
    全局临时过程在使用该过程的最后一个会话结束时除去
    4.远程
    ---sp_addlinkedserver,创建一个链接的服务器,使其允许对分布式的、针对OLEDB数据源的异类查询进行访问,如果链接服务器定义为Microsoft?SQLServer?,则可执行远程存储过程
    5.扩展
    ---扩展存储过程使您能够在动态链接库(DLL)文件所包含的函数中实现逻辑,可以象调用Transact-SQL过程那样从Transact-SQL语句调用这些函数
    以xp开头的存储过程,比如:xp_cmdshell、xp_sprintf等
    用户定义存储过程简单语法:
    CREATEPROC[EDURE]proc_name
    [value,……][data_type][OUTPUT]
    AS
    [WITH{RECOMPILE|ENCRYPTION|RECOMPILE,BEGIN
    sql_statement1
    sql_statement2
    ENCRYPTION}]
    END执行存储过程语法:EXEC[UTE]proc_name[value,……][data_type][OUTPUT]修改存储过程语法:ALTERPROC[EDURE]proc_name[value,……][data_type][OUTPUT]ASBEGINsql_statement1sql_statement2END查看存储过程创建语句:SP_HELPTEXTproc_name删除存储过程:
    语法:
    DROPPROC[EDURE]proc_name
    例:创建一个存储过程,该过程返回所有作者的信息。解答:USEpubsIFEXISTS(SELECTnameFROMsysobjectsWHEREname='prcDisplayAuthors'ANDtype='P')DROPPROCEDUREprcDisplayAuthorsGOCREATEPROCEDUREprcDisplayAuthorsASSELECT*FROMauthorsGO执行以上存储过程:
    EXECUTEprcDisplayAuthors
    小测试:当我们将authors表名改为author后,创建时会有什么结果?执行时会有什么结果?
    例:创建存储过程,该过程根据客户指定的作者居住城市返回相关作者信息。解答:该存储过程需能接受客户给定的城市,接着城市查找作者信息并返回,因此,我们需要创建一个带输入参数的存储过程(参数的作用就是能够接受外界传进来的值)。提示:参数是查询中的一个占位符或是一个存储过程,只要查询或存储过程被执行该过程就接受用户定义的值参数可以分为输入参数和输出参数USEpubsIFEXISTS(SELECTnameFROMsysobjectsWHEREname='prcDisGivenAuthors'ANDtype='P')DROPPROCEDUREprcDisGivenAuthorsGOCREATEPROCEDUREprcDisGivenAuthors@au_cityvarchar(20)ASSELECT*FROMauthorsWHEREcity=@au_cityGO执行以上存储过程:EXECUTEprcDisGivenAutho, rs'Oakland'或者EXECUTEprcDisGivenAuthors@au_city='Oakland'以上语句返回居住在Oakland城市的所有作者信息。例:修改存储过程prcDisplayAuthors,只需显示作者的姓和名。
    解答:
    ALTERPROCEDUREprcDisplayAuthors
    AS
    SELECTau_lname+''+au_fnameFROMauthors
    验证存储过程是否修改:
    首先执行SP_HELPTEXTprcDisplayAuthors语句查看存储过程文本。接着执行存储过程:
    EXECprcDisplayAuthors
    例:修改存储过程prcDisGivenAuthors,当用户输入城市中有作者居住时不仅返回作者姓、名信息同时返回该过程已被成功执行的信息—0,否则返回—1。
    分析:关键字RETURN用于在过程或函数中返回特定值,存储过程只能返回整数。
    解答:
    ALTERPROCEDUREprcDisGivenAuthors
    @au_cityvarchar(20)
    AS
    BEGIN
    IFEXISTS(SELECT*FROMauthors
    WHEREcity=@au_city)
    BEGIN
    SELECTau_lname,au_fnameFROMauthors
    RETURN0
    END
    ELSE
    RETURN1
    END
    测试结果:
    测试1:
    DECLARE@resultint
    EXECUTE@result=prcDisGivenAuthors'A'
    PRINT@result
    测试2:
    DECLARE@resultint
    EXECUTE@result=prcDisGivenAuthors'Oakland'
    PRINT@result
    分别查看返回结果。
    例:创建一个存储过程prcDisplayBoth,在过程中分别调用过prcDisGivenAuthors和prcDisplayAuthors。
    解答:
    USEpubs
    IFEXISTS(SELECTnameFROMsysobjects
    WHEREname='prcDisplayBoth'ANDtype='P')
    DROPPROCprcDisplayBoth
    GO
    CREATEPROCprcDisplayBoth
    AS
    BEGIN
    EXECprcDisplayAuthors
    EXECprcDisGivenAuthors'Oakland'
    END
    GO
    例:创建存储过程prcReturnAuthorsValues,该过程接受客户提供的city,如果有值返回,则返回对应作者的姓和名并分别赋给变量last_name和first_name,并且打印变量值;否则打印错误消息文本’对不起,没有您查找的资料’
    分析:在这里需要过程执行后能返回特定值,因此我们需要为过程定义输出参数,同时还要接受用户输入值,所以,我们需要在过程中定义输入和输出参数。
    解答:
    USEpubs
    IFEXISTS(SELECTnameFROMsysobjects
    WHEREname='prcReturnAuthorsValues'ANDtype='P')
    DROPPROCprcReturnAuthorsValues
    GO
    CREATEPROCprcReturnAuthorsValues
    @cityvarchar(20),
    @l_namevarchar(40)OUTPUT,
    @f_namevarchar(20)OUTPUT
    AS
    BEGIN
    IFEXISTS(SELECT*FROMauthorsWHEREcity=@city)
    BEGIN
    SELECT@l_name=au_lname,@f_name=au_fname
    FROMauthors
    WHEREcity=@city
    END
    ELSE
    PRINT'对不起,没有您查找的资料'
    END
    GO
    执行结果1:
    DECLARE@first_nameVARCHAR(20),@last_nameVARCHAR(40)
    EXECprcReturnAuthorsValues'Gary',@last_nameOUTPUT,@first_nameOUTPUT
    PRINT@last_name+''+@first_name
    执行结果2:
    DECLARE@first_nameVARCHAR(20),@last_nameVARCHAR(40)
    EXECprcReturnAuthorsValues'a',@last_nameOUTPUT,@first_nameOUTPUT
    PRINT@last_name+''+@first_name
    例:修改存储过程prcDisplayAuthors,能防止用户查看过程的创建语句。
    四、触发器(trigger):
    触发器是一种特殊的存储过程,一个触发器是由T-SQL语句集组成的代码块,在响应某些动作(改动数据)时激活该语句集。
    可为任何给定的INSERT、UPDATE或DELETE语句创建多个触发器
    特性:
    1.当任何数据修改语句被发出时,就被SQLServer自动地激发
    2.它防止了对数据的不正确、未授权的、和不一致的改变
    3.不能被显式地调用或执行
    4.不能返回数据
    创建语法:
    CREATETRIGGERtrigger_name
    ONtable_name
    [WITHENCRYPTION]
    FOR[INSERT|DELETE|UPDATE]ASsql_statements查看触发器:SP_HELPtrigger_name删除语法:
    DROPTRIGGERtrigger_name
    幻表:1.当触发器激发对INSERT,DELETE,或UPDATE语句的响应时,两个特殊的表被创建。这些是插入和删除表,也称为幻表2.inserted表包含插入在触发器表中的所有记录的拷贝3.deleted表包含了已从触发器表中被删除的所有记录当任何更新发生时,触发器就使用inserted表和deleted表a.INSERTTRIGGER当试图插入一行到触发器表中时,INSERT触发器被激发当INSERT语句被发出时,一个新行被加到触发器和inserted幻表中例:每当用户插入数据到Categories表时都需打印消息文本’Categorieinserted’.解答:需在表Categories上创建触发器,该触发器应能对该表的数据插入触发一系列操作。因此,需创建INSERT触发器。USEpubsIFEXISTS(SELECTnameFROMsysobjectsWHEREname='trgInsertCategorie'ANDtype='TR')DROPTRIGGERtrgInsertCategorieGOCREATETRIGGERtrgInsertCategorieONCategoriesFORinsertASprint'Categorieinserted'测试:
    执行语句:insertCategoriesvalues('Beverages',null,null)
    查看结果。
    例:当用户插入数据到折扣表时,我们需验证其插入的折扣值,如果插入新折扣值小于10,则回滚插入操作(即不能插入新值)。
    分析:对客户插入的折扣值需要我们在该值插入到表之前进行验证,如果符合要求则成功插入,否则不能插入新值,也就是说我们对每一条新值插入进表之前得先验证,接着再决定是否将新值插入表中,通过INSERT触发器我们就能实现。
    解答:
    USEpubs
    IFEXISTS(SELECTnameFROMsysobjects
    WHEREname='trgInsertDiscounts'ANDtype='TR')
    DROPTRIGGERtrgInsertDiscounts
    GO
    CREATETRIGGERtrgInsertDiscounts
    ONDiscounts
    FORinsert
    AS
    begin
    declare@new_discdecimal(4,2)
    select@new_disc=inserted.discount
    frominserted
    print@new_disc
    if(@new_disc<10.00)
    begin
    print'折扣值不符合要求'
    ROLLBACKTRANSACTION--回滚INSERT语句
    end
    else
    print'已成功插入'
    end
    执行以下语句测试:
    insertdiscounts
    values('InitialCustomer',null,null,null,4.00)
    b.DELETETRIGGER当试图从触发器表中删除行时,DELETE触发器被激发当DELETE语句被发出时,所删除行被加到触发器和deleted幻表中例:禁止用户删除折扣表的任何信息,并显示消息文本’不能删除折扣信息’解答:USEpubsIFEXISTS(SELECTnameFROMsysobjectsWHEREname='trgDeleteDiscounts'ANDtype='TR')DROPTRIGGERtrgDeleteDiscountsGOCREATETRIGGERtrgDeleteDiscountsONDiscountsFORdeleteASbeginprint'不能删除折扣信息'ROLLBACKTRANEnd测试语句:Deletefromdiscounts例:禁止用户删除折扣表的任何信息,显示消息文本’不能删除折扣信息’并将用户要删除的行数据打印。
    解答:
    USEpubs
    IFEXISTS(SELECTnameFROMsysobjects
    WHEREname='trgDeleteDiscounts'ANDtype='TR')
    DROPTRIGGERtrgDeleteDiscounts
    GO
    CREATETRIGGERtrgDeleteDiscounts
    ONDiscounts
    FORdelete
    AS
    begin
    print'不能删除折扣信息'
    print'您要删除的行信息为:'
    SELECT*FROMDELETED
    ROLLBACKTRAN
    End
    例:执行以下语句—USEpubsIFEXISTS(SELECTnameFROMsysobjectsWHEREname='a'ANDtype='U')DROPTABLEaGOcreatetablea(a_idintnotnullidentity(1,1)primarykey,a_namevarchar(30))GOUSEpubs
    IFEXISTS(SELECTnameFROMsysobjects
    WHEREname='b'ANDtype='U')
    DROPTABLEb
    GO
    createtableb
    (
    b_idintnotnull,
    a_idintnotnull,
    b_namevarchar(50)
    )
    GO
    insertintoavalues('Smith')insertintobvalues(1,1,'John')当客户删除表a数据时,应同时删除表b中对应的纪录解决:例:修改表b。修改如下:ALTERTABLEbADDforeignkey(a_id)REFERENCESa(a_id)再执行deletefroma语句,请问结果是什么?说明原因并解决。提示:不能使用触发器来实现,可以参考使用级联删除。级联删除—定义在外键上的操作,当删除父表(主键表)数据时会同时删除对应子表(外键表)数据。c.UPDATETRIGGER当出现修改触发触发器表时,该触发器被激活注意:在执行更新操作时,服务器首先将老数据删除,接着将更新数据插入表中。因此,deleted幻表存储的是更新前的数据,inserted幻表存储的是更新后的数据。例:当更新表authors的某一指定作者名(比如id为172-32-1176)时应打印更新前及更新后的数据给客户看。
    解答:
    USEpubs
    IFEXISTS(SELECTnameFROMsysobjects
    WHEREname='trgUpdateAuthors'ANDtype='TR')
    DROPTRIGGERtrgUpdateAuthors
    GO
    CREATETRIGGERtrgUpdateAuthors
    ONauthors
    FORupdate
    AS
    beginprint'更新前的数据:'select*fromdeletedprint'********************************************'print'更新后的数据:'select*frominsertedend五、事务(transaction):
    系统崩溃是由于两个更新之间导致数据不一致性而引起的。需要防止这种情况,要确保两个更新或者都发生或者都不发生
    一个事务可以被定义为作为工作的单个的逻辑单元被一起执行的一串的操作
    单个的工作单元必须具有称为ACID(原子性,一致性,隔离性,和持久性)的四个性质
    1.原子性(atomy)
    事务内的所有语句作为一个独立的完整的单元块执行
    2.一致性(consistency)
    事务内语句要不都执行成功,要不都执行失败
    3.隔离性(insulation)
    由并发事务所作的修改必须与任何其它并发事务所作的修改隔离
    4.持久性(durative)
    事务完成之后,它对于系统的影响是永久性的。该修改即使出现系统故障也将一直保持。
    显式事务-是事务的开始和结束都被显式地定义的事务。SQL中的DDL语句是自动执行事务的。语法:BEGINTRAN[SACTION][transaction_name|@tran_name_variable]COMMITTRANSACTION或COMMITWORK:语句标志显式事务的结束点
    语法:
    COMMIT[TRAN[SACTION][transaction_name|@tran_name_variable]]
    ROLLBACKTRANSACTION或ROLLBACKWORK:这些语句把显式的或隐式的事务回滚到事务的开始,或者回滚到事务内的保存点语法:ROLLBACK[TRAN[SACTION][transaction_name|@tran_name_variable|savepoint_name|@savepoint_variable]]事务保存点:
    保存点把事务分成几个逻辑单元,这样事务可以返回到保存点,如果事务的一部分是有条件地被取消
    语法:
    SAVETRAN[SACTION]{savepoint_name|@savepoint_variable}
    例:确保下面两条语句同时成功执行UpdateauthorsSetcity=‘MenloPark’Whereau_id=‘172-32-1176’UpdatepublishersSetcity=‘NEWYORK’Wherepub_id=‘0877’解答:需要实现原子性,通过显示事务来实现BEGINTRANtrnUpdateAuPubUpdateauthorsSetcity=‘MenloPark’Whereau_id=‘172-32-1176’Updatepublishers
    Setcity=‘NEWYORK’
    Wherepub_id=‘0877’
    COMMITTRANtrnUpdateAuPub
    执行以下语句:
    BEGINTRANtrnUpdateAuPub
    Updateauthors
    Setcity=‘MenloPark’
    Whereau_id=‘17’
    Updatepublishers
    Setcity=‘NY’
    Wherepub_id=‘0877’
    COMMITTRANtrnUpdateAuPub
    分析结果。
    例:语句1:
    Updatediscounts
    Setdiscount=7.70
    Wherediscounttype=‘VolumeDiscount’
    语句2:
    Updatepublishers
    Setcity=‘NY’
    Wherepub_id=‘0877’
    当语句1更新的折扣值大于折扣表中最小折扣值时则回滚语句1、2
    解答:
    BEGINTRANtrnUpdateDisPub
    Updatediscounts
    Setdiscount=7.70
    Wherediscounttype=‘VolumeDiscount’
    Updatepublishers
    Setcity=‘NY’
    Wherepub_id=‘0877’
    If(selectdiscountfromdiscountswhere
    discounttype='VolumeDiscount')
    >
    (selectmin(discount)fromdiscounts)
    Rollbacktran
    Else
    Committran
    分析结果
    例:不管上面例题的条件是否成立,始终提交语句2
    分析:通过设置保存点来实现,即不管什么情况都会提交事务中的部分语句
    解答:
    BEGINTRANtrnUpdateDisPub
    Updatediscounts
    Setdiscount=7.70
    Wherediscounttype='VolumeDiscount'
    savetrantrnUpdateDisPub1
    Updatepublishers
    Setcity='NY'
    Wherepub_id='0877'
    If((selectdiscountfromdiscountswherediscounttype='VolumeDiscount')
    >
    (selectmin(discount)fromdiscounts))
    RollbacktrantrnUpdateDisPub1
    Else
    Committran
    分析结果。
    锁的概念:
    当有语句在对同一资源执行更新或删除、添加的同时,SQLSERVER会对该资源上锁,在上锁期间,任何对该资源的操作都将不能进行,从而确保操作的正常运行。
    死锁概念:两个用户(或事务)在个别的对象的上锁,并且每个用户正在等待另一个对象的锁死锁演示:
    例:打开连接1
    执行语句:
    SETTRANSACTIONISOLATIONLEVELSERIALIZABLEGOBEGINTRANUpdatepublishersSetcity='NY'Wherepub_id='0877'(注意:没有回滚或提交事务,也就代表该事务没有结束)打开连接2执行语句:SETTRANSACTIONISOLATIONLEVELSERIALIZABLEGOSelect*frompublishers注意查看语句执行状态。用SETTRANSACTIONISOLATIONLEVEL设置隔离级别。参数READCOMMITTED指定在读取数据时控制共享锁以避免脏读,但数据可在事务结束前更改,从而产生不可重复读取或幻像数据。该选项是SQLServer的默认值。READUNCOMMITTED
    执行脏读或0级隔离锁定,这表示不发出共享锁,也不接受排它锁。当设置该选项时,可以对数据执行未提交读或脏读;在事务结束前可以更改数据内的数值,行也可以出现在数据集中或从数据集消失。该选项的作用与在事务内所有语句中的所有表上设置NOLOCK相同。这是四个隔离级别中限制最小的级别。REPEATABLEREAD
    锁定查询中使用的所有数据以防止其他用户更新数据,但是其他用户可以将新的幻像行插入数据集,且幻像行包括在当前事务的后续读取中。因为并发低于默认隔离级别,所以应只在必要时才使用该选项。SERIALIZABLE在数据集上放置一个范围锁,以防止其他用户在事务完成之前更新数据集或将行插入数据集
    内。这是四个隔离级别中限制最大的级别。因为并发级别较低,所以应只在必要时才使用该选项。该选项的作用与在事务内所有SELECT语句中的所有表上设置HOLDLOCK相同。
    六、游标(cusor):游标是一个在给定结果集中帮助访问和操纵数据的数据库对象往往需要这样一种机制以便每次处理一行或一部分行,游标就是提供这种机制的结果集扩展游标能实现的功能:1.允许结果集中当前行被修改2.帮助从结果集中当前行导航到不同的行3.允许从结果集中检索指定的行实现游标的步骤:1.定义游标和设置的它的属性语法:DECLAREcursor_name[INSENSITIVE][SCROLL]CURSORFOR{select_statement}[FOR{READONLY|UPDATE[OFcolumn_list]}]INSENSITIVE属性:定义一个游标,以创建将由该游标使用的数据的临时复本SCROLL属性:游标能对结果集执行FIRST、LAST、PRIOR、NEXT等操作,否则只能执行NEXT操作。READONLY属性:游标设置为只读UPDATE[OFcolumn_list]属性:定义游标内可更新的列。如果指定OFcolumn_name[,...n]参数,则只允许修改所列出的列。如果在UPDATE中未指定列的列表,则可以更新所有列。2.打开游标
    语法:
    OPENcursor_name
    3.将游标移动到所需操作的行
    语法:
    FETCH[[NEXT|PRIOR|FIRST|LAST|ABSOLUTEn|RELATIVEn]]FROM
    cursor_name[INTO@variable_name[,...n]]
    ABSOLUTEn属性:
    如果n或@nvar为正数,返回从游标头开始的第n行并将返回的行变成新的当前行
    RELATIVEn属性:
    如果n或@nvar为正数,返回当前行之后的第n行并将返回的行变成新的当前行
    INTO@variable_name[,...n]属性:
    允许将提取操作的列数据放到局部变量中。列表中的各个变量从左到右与游标结果集中的相应列相关联。注意数据类型的匹配以及变量个数与游标选择列表中的列的数目一致
    4.在当前行上执行各种操作
    5.关闭游标
    语法:
    CLOSEcursor_name
    6.释放游标所占据的资源
    语法:
    DEALLOCATEcursor_name
    例:以如下格式显示结果:
    ProductID=1
    ProductName=Chai
    ProductID=2
    ProductName=Chang
    ProductID=3
    ProductName=AniseedSyrup
    …………………
    分析:我们已知道SQL语句返回的缺省是表格形式的结果集,以上格式要求读取每一行的时候以特定格式打印,因此,我们需要游标来处理,一次读取一行。
    解答:
    DECLARE@ProductIDint
    DECLARE@ProductNamenvarchar(25)
    --第一步,为即将操作的结果集声明游标
    DECLAREcurProductscursorfor
    SELECTproductid,productnameFROMproducts
    --第二步,打开游标
    OPENcurProducts
    --第三步,通过游标提取当前行并赋给两个变量
    FETCHcurProductsinto@ProductID,@ProductName
    --通过循环来将游标遍历结果集
    While(@@fetch_status=0)
    /*@@fetch_status系统函数:返回被FETCH语句执行的最后游标的状态。
    返回值:0--FETCH语句成功
    -1--FETCH语句失败或此行不在结果集中
    -2--被提取的行不存在
    */
    BEGIN
    Print'ProductID='+convert(varchar(3),@ProductID)
    Print'ProductName='+@ProductName
    --让游标读取下一行
    FETCHcurProductsinto@ProductID,@ProductName
    END
    --关闭游标
    CLOSEcurProducts
    --释放游标所占据的资源
    DEALLOCATEcurProducts
    补充:联机分析处理(OLAP)
    数据仓库是一个数据库,包含那些通常表示某个组织机构业务历史的数据。通过分析这些历史数据,可以支持对分散的组织单元进行从策略计划到性能评估的多级业务决策。对数据仓库中的数据进行组织是为了支持分析。
    OLAP技术使数据仓库能够快速响应重复而复杂的分析查询,从而使数据仓库能有效地用于联机分析。
    
  • 上一篇资讯: 天PLSQL简介
  • 下一篇资讯: 基本SQL语句-应用
  • 设为首页 | 加入收藏 | 网学首页 | 原创论文 | 计算机原创
    版权所有 网学网 [Myeducs.cn] 您电脑的分辨率是 像素
    Copyright 2008-2020 myeducs.Cn www.myeducs.Cn All Rights Reserved 湘ICP备09003080号 常年法律顾问:王律师