• MS SQL高级——视图与存储过程


    视图与存储过程

    什么是视图

     视图的概念

    • 是存储在服务器端的一个查询块,是一张虚拟表。
    • 表示一张表的部分数据或多张表的综合数据。
    • 其结构和数据是建立在对表的查询基础上。
    • 视图的使用,跟对普通的表的查询使用完全一样。

    视图中不存放数据

    • 数据存放在视图所引用的原始表中。

    表视图的多样性

    • 一个或多个原始表,根据不同用户的不同需求,可以创建不同的视图。

    视图的用途

    • 筛选表中的行。
    • 防止未经许可的用户访问敏感数据。
    • 降低数据库的复杂程度。
    • 将多个物理数据库抽象为一个逻辑数据库。

    如何创建视图

    使用管理器创建视图

     

    T-SQL语句管理视图

    使用T-SQL语句创建视图

    CREATE VIEW view_Stulnfo 
        AS
        <SELECT语句> 
     1 use StudentManager
     2 go
     3 --判断视图是否存在
     4 if exists(select * from sysobjects where name='view_ScoreQuery')
     5 drop view view_ScoreQuery
     6 go
     7 --创建视图
     8 create view view_ScoreQuery
     9 as
    10     select top 1000 Students.StudentId,StudentName,ClassName,
    11              C#=CSharp,SQLDB=SQLServerDB,
    12              ScoreSum=(CSharp+SQLServerDB) from Students
    13              inner join ScoreList on Students.StudentId=ScoreList.StudentId
    14              inner join StudentClass on Students.ClassId=StudentClass.ClassId
    15              order by StudentClass.ClassId
    16 go
    17 --使用视图查询
    18 select * from view_ScoreQuery
    View Code

    使用T-SQL语句删除视图

    IF EXISTS (SELECT*FROM sysobjects WHERE name = view_Stulnfo)
        DROP VIEW view_Stulnfo

    使用T-SQL语句查看视图

    SELECT* FROM view Stulnfo

    创建成绩查询视图

    使用视图注意事项

    • 视图中可以使用多个表
    • 一个视图可以嵌套另一个视图(尽量少套用)
    • 视图定义中的SELECT语句不能包括下列内容:
      • ORDER BY子句,除非在SELECT语句的选择列表中也有一个 TOP子句。 
      • INTO关键字。 
      • 引用临时表或表变量。

    什么是存储过程

    概念

    • 预先存储好的SQL程序
    • 保存在SQLServer中(跟视图的存储方式一样)
    • 通过名称和参数执行
      • 在数据库服务器端直接调用(DBA)
      • 供应用程序调用(软件开发工程师)

    类似于Java和C#语言中的方法

    • 可带参数,也可返回结果
    • 可包含数据操纵语句、变量、逻辑控制语句等

    存储过程的优点

    • 执行速度更快
    • 允许模块化程序设计
    • 提高系统安全性
    • 减少网络流通量
    • 视图和存储过程的重要优点:安全且执行速度快

    应用程序发送SQL的过程

    <传输语句> <语法检查> < 语句优化> <语句编译> <语句执行>

    应用程序调用存储过程或视图的过程

    <传输参数> <语句执行>

    存储过程的分类

    系统存储过程

    • 系统存储过程的名称一般以“sp_”开头。
    • 由SQLServer创建、管理和使用。
    • 存放在Master数据库中。
    • 目类似Java和C#语言类库中的方法。

    扩展存储过程

    • 扩展存储过程的名称通常以“xp_”开头。
    • 使用编程语言(如C#)创建的外部存储过程
    • 以DLL形式单独存在。

    用户自定义存储过程

    • 由用户在自己的数据库中创建的存储过程。
    • 类似C#语言中用户自定义的方法。

    调用存储过程

    调用存储讨程的语法

    EXECUTE 过程名[参数]
    
    EXEC 过程名[参数]

    如果执行存储过程的语句是批处理中的第一个语句,则可以不指定EXECUTE关键字

    常用的系统存储过程

    常用系统存储过程调用示例

     1 sp_databases
     2 
     3 EXEC  sp_renamedb 'ProductDB','pDB'
     4 
     5 USE StudentManager
     6 GO
     7 sp_tables
     8 
     9 EXEC sp_columns Students 
    10 
    11 EXEC sp_help Students 
    12 
    13 EXEC sp_helpconstraint Students
    14 
    15 EXEC sp_stored_procedures  
    View Code

    常用的系统存储过程

    系统存储过程 说明
    sp_databases 列出服务器上的所有数据库
    sp_helpdb 报告有关指定数据库或所有数据库的信息
    sp_renamedb 更改数据库的名称
    sp_tables 返回当前环境下可查询的对象的列表
    sp_columns 返回某个表列的信息
    sp_help 查看某个表的所有信息
    sp_helpconstraint 查看某个表的约束
    sp_helpindex 查看某个表的索引
    sp_stored_procedures 列出当前环境中的所有存储过程
    sp_password 添加或修改登录帐户的密码
    sp_helptext 显示默认值、未加密的存储过程、用户定义的存储过程、触发器或视图的实际文本

    常用扩展存储过程

    xp_cmdshell

    • 可以执行DOS命令下的一些的操作。
    • 以文本行方式返回任何输出。

     1 USE master
     2 GO
     3 EXEC xp_cmdshell 'mkdir D:\ProductDB', NO_OUTPUT
     4 IF EXISTS(SELECT * FROM sysdatabases  WHERE name='ProductDB')
     5    DROP DATABASE ProductDB
     6 GO
     7 --CREATE DATABASE ProductDB
     8 -- (
     9 --
    10 --)
    11 --GO
    12 EXEC xp_cmdshell 'dir D:\ProductDB\'   -- 查看文件
    View Code

    如何创建存储过程

    定义存储过程的语法

    存储过程的参数

    • 和C#语言的方法一样,参数可选。
    • 参数分为输入参数、输出参数。
    • 输入参数允许有默认值。

    创建、执行无参的存储过程

    创建存储过程usp_ScoreQuery

    • 查询考试成绩,显示:学号、姓名、班级、总成绩,并按成绩的总分高低排序。
    • 统计分析考试成绩,显示班级名称、C#平均分、数据库平均分,按照班级分组实现。

     代码编写分析

     1 use StudentManager
     2 go
     3 if exists(select * from sysobjects where name='usp_ScoreQuery')
     4 drop procedure usp_ScoreQuery
     5 go
     6 create procedure usp_ScoreQuery --创建存储过程
     7 as
     8     --查询考试信息
     9     select Students.StudentId,StudentName,ClassName,
    10               ScoreSum=(CSharp+SQLServerDB) from Students
    11     inner join StudentClass on StudentClass.ClassId=Students.ClassId
    12     inner join ScoreList on Students.StudentId=ScoreList.StudentId
    13     order by ScoreSum DESC
    14     --统计分析考试信息
    15     select StudentClass.ClassId,C#Avg=avg(CSharp),DBAvg=avg(SQLServerDB)  into #scoreTemp
    16     from StudentClass 
    17     inner join Students on StudentClass.ClassId=Students.ClassId
    18     inner join ScoreList on ScoreList.StudentId=Students.StudentId
    19     group by StudentClass.ClassId order by ClassId
    20     select ClassName,C#Avg,DBAvg from #scoreTemp
    21     inner join StudentClass on StudentClass.ClassId=#scoreTemp.ClassId
    22 go
    23 exec usp_ScoreQuery  --调用存储过程
    View Code

    存储过程参数

    存储过程的参数分两种:

    • 输入参数:向存储过程传入
    • 输出参数:调用存储过程后,传出执行结果

    带输入参数的存储过程

    查询考试成绩,要求能够按照自定义的及格线查询结果?

     1 use StudentManager
     2 go
     3 if exists(select * from sysobjects where name='usp_ScoreQuery2')
     4 drop procedure usp_ScoreQuery2
     5 go
     6 --创建带参数的存储过程
     7 create procedure usp_ScoreQuery2 
     8 @CSharp int,
     9 @DB int
    10 as
    11     select Students.StudentId,StudentName,C#=CSharp,DB=SQLServerDB
    12     from Students
    13     inner join ScoreList on Students.StudentId=ScoreList.StudentId
    14     where CSharp<@CSharp or SQLServerDB<@DB
    15 go
    16 --调用带参数的存储过程
    17 exec usp_ScoreQuery2 60,65 --按照参数顺序赋值
    18 exec usp_ScoreQuery2 @DB=65,@CSharp=60 --参数顺序可以调换
    View Code

    输入参数的默认值

    查询中,如果用户没有输入及格线参数,则默认60

     1 use StudentManager
     2 go
     3 if exists(select * from sysobjects where name='usp_ScoreQuery3')
     4 drop procedure usp_ScoreQuery3
     5 go
     6 --创建带参数的存储过程
     7 create procedure usp_ScoreQuery3 
     8 @CSharp int=60,
     9 @DB int=60
    10 as
    11     select Students.StudentId,StudentName,C#=CSharp,DB=SQLServerDB
    12     from Students
    13     inner join ScoreList on Students.StudentId=ScoreList.StudentId
    14     where CSharp<@CSharp or SQLServerDB<@DB
    15 go
    16 --调用带参数的存储过程
    17 exec usp_ScoreQuery3 65 --第二个参数没有赋值,则默认
    18 exec usp_ScoreQuery3 @DB=65
    19 exec usp_ScoreQuery3 default,65 --不使用显示方式赋值
    20 exec usp_ScoreQuery3   --两个参数都是用默认参数
    View Code

    创建带输出参数的存储过程

    问题:查询考试成绩,要求自定义分数线,显示查询列表,并输出缺考总人数、不及格总人数?

     1 use StudentManager
     2 go
     3 if exists(select * from sysobjects where name='usp_ScoreQuery4')
     4 drop procedure usp_ScoreQuery4
     5 go
     6 create procedure usp_ScoreQuery4 --创建带参数的存储过程
     7 @AbsentCount int output,--缺考总人数
     8 @FailedCount int output,--不及格总人数
     9 @CSharp int=60,
    10 @DB int=60
    11 as
    12     select Students.StudentId,StudentName,C#=CSharp,DB=SQLServerDB
    13      from Students
    14      inner join ScoreList on Students.StudentId=ScoreList.StudentId
    15      where CSharp<@CSharp or SQLServerDB<@DB        --显示结果列表 
    16     select @AbsentCount=count(*) from Students 
    17     where StudentId not in(select StudentId from ScoreList) --查询缺考总人数
    18     select @FailedCount=count(*) from ScoreList
    19      where CSharp<@CSharp or SQLServerDB<@DB      --查询不及格总人数
    20 go
    View Code

    调用带输出参数的存储过程

    输出参数在使用前要首先定义,调用时也要使用output

    1 use StudentManager
    2 go
    3 --调用带参数的存储过程
    4 declare @AbsentCount int,@FailedCount int --首先定义输出参数
    5 exec usp_ScoreQuery4 @AbsentCount output,@FailedCount output
    6 --使用反馈的结果
    7 select 缺考总数=@AbsentCount,不及格总数=@FailedCount
    View Code

    自定义存储过程

     1 use StudentManager
     2 go
     3 if exists(select * from sysobjects where name='usp_ScoreQuery')
     4 drop procedure usp_ScoreQuery
     5 go
     6 create procedure usp_ScoreQuery
     7 
     8 as
     9     --查询考试信息
    10     select Students.StudentId,StudentName,ClassName,ScoreSum=(SQLServerDB+CSharp) from Students
    11     inner join StudentClass on Students.ClassId=StudentClass.ClassId
    12     inner join ScoreList on Students.StudentId=ScoreList.StudentId
    13     order by ScoreSum DESC
    14     --统计分析考试信息
    15     select ClassName,C#Avg=AVG(CSharp),DBAvg=AVG(SQLServerDB) 
    16     from StudentClass
    17     inner join Students on StudentClass.ClassId=Students.ClassId
    18     inner join ScoreList on ScoreList.StudentId=Students.StudentId
    19     group by ClassName 
    20 go
    21 
    22 exec usp_ScoreQuery  --调用存储过程
    23 
    24 
    25 --if exists(select * from sysobjects where name='usp_ScoreQuery2')
    26 --drop procedure usp_ScoreQuery2
    27 --go
    28 --create procedure  usp_ScoreQuery2
    29 --@CSharp int,  --参数定义
    30 --@DB int
    31 --as
    32 --     select Students.StudentId,StudentName,C#=CSharp,  DB=SQLServerDB from Students
    33 --    inner join ScoreList on Students.StudentId=ScoreList.StudentId 
    34 --    where CSharp<@CSharp or SQLServerDB<@DB
    35 --go
    36 ----调用带参数的SQL语句
    37 --exec usp_ScoreQuery2 60,65  --按照参数顺序赋值
    38 --exec usp_ScoreQuery2 @DB=65,@CSharp=60
    39 
    40 
    41 if exists(select * from sysobjects where name='usp_ScoreQuery2')
    42 drop procedure usp_ScoreQuery2
    43 go
    44 create procedure  usp_ScoreQuery2
    45 @CSharp int=60, 
    46 @DB int=60
    47 as
    48      select Students.StudentId,StudentName,C#=CSharp,  DB=SQLServerDB from Students
    49     inner join ScoreList on Students.StudentId=ScoreList.StudentId 
    50     where CSharp<@CSharp or SQLServerDB<@DB
    51 go
    52 --调用带参数的SQL语句
    53 exec usp_ScoreQuery2 65
    54 exec usp_ScoreQuery2 @DB=65
    55 
    56 exec usp_ScoreQuery2 default,65
    57 exec usp_ScoreQuery2 
    58 
    59 
    60 if exists(select * from sysobjects where name='usp_ScoreQuery4')
    61 drop procedure usp_ScoreQuery4
    62 go
    63 create procedure  usp_ScoreQuery4
    64 @AbsentCount int output,--缺考总人数
    65 @FailedCount int output,--不及格总人数
    66 @CSharp int=60, 
    67 @DB int=60
    68 as
    69      select Students.StudentId,StudentName,C#=CSharp,  DB=SQLServerDB from Students
    70     inner join ScoreList on Students.StudentId=ScoreList.StudentId 
    71     where CSharp<@CSharp or SQLServerDB<@DB
    72     
    73     select @AbsentCount=COUNT(*) from Students 
    74     where StudentId not in(Select StudentId from ScoreList)
    75     select @FailedCount=COUNT(*) from ScoreList
    76     where CSharp<@CSharp or SQLServerDB<@DB
    77 go
    78 --调用带输出参数的存储过程
    79 declare @AbsentCount int,@FailedCount int --首先定义输出参数
    80 exec usp_ScoreQuery4 @AbsentCount output,@FailedCount output
    81 --读取输出参数
    82 select 缺考总数=@AbsentCount,不及格总数=@FailedCount
    View Code

    END

  • 相关阅读:
    批量备份mysql数据库(shell编程)
    批量检查多个网址是否正常(shell编程)
    就linux三剑客简单归纳
    sql语句浅谈以及mysql遇到的问题解决见解
    linux shell每天一阅 -- 安装nginx以及apache
    Linux文件系统检查错误
    Linux账号管理和ACL
    简书博客
    Block内的强引用
    一次没有意义的优化
  • 原文地址:https://www.cnblogs.com/zeon/p/16324486.html
Copyright © 2020-2023  润新知