zoukankan      html  css  js  c++  java
  • sql server 2005学习笔记

          200942910:11:04

    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为参数的数据类型(intvarchar(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 statisticsDBCC语句

    (5)     权限. Create procedure的权限默认授予sysadmin固定服务器角色成员,db_owerdb_ddladmin默写数据库角色成员.可以把权限转让.

    4: 存储过程执行语法

    [exce[ute]]

    {[@return_staus = ]

    {procedure_name[;number]|@procedure_name_var}

    [[@parameter = ]{value|@variable[ouput]|[default]}

    [,..n]

    [with recompile]}

    说明:

             @return_status为可选的整形变量,保存存储过程的返回状态,execute语句使用该变量前,必须对其定义.

             Procedure_namenumber用于调用定义一组存储过程中一某一个,procedure_name代表了存储过程的组名,number用来指定哪一个.

             Procedure_name_varcreate procedure中定义的存储过程名

             @parametercreate procedure中定义的参数名,value为存储过程的实参;

             @variableoutput参数返回的值

             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,UPDATEDELETE

    一、使用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)上进行的insertupdate操作不能用于delete操作,返回值为truefalse

    (4)     If(columns_update())子句用于测试是否插入或更新了指定的列,返回二进制位数据,若为0没有成功更新,若为1,更新成功

    (5)     Bitwise_operator为用于比较去处的位运算符.update_bitmask的值为整型的位屏蔽码,与实际更新或插入的列对应.例如表t 包含列C0,C1,C2,C3C4.假定该表上有update触发器,若要检查列C0,C2,C4是否都有更新,可指定update_bitmask的值为00010101(0x15);若要检查是否只有列C1有更新,可指定updated_bitmask的值为00000010

    (6)     Comparison_operator为比较运算符;columns_bitmask为列屏蔽友,用来检查是否已更新或插入对应列

    (7)     Sql_statement为触发器的SQL语句,当执行delete,insertupdate,对应的解发器生效.

    (8)     N表示触发器可包含多条SQL语句

    触发器中使用的特殊表

        执行触发器时,系统创建了两个特殊的逻辑表:inserted表和deleted

             Inserted:当向表中插入数据时.insert触发器触发执行,新的记录插入到触发器表和inserted表中

             Deleted:用于保存已从表中删除的记录,当触发一个delete触发器时,被删除的记录存放到deleted表中

        修改一条记录等于插入一条新记录,同时删除旧记录.对定义了update触发器的表记录修改时,表中原记录移到deleted表中,修改过的记录插入到inserted表中,触发器可检查deletedinserted

        :检索deleted,inserted表中的所有记录

                       Select * from deleted

                       Select * from inserted

    使用触发器的限制

    (1)     Create trigger必须是批处理中的第一条语句,并且只能应用到一个表中

    (2)     触发器只能在当前的数据库中创建,但触发器可以引用当前数据库的外部对象

    (3)     如果指定触发器所有者名限定触发器,要以相同的方式限定表名

    (4)     在同一create trigger语句中,可以为多种操作(insertupdate)定义相同的触发器操作

    (5)     如果表中存在外键,不能定义insertupdate触发器

    (6)     触发器中可指定set语句,执行期间有效,执行完恢复到以前的状态

    (7)     触发器中不能指定如下T-SQL语句:

    Create database,alter database,load database,restore database,drop database,load log,restore log,disk init,disk resizereconfigure

    (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)

    消息4008sysmessages中的用户定义消息,有关创建用户消息的方法看下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 

    在执行视图的插入语句时,虽然将bookKeycomputedCor字段的值传递了insertedTrig触发器中,但触发器中的insert语句没有选择inserted表的中bookKeycomputedCol字段的值(即你写入的这两个字段的值并不真正插入的,它是由系统自动生成或是计算列) 

        :删除触发器

            利用SQL语句琰删除触发器

                        Drop trigger trigger_name[…n]

     以下是一些网站上引用

     

    用SQL语句创建表&用SQL语句创建数据库

  • 相关阅读:
    TyporaRecord
    c# 串口 应答式顺序下发命令 循环 间隔发送指令
    WPF 如何在单独的配置文件中使用Log4net
    UWP VisualStateManager
    USB通信
    UWP RelativePanel
    JSON 序列化与反序列化
    Unity 依赖注入的三种常用模板
    IOC Unity容器的基本使用
    使用EF完成基于SQLite的CodeFirst
  • 原文地址:https://www.cnblogs.com/gaojun/p/1445959.html
Copyright © 2011-2022 走看看