• sql 复习大全——精品




    (1):查询一个数据库中是否存在某个表(两种方式):假设表名为table_name
          if Exists(select * from sysobjects where name='table_name') drop table table_name 或
          if object_id('table_name') is not null drop table table_name
          同样的操作也可用来判断数据库是否存在!
    (2):对表的一些实例操作:
          创建一个表的实例:(学生成绩表:grade_table)
          if exists(select * from sysobjects where name = 'grade_table')
           drop table grade_table     
          go
          create table grade_table
          (
                 stuID varchar(20),
                 courseID varchar(20),
                 grade int
          )
          插入表中数据:(学生成绩表:grade_table)
        

     insert into grade_table values('10001','001','85')
          insert into grade_table values('10002','001','95')
          更新表中数据:
          update grade_table set grade=70 where stuID='10001' and courseID='001'
          删除表中数据:
          delete grade_table where stuID='10001' and courseID='001'

    新建一个与student_table相同的表student然后插入student_table中查询的数据,一般此方法可用来导一些数据

    insert into student select * from student_table as s1 where s1.studentID not in (select studentID from student)

     
    存储过程
    在Sql Server中,可以定义子程序存放在数据库中,这样的子程序称为存储过程,它是数据库对象之一.
    一 存储过程的优点:
    1: 存储过程在服务器端运行,执行速度快
    2: 存储过程只执行一次,然后把编译的二进制代码保存在调整缓存中,以后可从中调用,提高系统的性能.
    3: 确保数据库的安全.使用存储过程可以完成所有的数据库操作,并可通过编程方式来控制
    4: 自动完成所需要的预先势利的任务.方便客户
    二 存储过程的类型(五类)
    (1)     系统存储过程. 由系统提供的存储过程,可以作为命令执行各种操作.定义在系统数据库master中,前缀是sp_,例如常用的显示系统对象信息的sp_help存储过程
    (2)     本地存储过程. 指用户数据库中创建的存储过程,这种存储过程完成特定的数据库任务
    (3)     临时存储过程. 它属于本地存储过程,如果存储过程前面有一个’#’代表局部临时存储过程,如果有’##’代表全局临时存储过程,可以在所有的用户会话中使用.
    (4)     远程存储过程. 指从远程服务上调用的存储过程
    (5)     扩展存储过程. 在SQL Server环境之外执行的动态链接库称为扩展存储过程,前缀_sp,使用时要先加载到SQL Server系统中
    三 创建用户存储过程
        用户存储过程只能定义在当前数据库中,可以使用SQL语句,也可使用企业管理器,这里只用SQL语句,注意存储过程中不能定义如下的对象:
             Create view               (视图)
             Create default          (缺省)
             Create rule                (规则)
             Create procedure    (存储过程)
             Create trigger          (触发器)
    1: 通过Sql命令来创建和执行存储过程(假设使用学生表)
        定义如下存储过程:
               Use student
               Go
               Create procedure student_grade
               As
               Select stu.stuID,stu.name,course.name,course.grade
                        From student_table as stu,course_table as course
                        Where stu.stuID=course.stuID and stu.courseID=course.courseID
    使用存储过程:
    Exce student_grade
    Go
    2: 创建存储过程语法格式
    Create proc[edure] procedure_name [;number] –定义过程名
    [{@parameter data_type}]                                   --定义参数的类型
    [varying][ =default][output]                                    --定义参数的属性
    [,…n1]
    [with {recompile|encryption|recompile,encryption}] –定义存储过程的处理方式
    [for replication]
    As sql_statement[…n2]                                                 --执行的操作(所有的sql语句都可以)
    说明:
    (1)     参数number为可选的整数,用于区分同名的存储过程,以便用一条drop procedure语句删除一组存储过程
    (2)     @parameter 为存储过程的形参,@符号作为第一个字符来指定参数名称.data_type为参数的数据类型(如int或varchar(32)等)
    (3)     Default指定存储过程输入参数的默认值,必须是常量或NULL,默认值中可以有通配符(%,_,[]和[^])
    (4)     Recompile表明每次运行该过程时,要重新编译;
    Encryption表示SQL server加密syscomments表中包含create procedure语句文本的条目,就是加密了,别人复制数据库而不能复制它,以防以存储过程来读取数据库中定义
    (5)     参数n2说明一个存储过程可以包含多条T-SQL语句
    3: 存储过程要注意的几点:
    (1)     用户定义的存储过程只能在当前数据库中使用(临时过程除外)
    (2)     成功执行create procedure语句后,过程名存储在sysobjects系统表中,而create procedure语句的文本存储在syscomments中
    (3)     自动执行存储过程.SQL Server启动时可自动执行一个或多个存储过程,这些存储过程必须定义在master数据库中,并在sysadmin固定服务器角色作为后台过程执行,并且不能有任何的参数
    (4)     Sql_statement语句限制 必须使用对象所有者名(就是这个数据库的所有者)对数据库对象进行限定的语句有:
    Create table, alter table, drop table, truncate table, create index, drop index, update statistics及DBCC语句
    (5)     权限. Create procedure的权限默认授予sysadmin固定服务器角色成员,db_ower和db_ddladmin默写数据库角色成员.可以把权限转让.
    4: 存储过程执行语法
    [exce[ute]]
    {[@return_staus = ]
    {procedure_name[;number]|@procedure_name_var}
    [[@parameter = ]{value|@variable[ouput]|[default]}
    [,..n]
    [with recompile]}
    说明:
             @return_status为可选的整形变量,保存存储过程的返回状态,execute语句使用该变量前,必须对其定义.
             Procedure_name和number用于调用定义一组存储过程中一某一个,procedure_name代表了存储过程的组名,number用来指定哪一个.
             Procedure_name_var为create procedure中定义的存储过程名
             @parameter为create procedure中定义的参数名,value为存储过程的实参;
             @variable为output参数返回的值
             Default表示不提供实参,而是使用对应的默认值
             n 表示可以实参可以有多个
    5: 举例
    (1)     创建数据库和相应的表
    create database student  --创建数据库
    go
    use student
    go
    -----------------------------创建学生表------------------------
    if object_id('student_table') is not null
    drop table student_table
    create table student_table
    (
    studentID varchar(20) primary key,
    sname varchar(20) not null,
    sex varchar(2),
    birthday datetime default getdate()
    )
    go
    insert into student_table values('101','王五','男','')
    insert into student_table values('102','李四','男','')
    go
    select * from student_table
    -------------------------------------创建课程表------------------------
    go
    if object_id('course_table') is not null
    drop table course_table
    create table course_table
    (
    courseID varchar(20) primary key,
    cname varchar(20) not null,
    )
    go
    insert into course_table values('001','C语言')
    insert into course_table values('002','数据结构')
    go
    select * from course_table
    --------------------------------------创建学生课程表--------------------------------
    go
    if object_id('student_course_table') is not null
    drop table student_course_table
    create table student_course_table
    (
    studentID varchar(20) foreign key references student_table(studentID),
    courseID varchar(20) foreign key references course_table(courseID),
    grade int
    )
    go
    insert into student_course_table values('101','001',67)
    insert into student_course_table values('101','002',77)
    insert into student_course_table values('102','001',97)
    insert into student_course_table values('102','002',57)
    go
    select * from student_course_table
       
    (1)     设计简单的存储过程
    从student数据库的三个表中查询,返回学生学号,姓名,课程名,成绩,学分
    Use student
    --检查是否已存在同名的存储过程,或有,删除
    If object_id('student_info') is not null
               Drop procedure student_info
    Go
    Create procedure student_info
    As
    Select a.studentID,a.sname,c.cname,b.grade
               From student_table as a inner join student_course_table as b
                        On a.studentID = b.studentID inner join course_table as c
                        On b.courseID = c.courseID
           
    执行:
    exec student_info
    或execute student_info
    (2)     使用带参数的存储过程
    从student数据库的三个表中查询某个人指定的成绩和学分
    Use student
    If exists(select name from sysobjects where name='student_info1' and type='p')
               Drop procedure student_info1
    Go
    Create procedure student_info1
               @sname char(8),@cname char(16)
    As
    Select a.studentID,a.sname,c.cname,b.grade
               From student_table as a inner join student_course_table as b
                        On a.studentID = b.studentID inner join course_table as c
                        On b.courseID = c.courseID
               where a.sname=@sname and c.cname=@cname
    执行:(多种方式
     execute student_info1 ‘王五’,’C语言’

     Exec student_info1 @name=’王五’,@cname=’C语言’
    (3)     使用带有通配符参数的存储过程
    从三个表的连接中返回指定学生学号,姓名,所选课程名称及成绩,该存储过程使用了模式匹配,如果没有提供参数,则使用预设的默认值
    Use student
    If object_id('stu_info') is not null
               Drop procedure stu_info
    Go
    Create procedure st_info
               @name varchar(30)='王%'
    As
    Select a.studentID,a.sname,c.cname,b.grade
               From student_table a inner join student_course_table b
                        on a.studentID = b.studentID inner join course_table c
                        on b.courseID =c.courseID
               where a.sname like @name
    go     
            执行该存储过程
    使用默认参数;execute stu_info
    使用实参; exec stu_info @name=’王%’ 或exec stu_info ‘王%’
    (4)     使用带output参数的存储过程
    用于计算指定学生的总学分,存储过程中使用了一个输入参数和一个输出参数
    Use student
    Go
    If exists(select name from sysobjects where name='totalcredit' and type='p')
               Drop procedure totalcredit
    Go
    Create procedure totalcredit @name varchar(30),@total int OUTPUT
    As
    Select @total=sum(grade)
               From student_table a,student_course_table b,course_table
               Where a.sname=@name and a.studentID=b.studentID
               Group by a.studentID
    Go
    注意:output变量必须在定义存储过程和使用该变量时都定义
     
    执行:
    Declare @t_credit char(20),@total int --@total将作为OUTPUT变量必须先定义
    Exec totalcredit ‘王五’,@total OUTPUT ---OUTPUT必须为大写
    Select ‘王五’,@total
    go
    触发器
    触发器是一类特殊的存储过程.它与表的关系密切,用于保护表中的数据,当有操作影响到触发器保护的数据时,触发器自动 执行,例如使用触发器实现多个表间数据的一致性.
    一般情况下,对表数据的操作有插入,修改,删除,因而维护数据的触发器也可分为三类:
    INSERT,UPDATE和DELETE
    一、使用SQL命令创建触发器
    语法格式如下:
    Create trigger tigger_name on {table|view}             --指定触发器的名称和操作对象
    [with encryption]                                                               --是否使用加密方式
    {{{for|after|instead of} {[delete[,][insert][,],[update]]—定义触发器的类型
    [not for replication]                                                          --说明该触发器不用于复制
    As
    [{if update(column)[{AND|OR} update(column)]
    […n]
    |if(columns_update(){ bitwise_operator } updated_bitmask)
    {comparison_operator } column_bitmask [..n]}]   --两个if语句用来说明触发器执行的条件
    Sql_statement […n]                                                          --一条或若干条sql语句
    }}
            说明:
    (1)     Table | view指在其上执行触发器的表或视图
    (2)     After关键字用于说明触发器在指定操作都成功执行后触发,after是默认设置,不能在视力上定义after触发器
    (3)     If update(column)子句用于测试在指定的列上(column)上进行的insert或update操作不能用于delete操作,返回值为true或false
    (4)     If(columns_update())子句用于测试是否插入或更新了指定的列,返回二进制位数据,若为0没有成功更新,若为1,更新成功
    (5)     Bitwise_operator为用于比较去处的位运算符.update_bitmask的值为整型的位屏蔽码,与实际更新或插入的列对应.例如表t 包含列C0,C1,C2,C3和C4.假定该表上有update触发器,若要检查列C0,C2,C4是否都有更新,可指定update_bitmask的值为00010101(即0x15);若要检查是否只有列C1有更新,可指定updated_bitmask的值为00000010
    (6)     Comparison_operator为比较运算符;columns_bitmask为列屏蔽友,用来检查是否已更新或插入对应列
    (7)     Sql_statement为触发器的SQL语句,当执行delete,insert或update时,对应的解发器生效.
    (8)     N表示触发器可包含多条SQL语句
    二 触发器中使用的特殊表
        执行触发器时,系统创建了两个特殊的逻辑表:inserted表和deleted表
             Inserted表:当向表中插入数据时.insert触发器触发执行,新的记录插入到触发器表和inserted表中
             Deleted表:用于保存已从表中删除的记录,当触发一个delete触发器时,被删除的记录存放到deleted表中
        修改一条记录等于插入一条新记录,同时删除旧记录.对定义了update触发器的表记录修改时,表中原记录移到deleted表中,修改过的记录插入到inserted表中,触发器可检查deleted和inserted表
        例:检索deleted,inserted表中的所有记录
                       Select * from deleted
                       Select * from inserted
    三 使用触发器的限制
    (1)     Create trigger必须是批处理中的第一条语句,并且只能应用到一个表中
    (2)     触发器只能在当前的数据库中创建,但触发器可以引用当前数据库的外部对象
    (3)     如果指定触发器所有者名限定触发器,要以相同的方式限定表名
    (4)     在同一create trigger语句中,可以为多种操作(如insert或update)定义相同的触发器操作
    (5)     如果表中存在外键,不能定义insert和update触发器
    (6)     触发器中可指定set语句,执行期间有效,执行完恢复到以前的状态
    (7)     触发器中不能指定如下T-SQL语句:
    Create database,alter database,load database,restore database,drop database,load log,restore log,disk init,disk resize和reconfigure
    (8)     触发器不能有任何结果集返回
    四 举例
    对于student数据库,如果在student_table表中添加或更改数据,则将向客户端显示一条信息
    /*使用带有提示消息的触发器
    USE master
    GO
    EXEC sp_addmessage 50021, 10, 'no update or delete','us_english',false,replace
    EXEC sp_addmessage 50021, 10, '不能插入或更新','简体中文',false,replace
    go
    Use student
    If exists(select name from sysobjects where name=’reminder’ and type=’tr’)
               Drop trigger reminder
    Go
    Create trigger reminder on student_table
               For insert,update
               As raiserror(4008,16,10)
    消息4008是sysmessages中的用户定义消息,有关创建用户消息的方法看下sp_addmessage存储过程
    注意:SQL server 在调用sp_addmessage 时有一个参数@lang是用来指明所需要加入的message的语种的,如果没有指定,则认为是语言是会话的默认语言,如果你安装的是中文版,则一般是中文,而SQL server有强制必须先增加英文的错误信息之后才能增加中文的错误信息,所以必须现增加英文版的错误信息。然后再增加本地语种的错误信息。
    使用sp_dropmessag删除sysmessages表中添加的信息。直接delete删除不掉
    例如:use master go exec sp_dropmessage 50021
    (1)     在数据库student中创建一个触发器,当向student_course_table中插入一记录时,检查该记录的学号在student_table表中是否存在,检查课程号在course_table中是否存在,若都有则插入,否则不执行插入
    Use student
    If object_id('check_trig') is not null
               Drop trigger check_trig
    Go
    Create trigger check_trig on student_course_table
    For insert
    As
    If exists(select *
               from inserted a
               Where a.studentID not in(select b.studentID from student_table b) or
               a.courseID not in(select c.courseID from course_table c))
               Begin
                        Raiserror('违背数据的一致性',16,1)
                        Rollback transaction
               End
    (2)     在student数据库的student_course_table表中创建一个触发器,若对学号列和课程列修改,则给出提示信息,并取消修改操作.
    通过调用colunms_updated()函数,可快速测试对学号列和课程号列修改所做的更改
    Use student
    Go
    Create trigger update_trig
               On student_course_table
               For update
    As
    If(columns_updated() &3)>0
               Begin
                        Raiserror(‘违背数据的一致性’,16,1)
                        Rollback transaction
               End
    Go
    (3)     Inserted of触发器的设计
    如果视图的数据来自于多个基表,则必须使用instead of 触发器支持引用表中数据的插入,更新和删除操作
    例如:若在一个多表视图上定义了instead of insert触发器,那视图的值可能允许为空,也可能不为空,若视图某列的值不允许为空,则inset语句必须为该列提供相应的值.
         如果视图的列为以下几种情况之一:
    1>     基表中的计算列
    2>     基表中的标识列
    3>     具有timestamp数据类型的基表列
    该视图的insert语句必须为这些列指定值,instead of 触发器在构成将值插入基表的insert语句时会指定的值
    例:在student数据库中的创建表,视图和触发器,以说明instead of insert触发器的使用
    Use student
    go
    Create table books
    (
    bookKey int identity(1,1),
    bookName varchar(10) not null,
    color varchar(10) not null,
    computedCol as (bookName + color),
    Page int,
    )
    Go
    --创建一个视图,包含基表中的所有列
    Create view view2
    As
    Select * from books
    Go
    --在view2视图上创建一个instead of insert触发器
    Create trigger insteadTrig on view2
    Instead of insert
    As
    Begin
               Insert into books
               Select bookName,color,page from inserted
    End
    Go
    直接引用books表的insert语句不能为bookKey字段和computedCor字段提供值
    --正确的insert语句
    Insert into books(bookName,color,page)
               Values('计算机','红色',100)
    --查看结果
    select * from books
    2计算机 红色    计算机红色     100
    --不正确的insert语句(就是插入所有列)
    Insert into books values(2,'计算机辅助教程','红色','绿色',100)
    但对于引用view2视力的insert语句为每一列都指定值:例如
    --对于view2正确的insert语句
    Insert into view2 values(2,'计算机','红色','绿色',100)
    --查看结果
    Select * from view2
    2计算机 红色    计算机红色     100
    3计算机 红色    计算机红色     100
    在执行视图的插入语句时,虽然将bookKey和computedCor字段的值传递了insertedTrig触发器中,但触发器中的insert语句没有选择inserted表的中bookKey和computedCol字段的值(即你写入的这两个字段的值并不真正插入的,它是由系统自动生成或是计算列)
        五:删除触发器
            利用SQL语句琰删除触发器
                        Drop trigger trigger_name[…n]
     以下是一些网站上引用
     

    用SQL语句创建表&用SQL语句创建数据库 数据库中的所有数据存储在表中。数据表包括行和列。列决定了表中数据的类型。行包含了实际的数据。
    例如,数据库pubs中的表authors有九个字段。其中的一个字段名为为au_lname,这个字段被用来存储作者的名字信息。每次向这个表中添加新作者时,作者名字就被添加到这个字段,产生一条新记录。
    通过定义字段,你可以创建一个新表。每个字段有一个名字和一个特定的数据类型(数据类型在后面的“字段类型”一节中讲述),例如字段au_lname存储的是字符型数据。一个字段也可以存储其它类型的数据。
    使用SQL Sever,创建一个新表的方法是很多的。你可以可执行一个SQL语句或使用SQL事务管理器(SQL Enterprise Manager)来创建一个新表。在下一节里,你将学会如何用SQL语句来创建一个新表。
    一、用CREATE语句创建表

    注意:
    如果你还没有建立自己的数据库,现在就跳回到第三章创建这个库。你绝不能向master,tempdb或任何其他任何系统数据库中添加数据。
    从SQL Sever程序组(在任务栏中)中启动ISQL/w程序。出现查询窗口后,从窗口顶部的下拉列表中选择你在第三章所创建的数据库。下一步,在查询窗口中键入下面的SQL语句,单击执行查询按钮,执行这个语句:
    CREATE TABLE guestbook (visitor VARCHAR(40),comments TEXT,entrydate DATETIME)
    如果一切正常,你会在结果窗口中看到如下的文字(如果出现异常,请参阅第三章):
    This command dit not return data ,and it did not return any rows
    祝贺你,你已经建立了你的第一个表!
    你所创建的表名为guestbook,你可以使用这个表来存储来字你站点访问者的信息。你是用CREATE TABLE语句创建的这个表,这个语句有两部分:第一部份指定表的名字;第二部份是括在括号中的各字段的名称和属性,相互之间用逗号隔开。
    表guestbook有三个字段:visitor,comments 和entrydate。

    Visitor         字段存储访问者的名字,

    Comments     字段存储访问者对你站点的意见,

    Entrydate      字段存储访问者访问你站点的日期和时间。
    注意每个字段名后面都跟有一个专门的表达式。例如,字段名comments后面跟有表达式TEXT。这个表达式指定了字段的数据类型。数据类型决定了一个字段可以存储什么样的数据。因为字段comments包含文本信息,其数据类型定义为文本型。
     

    二、字段类型
    不同的字段类型用来存放不同类型的数据。创建和使用表时,你更应该理解五种常用的字段类型:字符型,文本型,数值型,逻辑性和日期型。
    (1)字符型数据
    字符型数据非常有用。当你需要存储短的字符串信息时,你总是要用到字符型数据。例如,你可以把从HTML form的文本框中搜集到的信息放在字符型字段中。
    要建立一个字段用来存放可变长度的字符串信息,你可以使用表达式 VARCHAR。考虑你前面创建的表guestbook:
    CREATE TABLE guestbook (visitor VARCHAR(40),comments TEXT,entrydate DATETIME)
    在这个例子中,字段visitor的数据类型为VARCHAR。注意跟在数据类型后面的括号中的数字。这个数字指定了这个字段所允许存放的字符串的最大长度。在这个例子中,字段visitor能存放的字符串最长为四十个字符。如果名字太长,字符串会被截断,只保留四十个字符。
    VARCHAR类型可以存储的字符串最长为255个字符。要存储更长的字符串数据,可以使用文本型数据(下一节中讲述)。
    另一种字符型数据用来存储固定长度的字符数据。下面是一个使用这种数据类型的例子:
     
    CREATE TABLE guestbook (visitor CHAR(40),comments TEXT,entrydate DATETIME)
     
    在这个例子中,字段visitor被用来存储四十个字符的固定长度字符串。表达式CHAR指定了这个字段应该是固定长度的字符串。
    VARCHAR型和CHAR型数据的这个差别是细微的,但是非常重要。假如你向一个长度为四十个字符的VARCHAR型字段中输入数据Bill Gates。当你以后从这个字段中取出此数据时,你取出的数据其长度为十个字符——字符串Bill Gates的长度。
    现在假如你把字符串输入一个长度为四十个字符的CHAR型字段中,那么当你取出数据时,所取出的数据长度将是四十个字符。字符串的后面会被附加多余的空格。
    当你建立自己的站点时,你会发现使用VARCHAR型字段要比CHAR型字段方便的多。使用VARCHAR型字段时,你不需要为剪掉你数据中多余的空格而操心。
    VARCHAR型字段的另一个突出的好处是它可以比CHAR型字段占用更少的内存和硬盘空间。当你的数据库很大时,这种内存和磁盘空间的节省会变得非常重要。
    (2)文本型数据
    字符型数据限制了字符串的长度不能超过255个字符。而使用文本型数据,你可以存放超过二十亿个字符的字符串。当你需要存储大串的字符时,应该使用文本型数据。
    这里有一个使用文本型数据的例子:
     
    CREATE TABLE guestbook (visitor VARCHAR(40),comments TEXT,entrydate DATETIME)
     
    在这个例子中,字段comments被用来存放访问者对你站点的意见。注意文本型数据没有长度,而上一节中所讲的字符型数据是有长度的。一个文本型字段中的数据通常要么为空,要么很大。
    当你从HTML form的多行文本编辑框(TEXTAREA)中收集数据时,你应该把收集的信息存储于文本型字段中。但是,无论何时,只要你能避免使用文本型字段,你就应该不适用它。文本型字段既大且慢,滥用文本型字段会使服务器速度变慢。文本型字段还会吃掉大量的磁盘空间。
    警告:
    一旦你向文本型字段中输入了任何数据(甚至是空值),就会有2K的空间被自动分配给该数据。除非删除该记录,否则你无法收回这部分存储空间。

    (3)数值型数据
    SQL Sever支持许多种不同的数值型数据。你可以存储整数、小数、和钱数。
    通常,当你需要在表中的存放数字时,你要使用整型(INT)数据。INT型数据的表数范围是从-2,147,483,647到2,147,483,647的整数。下面是一个如何使用INT型数据的例子:
    CREATE TABLE visitlog (visitor VARCHAR(40),numvisits INT)
     
    这个表可以用来记录你站点被访问的次数。只要没有人访问你的站点超过2,147,483,647次,nubvisits字段就可以存储访问次数。
    为了节省内存空间,你可以使用SMALLINT型数据。SMALLINT 型数据可以存储从-32768到32768的整数。这种数据类型的使用方法与INT型完全相同。
    最后,如果你实在需要节省空间,你可以使用TINYINT型数据。同样,这种类型的使用方法也与INT型相同,不同的是这种类型的字段只能存储从0到255的整数。TINYINT型字段不能用来存储负数。
    通常,为了节省空间,应该尽可能的使用最小的整型数据。一个TINYINT型数据只占用一个字节;一个INT型数据占用四个字节。这看起来似乎差别不大,但是在比较大的表中,字节数的增长是很快的。另一方面,一旦你已经创建了一个字段,要修改它是很困难的。因此,为安全起见,你应该预测以下,一个字段所需要存储的数值最大有可能是多大,然后选择适当的数据类型。
    为了能对字段所存放的数据有更多的控制,你可以使用NUMERIC型数据来同时表示一个数的整数部分和小数部分。NUMERIC型数据使你能表示非常大的数——比INT型数据要大得多。一个NUMERIC型字段可以存储从-10^38到 10^38范围内的数。NUMERIC型数据还使你能表示有小数部分的数。例如,你可以在NUMERIC型字段中存储小数3.14。
    当定义一个NUMERIC型字段时,你需要同时指定整数部分的大小和小数部分的大小。这里有一个使用这种数据类型的例子:
     
    CREATE TABLE numeric_data (bignumber NUMERIC(28,0), fraction NUMERIC (5,4) )
     
    当这个语句执行时,将创建一个名为numeric_data的包含两个字段的表。字段bignumber可以存储直到28位的整数。字段fraction可以存储有五位整数部分和四位小数部分的小数。
    一个NUMERIC型数据的整数部分最大只能有28位,小数部分的位数必须小于或等于整数部分的位数,小数部分可以是零。
    你可以使用INT型或NUMERIC型数据来存储钱数。但是,专门有另外两种数据类型用于此目的。如果你希望你的网点能挣很多钱,你可以使用MONEY型数据。如果你的野心不大,你可以使用SMALLMONEY型数据。MONEY型数据可以存储从-922,337,203,685,477.5808到 922,337,203,685,477.5807的钱数。如果你需要存储比这还大的金额,你可以使用NUMERIC型数据。
    SMALLMONEY型数据只能存储从-214,748.3648到214,748.3647 的钱数。同样,如果可以的话,你应该用SMALLMONEY型来代替MONEY型数据,以节省空间。下面的例子显示了如何使用这两种表示钱的数据类型:
     
    CREATE TABLE products (product VARCHAR(40),price MONEY,
    Discount_price SMALLMONEY)
     
    这个表可以用来存储商品的折扣和普通售价。字段price 的数据类型是MONEY,字段discount_price的数据类型是SMALLMONEY。
     
    (4)存储逻辑值
    如果你使用复选框(CHECKBOX)从网页中搜集信息,你可以把此信息存储在BIT型字段中。BIT型字段只能取两个值:0或1。这里有一个如何使用这种字段的例子:
     
     
    CREATE TABLE opinion (visitor VARCHAR(40),good BIT)
     
    这个表可以用来存放对你的网站进行民意调查所得的信息。访问者可以投票表示他们是否喜欢你的网站。如果他们投YES,就在BIT型字段中存入1。反之,如果他们投NO,就在字段中存入0(在下一章里,你将学会如何计算投票)。
    当心,在你创建好一个表之后,你不能向表中添加BIT型字段。如果你打算在一个表中包含BIT型字段,你必须在创建表时完成。
    (5)存储日期和时间
    当你建立一个网站时,你也许需要记录在一段时间内的访问者数量。为了能够存储日期和时间,你需要使用DATETIME型数据,如下例所示:
     
    CREATE TABL visitorlog(arrivaltime DATETIME ,departuretime DATETIME)
     
    这个表可以用来记录访问者进入和离开你网站的时间和日期。一个DATETIME型的字段可以存储的日期范围是从1753年1月1日第一毫秒到9999年12月31日最后一毫秒。
    如果你不需要覆盖这么大范围的日期和时间,你可以使用SMALLDATETIME型数据。它与DATETIME型数据同样使用,只不过它能表示的日期和时间范围比DATETIME型数据小,而且不如DATETIME型数据精确。一个SMALLDATETIME型的字段能够存储从1900年1月1日到2079年6月6日的日期,它只能精确到秒。
    DATETIME型字段在你输入日期和时间之前并不包含实际的数据,认识这一点是重要的。在下一章,你将学习怎样使用大量的SQL函数来读取和操作日期和时间(参见下面的“缺省值”一节)。你也可以在VBScript和JScript 中使用日期和时间函数来向一个DATETIME型字段中输入日期和时间。
    三、字段属性


    上一节介绍了如何建立包含不同类型字段的表。在这一节中,你将学会如何使用字段的三个属性。这些属性允许你控制空值,缺省值和标识值。
    (1)允许和禁止空值
    大多数字段可以接受空值(NULL)。当一个字段接受了空值后,如果你不改变它,它将一直保持空值。空值(NULL)和零是不同的,严格的说,空值表示没有任何值。
    为了允许一个字段接受空值,你要在字段定义的后面使用表达式NULL。例如,下面的表中两个字段都允许接受空值:
     
    CREATE TABLE empty (empty1 CHAR (40) NULL,empty2 INT NULL)
     
    注意:
    BIT型数据不能是空值。一个这种类型的字段必须取0或者1。
    有时你需要禁止一个字段使用空值。例如,假设有一个表存储着信用卡号码和信用卡有效日期,你不会希望有人输入一个信用卡号码但不输入有效日期。为了强制两个字段都输入数据,你可以用下面的方法建立这个表:
    CREATE TABLE creditcards (creditcard_number CHAR(20) NOT NULL,
    Creditcard_expire DATETIME NOT NULL)
    注意字段定义的后面跟有表达式NOT NULL。通过包含表达式NOT NULL,你可以禁止任何人只在一个字段中插入数据,而不输入另一个字段的数据。
     
    你将会发现,在你建设自己的网站过程中,这种禁止空值的能力是非常有用的。如果你指定一个字段不能接受空值,那么当你试图输入一个空值时,会有错误警告。这些错误警告可以为程序调试提供有价值的线索。
    (2)缺省值
    假设有一个存储地址信息的表,这个表的字段包括街道、城市、州、邮政编码和国家。如果你预计地址的大部分是在美国,你可以把这个值作为country字段的缺省值。
    为了在创建一个表时指定缺省值,你可以使用表达式DEFAULT。请看下面这个在创建表时使用缺省值的例子:
    CREATE TABLE addresses (street VARCHAR(60) NULL,
    city VARCHAR(40) NULL,
    state VARCHAR(20) NULL
    zip VARCHAR(20) NULL,
    country VARCHAR(30) DEFAULT ‘USA’)
    在这个例子中,字段country的缺省值被指定为美国。注意单引号的使用,引号指明这是字符型数据。为了给非字符型的字段指定缺省值,不要把该值扩在引号中:
    CREATE TABLE orders(price MONEY DEFAULT $38.00,
    quantity INT DEFAULT 50,
    entrydate DATETIME DEFAULT GETDATE())
    在这个CREATE TABLE语句中,每个字段都指定了一个缺省值。注意DATETIME型字段entrydate所指定的缺省值,该缺省值是函数Getdate()的返回值,该函数返回当前的日期和时间。
     
    (3)标识字段
    每个表可以有一个也只能有一个标识字段。一个标识字段是唯一标识表中每条记录的特殊字段。例如,数据库pubs中的表jobs包含了一个唯一标识每个工作标识字段:
    job_id job_desc
    …………………………………………………………….
    1 New Hire Job not specified
    2 Chief Executive officer
    3 Bushness Operations Manager
    4 Chief Financial Officier
    5 Publisher
    字段job_id为每个工作提供了唯一的一个数字。如果你决定增加一个新工作,新增记录的job_id字段会被自动赋给一个新的唯一值。
    为了建立一个标识字段,你只需在字段定义后面加上表达式IDENTITY即可。你只能把NUMERIC型或INT型字段设为标识字段,这里有一个例子:
    CREATE TABLE visitorID (theID NUBERIC(18) IDENTITY,name VARCHAR(40))
    这个语句所创建的表包含一个名为theid的标识字段。每当一个新的访问者名字添加到这个表中时,这个字段就被自动赋给一个新值。你可以用这个表为你的站点的每一个用户提供唯一标识。
    技巧:
    建立一个标示字段时,注意使用足够大的数据类型。例如你使用TINYINT型数据,那么你只能向表中添加255个记录。如果你预计一个表可能会变得很大,你应该使用NUMERIC型数据。
    标识字段的存在会使你想尝试许多不可能的事情。例如,你也许想利用标识字段来对记录进行基于它们在表中位置的运算。你应该抛弃这种意图。每个记录的标识字段的值是互不相同的,但是,这并不禁止一个标识字段的标识数字之间存在间隔。例如,你永远不要试图利用一个表的标识字段来取出表中的前十个记录。这种操作会导致失败,比如说6号记录和7号记录根本不存在。

    四、删除和修改表
    要删除一个表,你可以使用SQL语句DROP TABLE。例如,又从数据库中彻底删除表mytable,你要使用如下的语句:
    DROP TABLE mytable
    警告:
    使用DROP TABLE命令时一定要小心。一旦一个表被删除之后,你将无法恢复它。
    当你建设一个站点时,你很可能需要向数据库中输入测试数据。而当你准备向世界提供你的网点时,你会想清空表中的这些测试信息。如果你想清除表中的所有数据但不删除这个表,你可以使用TRUNCATE TABLE语句。例如,下面的这个SQL语句从表mytable中删除所有数据:
    TRUNCATE TABLE mytable
    虽然你不能删除和修改已经存在的字段,但你可以增加新字段。最容易的实现方法是使用SQL事务管理器中的Manager Tables窗口。你也可以使用SQL语句ALTER TABLE。下面是一个如何使用这种语句的例子:
    ALTER TABLE mytable ADD mynewcolumn INT NULL
    这个语句向表mytable中增加了一个新字段mynewcolumn。当你增加新字段时,你必须允许它接受空值,因为表中原来可能已经有了许多记录。

     总结

    为了大家更容易理解我举出的SQL语句,本文假定已经建立了一个学生成绩管理数据库,全文均以学生成绩的管理为例来描述。

    1.在查询结果中显示列名:

    a.用as关键字:select name as '姓名' from students order by age

    b.直接表示:select name '姓名' from students order by age

    2.精确查找:

    a.用in限定范围:select * from students where native in ('湖南', '四川')

    b.betweenand:select * from students where age between 20 and 30

    c.“=”:select * from students where name = '李山'

    d.like:select * from students where name like '李%' (注意查询条件中有“%”,则说明是部分匹配,而且还有先后信息在里面,即查找以“李”开头的匹配项。所以若查询有“李”的所有对象,应该命令:'% 李%';若是第二个字为李,则应为'_李%'或'_李'或'_李_'。)

    e.[]匹配检查符:select * from courses where cno like '[AC]%' (表示或的关系,与"in()"类似,而且"[]"可以表示范围,如:select * from courses where cno like '[A-C]%')

    3.对于时间类型变量的处理

    a.smalldatetime:直接按照字符串处理的方式进行处理,例如:
    select * from students where birth > = '1980-1-1' and birth <= '1980-12-31'

    4.集函数

    a.count()求和,如:select count(*) from students (求学生总人数)

    b.avg(列)求平均,如:select avg(mark) from grades where cno=’B2’

    c.max(列)和min(列),求最大与最小

    5.分组group

    常用于统计时,如分组查总数:
    select gender,count(sno)
    from students
    group by gender
    (查看男女学生各有多少)

    注意:从哪种角度分组就从哪列"group by"

    对于多重分组,只需将分组规则罗列。比如查询各届各专业的男女同学人数,那么分组规则有:届别(grade)、专业(mno)和性别(gender),所以有"group by grade, mno, gender"

    select grade, mno, gender, count(*)
    from students
    group by grade, mno, gender

    通常group还和having联用,比如查询1门课以上不及格的学生,则按学号(sno)分类有:

    select sno,count(*) from grades
    where mark<60
    group by sno
    having count(*)>1

    6.UNION联合

    合并查询结果,如:

    SELECT * FROM students
    WHERE name like ‘张%’
    UNION [ALL]
    SELECT * FROM students
    WHERE name like ‘李%’

    7.多表查询

    a.内连接

    select g.sno,s.name,c.coursename
    from grades g JOIN students s ON g.sno=s.sno
    JOIN courses c ON g.cno=c.cno
    (注意可以引用别名)
    b.外连接
    b1.左连接
    select courses.cno,max(coursename),count(sno)
    from courses LEFT JOIN grades ON courses.cno=grades.cno
    group by courses.cno

    左连接特点:显示全部左边表中的所有项目,即使其中有些项中的数据未填写完全。

    左外连接返回那些存在于左表而右表中却没有的行,再加上内连接的行。

    b2.右连接

    与左连接类似

    b3.全连接

    select sno,name,major
    from students FULL JOIN majors ON students.mno=majors.mno

    两边表中的内容全部显示

    c.自身连接

    select c1.cno,c1.coursename,c1.pno,c2.coursename
    from courses c1,courses c2 where c1.pno=c2.cno

    采用别名解决问题。

    d.交叉连接

    select lastname+firstname from lastname CROSS JOIN firstanme

    相当于做笛卡儿积

    8.嵌套查询

    a.用关键字IN,如查询李山的同乡:

    select * from students
    where native in (select native from students where name=’ 李山’)

    b.使用关键字EXIST,比如,下面两句是等价的:

    select * from students
    where sno in (select sno from grades where cno=’B2’)

    select * from students where exists
    (select * from grades where
    grades.sno=students.sno AND cno=’B2’)

    9.关于排序order

    a.对于排序order,有两种方法:asc升序和desc降序

    b.对于排序order,可以按照查询条件中的某项排列,而且这项可用数字表示,如:

    select sno,count(*) ,avg(mark) from grades
    group by sno
    having avg(mark)>85
    order by 3

    10.其他

    a.对于有空格的识别名称,应该用"[]"括住。

    b.对于某列中没有数据的特定查询可以用null判断,如select sno,courseno from grades where mark IS NULL

    c.注意区分在嵌套查询中使用的any与all的区别,any相当于逻辑运算“||”而all则相当于逻辑运算“&&”

    d.注意在做否定意义的查询是小心进入陷阱:

    如,没有选修‘B2’课程的学生 :

    select students.*
    from students, grades
    where students.sno=grades.sno
    AND grades.cno <> ’B2’

    上面的查询方式是错误的,正确方式见下方:

    select * from students
    where not exists (select * from grades
    where grades.sno=students.sno AND cno='B2')

    11.关于有难度多重嵌套查询的解决思想:

    如,选修了全部课程的学生:

    select *
    from students
    where not exists ( select *
    from courses
    where NOT EXISTS
    (select *
    from grades
    where sno=students.sno
    AND cno=courses.cno))

    最外一重:从学生表中选,排除那些有课没选的。用not exist。由于讨论对象是课程,所以第二重查询从course表中找,排除那些选了课的即可。

     

    添加数据库


    use master
    go
    if exists (select * from sysdatabases where name='test')
    drop database mlnt
    go
    create database test
    on
    (
    name='test_data',
    filename='D:"SQLSERVER2000"MSSQL"Data"test_data.mdf',
    size=10mb,
    filegrowth=10%

    )
    log on
    (
    name='test_log',
    filename='D:"SQLSERVER2000"MSSQL"Data"test_log.ldf',
    size=10mb,
    filegrowth=10%
    )sql server 2005 怎么把性别bit 类型的1、0转换成中文男或女显示啊?select case 性别
           when 1 then '男'
           when 0 then '女'
    end as 性别
    from tablea Sql server 2005学习笔记之约束

    一个成功的数据库必须对这些数据进行定义,使它们符合现实,具有完整性,那么这里完整性,就是我们所说的约束.
    约束实际上就是使数据完整, 也就是存储的数据具有一致性和正确性,为了使我们的数据完整,sql server 2005定义了相应的检查和控制数据完整的一套机制,根据所对应的数据库对象和范围的不同,可以分为实体完整,域完整,参照完整和用户自定义完整4种,这 4种完整性的涵义在这里我就不多说了,具体大家可以看书.
    约束在实现时,可以通过以下来实现,主要包括 primary key,check,unique,default,foreign key.
    那么下面我们就来看看如何在sql server2005中实现以上5种约束.
    一,建立student 数据库,方法有两种,这里我们用<新建查询>也就是sql语句来实现,语句如下:
    Create database student
    写完后按f5执行,数据库就可以了,
    二,建立两张表,一个是学生资料表(stuinfo),和学生成绩表(stucj),sql语句如下:
    Stuinfo表:

    create table stuinfo
    (
    stuid char(8) not null,
    stuname nvarchar(10),
    stusex nvarchar(2),
    stuage tinyint,
    stuaddr varchar(50),
    stutel varchar(15),
    stuintro varchar(200)
    )

    Stucj表:

    create table stucj
    (
    stuid char(8) not null,
    stuname nvarchar(10),
    chinese numeric(4,1),
    english numeric(4,1),
    math numeric(4,1)
    )

    三, primary key(主键约束)指的是唯一能将所有记录区分开的字段,以上两张表中的stuid(学生学号)可以作为主键,定义语句是:

    use student
    go
    alter table stuinfo
    add constraint pri_id1 primary key(stuid)
    alter table stucj
    add constraint pri_id2 primary key(stuid)
     

    四.Check(核对)约束,指的是限制一列和多列所输入的值的范围。表中shuage字段表示的是学生的年龄,对这个字段我们可以设置它的范围,sql 语句如下:


    Use student
    Go
    Alter table stuinfo
    Add constraint ch_age check(stuage>10 and stuage<50)

    执行完毕后,你可以向表中添加数据,此时我们的check约束就起作用了。
    五.Default(默认)约束,指的是当用户添加数据时,如果没有给该字段添加数据时,系统自动给它一个默认值,上表中的stusex(学生性别)字段,我们就可以给它设置默认值,比如男或女,那么定义的语句如下:

    Use student
    Go
    Alter table stuinfo
    Add constraint def_stusex default ‘男’ for stusex

    同样再次执行,添加数据时,你不添加stusex的值,看看结果。
    六.Foreign key(外键)约束,指的是用于和加强两张表之间的联系,当在添加,修改和删除数据时,保持两张表中数据的一致性。上面stuinfo表和stucj表中的stuid字段就可以设置,sql语句如下:

    Use student
    Go
    alter table stucj
    add constraint stu_f foreign key(stuid)
    references stuinfo(stuid)

    执行完毕后,可以对两张表中添加,删除和修改数据,测试看看。
    七.unique(唯一)约束,指的是让字段的数据具有唯一性,该字段内的数据不可以发生从复,但是可以为空,而主键不可以为空,实际上,主键也就是一个唯一性约束。在这里我们把stuname(学生姓名)字段设计成 unique,但是实际操作时,学生姓名是可以从复的,这里我们是假设,是为把这个约束制作完。接下来我们看看sql语句:

    Use student
    Go
    alter table stuinfo
    add constraint un_stu unique(stuname)

    同样,执行完毕后,可以添加数据,测试看看。
    以上,我们是一个一个的介绍了约束的使用,实际上在使用时,可以直接在建立表时一起定义,只不过这种定义我们没有给每一个约束命名,操作起来可能不是很方便。那么,接下来我们也来看看这种定义方式,建立一张新表stuinfo1:

    Use student
    Go
    create table stuinfo1
    (
    stuid char(8) not null primary key,
    stuname varchar(10) unique,
    stusex char(2) default '男',
    stuage tinyint check(stuage>10 and stuage<40),
    stutel char(14)
    )

    这种方法的缺点是:它的约束名不是很清楚,所以删除时就必须要到管理视图去操作,麻烦一点。下面我们来看看,用sql语句来删除这些约束:

    Use student
    Go
    alter table stuinfo
    drop constraint un_stu

    我们这里删除的是unique 约束,大家可以试着删除其它约束。
    最后,我把添加约束的格式写一下,便于大家参考:
    Alter table 表名
    Add constraint 约束名 约束类型(字段名或表达式)
    删除的格式如下:
    Alter table 表名
    drop constraint 约束名


  • 相关阅读:
    spring bean-- autowired的正确用法
    @Autowired的使用:推荐对构造函数进行注释
    spring中bean的构造函数,Autowired(Value)注入与@PostConstruct调用顺序
    IconVault – 创建自定义图标字体的神器推荐
    Pure – 赞!轻量的、响应式的 CSS 模块集
    HTML Inspector – 帮助你编写高质量的 HTML 代码
    Tourist.js – 简单灵活的操作指南和导航插件
    分享!20套惊艳的扁平化设计素材免费下载
    Web 开发人员必备的随机 JSON 数据生成工具
    Sylius – 100% 免费和开源的电子商务解决方案
  • 原文地址:https://www.cnblogs.com/weixing/p/1871872.html
Copyright © 2020-2023  润新知