zoukankan      html  css  js  c++  java
  • SQLSERVER(三)

    1.SQLServer登录

      1.1SQlServer三层安全管理机制

        包括登录名、数据库、操作数据库权限

        一个登录名对应多个数据库用户,属于一对多;一个数据库用户对应一个数据库,属于一对一

      1.2登录名(登陆账户)

        用以登录SQL Server数据库服务器;一个数据库服务器可能有若干个数据库

      1.3数据库用户

        用于访问指定的数据库。登陆成功后,根据登录名找到对应的数据库用户,再去访问某个具体的用户数据库。找到该数据库用户对应的权限,操作数据库

    2.添加登陆账户

      登录账户sa是超级管理员账户,拥有数据库管理的最高权限,可以管理所有的数据库,安装时自动创建

    1 use master
    2 go
    3 exec sp_addlogin 'YangSan','1001'
    4 --账户名是“YangSan”,密码是“1001”,中间用逗号隔开
    添加SQLServer账户

     3.向数据库用户授权

      3.1授权的语法

        grant 权限[on 表名] to 数据库用户    

      3.2收回权限的语法

        remoke 权限[on 表名] to 数据库用户

    4.变量分类

      局部变量:仅在过程中使用

        局部变量必须以标记@作为前缀,如@age

        局部变量的使用也是先声明(使用declare),再赋值

      全局变量:任何时候均可以使用

        全部变量必须以标记@@作为前缀,如@@version(查询版本)

        全局变量由系统定义和维护,我们只能读取,不能修改全局变量

    5.局部变量定义与赋值

      局部变量的定义语法:declare @变量名 数据类型

      赋值方法: set @变量名=值    或   select @变量名=值 (使用select赋值要确保筛选出的记录只有一条)

     1 use SMDB
     2 go
     3 --声明变量
     4 declare @stuName varchar(20),@stuId int
     5 --赋值变量
     6 set @stuName='李铭'
     7 select @stuId=StudentId from Students where Studentname=@stuName
     8 --事先查询下李铭的信息
     9 select StudentName,StudentId,Gender from Students where StudentName=@stuName
    10 
    11 --查询李铭学号前后学员的信息
    12 select StudentName,StudentId,Gender from Students 
    13 where StudentId=(@stuId-1) or StudentId=@stuId or StudentId=(@stuId+1)
    14 order by StudentId DESC
    15 
    16 select StudentId,StudentName from Students
    17 where StudentId in (@stuId-1,@stuId,@stuId+1)
    18 
    19 select @@servername as '服务器名称'
    变量的简单使用

    6.set与select比较

    使用场景 set select
    同时对多个变量赋值 不支持 支持
    表达式返回多个值时 出错 将返回的最后一个值赋给变量
    表达式未返回值时   变量被赋NULL值 变量保持原值

      就赋值而言,set能做的select都能做。查询尽量多用select

     1 declare @stuAddress nvarchar(100),@stuName nvarchar(100)
     2 --set @stuAddress='昆山',@stuName='张三' --不允许这样赋值
     3 select @stuAddress='昆山',@stuName='张三'  --允许
     4 
     5 --set @stuAddress = (select StudentAddress from Students) --不允许
     6 select @stuAddress = StudentAddress from Students --得到最后一个
     7 --set @stuAddress = (select StudentAddress from Students where 1<0) --Null值
     8 select @stuAddress = StudentAddress from Students where 1<0 --保持原值
     9 
    10 select @stuAddress as '地址',@stuName as '姓名'
    set与select的使用

    7.全局变量的使用

    变量   含义
    @@ERROR 最后一个T—SQL错误的错误号
    @@IDENTITY 最后一次插入的标识值
    @@LANGUAGE 当前使用的语言的名称
    @@MAX_CONNECTIONS 可以创建的同时连接的最大数目
    @@ROWCOUNT 受上一个SQL语句影响的行数
    @@SERVERNAME 本地服务器的名称
    @@TRANSCOUNT 当前连接打开的事务数
    @@VERSION SWL Server的版本信息

    8.错误号的使用

      @@error 全局变量保留错误号

    use SMDB 
    go
    select * from StudentClass
    --插入一条学员信息,但班级为10,当前没有此班级
    --会引发外键冲突
    insert into Students(StudentName,Gender,Age,Birthday,StudentIdNo,CardNo,PhoneNumber,STudentAddress,ClassId)
    values('王小欣','',24,'1992-9-9',42109876543456,2011129876,'0512-88765678','昆山',10)
    
    print @@error
    @@error的使用
     1             //删除一名学生,但成绩表还有改学生信息,是不能被删除的
     2             string sql = "delete from Students where StudentId=" + studentId;
     3             try
     4             {
     5                 return SQLHelper.Update(sql);
     6             }
     7             catch (SqlException ex)
     8             {
     9                 if (ex.Number == 547)
    10                     throw new Exception("该学号被其他实体引用,不能直接删除该学员对象!");
    11                 else
    12                     throw new Exception("数据库操作出现异常!具体信息:
    " + ex.Message);
    13             }
    14             catch (Exception ex)
    15             {
    16                 throw ex;
    17             }
    18     
    @@error在C#中的应用

     9.数据类型转换

      convert(数据类型,表达式,样式)

        第三个参数可以省略,它一般用于日期类型转换为字符来行,或浮点类型数据转换为字符类型

      cast(表达式 as 数据类型)

     数据类型转换及日期函数

    10.if_else语句

     1 --SQL中的if语句
     2 if(条件)
     3     begin
     4         语句1
     5         语句2
     6         ......
     7     END
     8 else
     9     begin
    10         语句1
    11         语句2
    12         ......
    13     end
    14 
    15 --注:else是可选部分
    16 --如果有多条语句,才需要begin-end语句块,相当于c#中的{ }
    if_else语句
     1 use SMDB 
     2 go
     3 declare @avg int
     4 select @avg=avg(CSharp) from ScoreList 
     5 inner join Students on Students.StudentId=ScoreList.StudentId
     6 where Students.ClassId=1
     7 print 'CSharp平均分:'+convert(varchar(20),@avg)
     8 --执行判断
     9 if(@avg>=80)
    10     print '成绩合格'
    11 else
    12     print '成绩不合格'
    eg

    11.while语句

     1 --SQL中的while语句
     2 while(条件)
     3     begin
     4         语句1
     5         语句2
     6         ......
     7         break
     8     end
     9 --break表示跳出循环
    10 --如果有多条语句,才需要begin-end语句块
    while语句

    12.case_end语句

    1 case
    2     when 条件1 then 结果1
    3     when 条件2 then 结果2
    4     ......
    5     else 其他结果
    6 end
    7 --else表示case中所有when条件均不为then是返回的结果,相当于C#中的default
    8 --如果省略else且when条件都为false时,case语句返回null
    case_end语句
     1 use SMDB 
     2 go
     3 select 学号=Students.StudentId,姓名=Studentname,C#成绩=CSharp,
     4        等级=case
     5                 when CSharp>=90 then 'A'
     6                 when CSharp between 80 and 89 then 'B'
     7                 when CSharp between 70 and 79 then 'C'
     8                 when CSharp between 60 and 69 then 'D'
     9                 else '不及格'
    10             end
    11 from ScoreList inner join Students on ScoreList.StudentId=Students.StudentId
    eg

     13.子查询

      语法规范:子查询(总是用括号括起来)

        select ... from 表1 where 字段1 比较运算符(子查询)

      子查询注意:

        将子查询与比较运算符联合使用,必须保证子查询返回的值不能多于1个

        子查询是一个嵌套在select、insert、update、update或delete语句或其他子查询中的查询

      理解子查询执行过程:

        首先,执行小括号中的子查询,返回的结果是所有子查询的结果

        其次,才开始执行外围的父查询,返回查询的最终结果

     1 use SMDB
     2 go
     3 --查询学号在赵小金后面的学员信息
     4 
     5 --方法一:定义变量,可读性好
     6 declare @stuId int
     7 select @stuId=StudentId from Students where Studentname='赵小金'
     8 select StudentId,Studentname from Students where StudentId>@stuId
     9 
    10 --父查询中嵌套子查询
    11 select StudentId,Studentname from Students 
    12 where StudentId>(select StudentId from STudents where Studentname='赵小金')
    子查询

    14.in子查询(范围查询 in 后面类似数组)

      in后面的子查询可以返回多条记录

      常用in替换等于=的比较子查询 

      not in 表示不在此范围

     1 use SMDB
     2 go
     3 select Students.StudentId,StudentName from Students
     4 inner join ScoreList on ScoreList.StudentId=Students.StudentId
     5 where SQLServerDB>80
     6 
     7 select StudentId,StudentName from Students
     8 where StudentId in (select StudentId from ScoreList where SQLServerDB>80)
     9 
    10 --查询没有参加考试的学员
    11 select StudentId,Studentname from Students
    12 where StudentId not in(select StudentId from ScoreList)
    in

    15.exists子查询(判断是否存在)

      if exists (子查询)

         语句

      查询结果非空,记录数1条以上,则exists子查询返回真,否则返回假

      not exists 不存在

    1 use master
    2 go
    3 if exists(select * from sysdatabases where name='SMDB')
    4 print '数据库已存在'
    5 
    6 use SMDB
    7 go
    8 if    exists(select * from sysobjects where name='Students')
    9 print '数据表已存在'
    exists

     16.视图

      视图的概念:

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

       视图中不存放数据:数据存放在视图所引用的原始表中

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

      视图的用途:

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

       视图可以手动创建,简单快捷,引用查询视图像引用表一样简单快捷

      select * from V_Stu 

    17.创建和使用视图

    create view view_StuInfo
        as
        <select 语句>
    T-SQL语句创建视图规范
    if exists(select * from sysobjects where name=view_StuInfo)
        drop view view_StuInfo
    T-SQL语句删除视图规范
    select * from view_StuInfo
    T-SQL语句查看视图规范
     1 use SMDB
     2 go
     3 --判断视图是否存在
     4 if exists(select * from sysobjects where name='V_StuScore')
     5 drop view V_StuScore
     6 go
     7 --创建视图
     8 create view V_StuScore
     9 as
    10     select top 100 ID=Students.StudentId,姓名=StudentName,班级=ClassName,C#=CSharp,
    11     SQL=SQLServerDB,总分=(CSharp+SQLServerDB) from Students 
    12     inner join ScoreList on Students.StudentId=ScoreList.StudentId
    13     inner join StudentClass on StudentClass.ClassId=Students.ClassId
    14     order by 总分 DESC
    15 go
    16 
    17 select * from V_StuScore order by ID asc
    创建与引用视图实例

    18.视图中select语句不能包括下列内容(视图相对于存储过程的不足)

    1. order by子句,除非在select语句得选择列表中有top子句
    2. into子句
    3. 引用临时表或变量:视图只能查询,不能增删改,视图仅表示一种查询的逻辑关系,视图内不包括实体数据

    19.存储过程

      概念:

      1. 预先存储好的SQL程序
      2. 保存在SQL Server中(跟视图一样)
      3. 通过名称和参数执行:可以在数据库服务器端直接调用(DBA)、供应用程序调用可带参数、可返回结果
      4. 可以包含数据操纵语句(单个select语句或select语句块)、变量、逻辑控制语句等

      优点:

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

      SQL语句和存储过程的比较:

      1. 应用程序发送SQL的过程:  传输语句——>>>语法检查——>>>语法优化——>>>语句编译——>>>语法执行
      2. 调用存储过程或视图过程:  传输参数——>>>语句执行

      存储过程分类:

      1. 系统存储过程:以“sp_”开头,由SQL Server创建、管理和使用,存放在master数据库中,类似于C#语言类库中的方法
      2. 扩展存储过程:以“xp_”开头,使用编程语言(C#)创建的外部存储过程,以DLL形式单独存在  xp_cmdshell:可以执行DOS命令下的一些操作,以文本方式返回任何输出
      3. 用户自定义存储过程:由用户在自己的数据库中创建的存储过程,类似于C#中程序员自定义的方法
    系统存储过程   说明
    sp_databases 列出数据库上的所有数据库
    sp_helpdb 报告有关指定数据库或所有数据库的信息
    sp_renamedb 更改数据库的名称
    sp_tables 返回当前环境下可查询的对象的列表
    sp_columns 返回某个表列的信息
    sp_help 查看某个表的所有信息
    sp_helpconstraint 查看某个表的约束
    sp_helpindex 查看某个表的索引
    sp_stored_procedures 列出当前环境中的所有存储过程
    sp_password 添加或修改登录账户的密码
    sp_helptext 显示默认值、未加密的存储过程、用户定义的存储过程、触发器或视图的实际文本

      调用存储过程:exec 过程名 [参数]

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

    20.无参数存储过程

    1 create proc[EDURE] 存储过程名
    2     @参数1 数据类型=默认值 output,
    3     ......
    4     @参数n 数据类型=默认值 output
    5 as
    6     SQL语句
    7 go
    定义存储过程的语法

      参数:参数可选、分输入输出、输入参数允许有默认值

     1 use SMDB
     2 go
     3 if exists(select * from sysobjects where name='usp_QueryScore')
     4 drop proc usp_QueryScore
     5 go
     6 create proc usp_QueryScore
     7 as
     8     select ID=Students.StudentId,姓名=StudentName,班级=ClassName,C#=CSharp,SQL=SQLServerDB,
     9         总分=(CSHarp+SQLServerDB) from Students
    10         inner join StudentClass on StudentClass.ClassId=Students.ClassId
    11         inner join ScoreList on ScoreList.StudentId=Students.StudentId
    12         order by 总分 DESC
    13 
    14     select 班级=ClassName,C#平均分=AVG(CSharp),SQL平均分=AVG(SQLServerDB)
    15     from Students
    16     inner join StudentClass on StudentClass.ClassId=Students.ClassId
    17     inner join ScoreList on ScoreList.StudentId=Students.StudentId
    18     group by ClassName order by ClassName
    19     --group by排序的内容必须出现在select之后才可以被引用
    20 
    21     select StudentClass.ClassId,C#平均分=AVG(CSharp),SQL平均分=AVG(SQLServerDB)
    22     from Students
    23     inner join StudentClass on StudentClass.ClassId=Students.ClassId
    24     inner join ScoreList on ScoreList.StudentId=Students.StudentId
    25     group by StudentClass.ClassId order by StudentClass.ClassId
    26 
    27     select StudentClass.ClassId,C#平均分=AVG(CSharp),SQL平均分=AVG(SQLServerDB)
    28     into #ScoreTemp
    29     from Students
    30     inner join StudentClass on StudentClass.ClassId=Students.ClassId
    31     inner join ScoreList on ScoreList.StudentId=Students.StudentId
    32     group by StudentClass.ClassId order by StudentClass.ClassId
    33     --将临时表和班级表关联查询
    34     select ClassName,C#平均分,SQL平均分 from #ScoreTemp
    35     inner join  StudentClass on StudentClass.ClassId=#ScoreTemp.ClassId
    36 go
    37 
    38 exec usp_QueryScore
    创建无参数存储过程&&分组排序&&临时表

     21.带输入参数存储过程

     1 use SMDB
     2 go
     3 if exists(select * from sysobjects where name='usp_QueryScore')
     4 drop procedure usp_QueryScore
     5 go 
     6 --创建带参数的存储过程
     7 create proc usp_QueryScore
     8 @CSharp_Min int=60,     --默认参数输入
     9 @CSharp_Max int=80
    10 as
    11     select Students.StudentId,StudentName,CSharp,SQLServerDB 
    12     from Students
    13     inner join ScoreList on Students.StudentId=ScoreList.StudentId
    14     where CSharp>@CSharp_Min and CSharp<@CSharp_Max
    15 go
    16 
    17 select * from ScoreList
    18 --调用带参数的存储过程
    19 exec usp_QueryScore 65,85                             --默认要和定义的参数一一对应
    20 exec usp_QueryScore @CSharp_Max=80,@CSharp_Min=60     --也可以不一一对应但要声明参数名称
    21 exec usp_QueryScore                    --两个参数都是用默认参数
    22 exec usp_QueryScore 65                --只写一个参数,@CSharp_Min=65,C@Sharp_Max默认
    23 exec usp_QueryScore dsefault,90        --第一个参数默认,@CSharp_Max为90
    24 exec usp_QueryScore @CSharp_Min=70  --第一个参数为70,第二个参数默认
    带输入参数存储过程、默认输入及调用方式

    22.带输入输出存储过程

     1 use SMDB
     2 go
     3 if exists(select * from sysobjects where name='usp_QueryScore')
     4 drop procedure usp_QueryScore
     5 go 
     6 --创建带参数的存储过程
     7 create proc usp_QueryScore
     8 @AbsentCount int output,  --缺考总人数
     9 @FailedCount int output,  --不及格总人数
    10 @CSharp_Min int=60,     --默认参数输入
    11 @CSharp_Max int=80
    12 as
    13     select Students.StudentId,StudentName,CSharp,SQLServerDB 
    14     from Students
    15     inner join ScoreList on Students.StudentId=ScoreList.StudentId
    16     where CSharp>@CSharp_Min and CSharp<@CSharp_Max
    17     --输出参数要在SQL语句中赋值
    18     select @AbsentCount=count(*) from Students        --查询缺考总人数
    19         where StudentId not in (select StudentId from ScoreList)
    20     select @FailedCount=count(*) from ScoreList where CSharp<@CSharp_Min --查询不及格总人数
    21 go
    22 
    23 --调用带输出参数的存储过程
    24 declare @Absent int,@Failed int  --首先定义输出参数
    25 exec usp_QueryScore @Absent output,@Failed output,@CSharp_Min=70,@CSharp_Max=99
    26 select 缺考总人数=@Absent,不及格总数=@Failed
    带输入输出存储过程

     23.事务

      23.1事务的概念:

    1. 事务是作为单个逻辑工作单元执行的一系列操作
    2. 多个操作作为一个整体向系统提交,要么都执行、要么都不执行
    3. 事务是一个不可分割的工作逻辑单元
    4. 通俗讲,如果一个事务中包括两条语句,如果第一条语句执行成功,第二条语句执行失败,会重新撤销第一条语句所执行的结果

        23.2事务的四个属性

    1. 原子性:事务是一个完成的操作,事务的各部操作是不可分的,要么都执行,要么都不执行
    2. 一致性:当事务完成时,数据必须都处于一致状态
    3. 隔离性:并发事务之间彼此隔离、独立,它不应以任何方式依赖于或影响其他事务
    4. 永久性:事务完成后,它对数据库的修改被永久保存

      23.3事务分类

    1. 显式事务:用begin transaction明确指定事务的开始,是最常用的事务类型
    2. 隐式事务:通过设置set implicit_transactions on语句,将隐性事务模式设置为打开;其后的T-SQL语句自动启动一个新事务,提交或回滚一个事务后,下一个T-SQL语句又将启动一个新事务
    3. 自动提交事务:SQL Server的默认模式,每条单独的T-SQL语句视为一个事务 

      23.4使用SQL语句管理事务的基本步骤

    1. 开始事务:begin transaction
    2. 提交事务:commit transaction
    3. 回滚(撤销)事务:rollback transaction
    4. 一旦事务提交或回滚,则事务结束
    5. 事务处理中的关键问题主要是对insert、update、delete语句实时跟踪
     1 use StudentManager
     2 go
     3 select * from CardAccount
     4 go
     5 declare @errorSum int  --定义变量,用于累计事务执行中的错误
     6 set @errorSum=0   --初始化为0,代表没有错误
     7 begin transaction
     8     begin
     9         --转出
    10         update CardAccount set CurrentMoney=CurrentMoney-1000 where StudentId=100001
    11         set @errorSum=@errorSum+@@ERROR
    12         --转入
    13         update CardAccount set CurrentMoney=CurrentMoney+1000 where StudentId=100002
    14         set @errorSum=@errorSum+@@ERROR
    15         if(@errorSum=0)
    16             commit transaction
    17         else
    18             rollback transaction
    19     end
    20 go
    21 select * from CardAccount
    22 go
    事务

      23.5判断某条语句执行是否出错的方法

    1. 使用全局变量@@ERROR
    2. @@ERROR只判断当前一条T-SQL语句执行是否有错
    3. 为了判断事务中所有T-SQL语句是否有错,可以对错误进行累计
    4. set @errorSum=@errorSum+@@error
     1 use StudentManager
     2 go
     3 if exists(select * from sysobjects where name='usp_TransferAccounts')
     4 drop proc usp_TransferAccounts
     5 go
     6 create proc usp_TransferAccounts
     7 @intputAccount int,  --转入账户
     8 @outputAccount int,  --转出账户
     9 @transferMoney int --交易金额
    10 as
    11     declare @errorSum int  --定义变量,用于累计事务执行中的错误
    12     set @errorSum=0   --初始化为0,代表没有错误
    13     begin transaction
    14         begin
    15             --转出
    16             update CardAccount set CurrentMoney=CurrentMoney-@transferMoney 
    17                 where StudentId=@outputAccount
    18             set @errorSum=@errorSum+@@ERROR
    19             --转入
    20             update CardAccount set CurrentMoney=CurrentMoney+@transferMoney 
    21                 where StudentId=@intputAccount
    22             set @errorSum=@errorSum+@@ERROR
    23             if(@errorSum=0)
    24                 commit transaction
    25             else
    26                 rollback transaction
    27         end
    28 go
    29 --测试成功的转换
    30 select * from CardAccount 
    31 exec usp_TransferAccounts 100002,100001,100
    32 select * from CardAccount
    33 --测试失败的转换
    34 exec usp_TransferAccounts 100002,100001,1000
    35 select * from CardAccount
    将事务引用在存储过程中

     24.索引

      添加的索引越多,占用的存储空间越多。每插入、删除、修改一条记录,数据库有可能会更改很多。

      24.1分类

        聚集索引:表中各行的物理顺序与键值的逻辑(索引)顺序相同,每个表只能有一个

      1. 主键索引:为表定义一个主键将自动创建主键索引,主键索引是唯一索引的特殊类型
      2. 主键索引要求主键中的每一值是唯一的,并且不能为空

        非聚集索引(nonclustered index ):非聚集索引指定表的逻辑顺序

      1. 数据可以存储在一个位置,索引存储在另一个位置,索引中包含指向数据存储位置的指针
      2. 可以有多个,小于249
      3. 唯一索引:唯一索引不允许两行具有相同的索引值

     25.在ADO.NET中添加事务

            public static int UpdateByTran(List<string> sqlList)
            {
                SqlConnection conn = new SqlConnection(ConnStr);
                SqlCommand cmd = new SqlCommand();
                cmd.Connection = conn;
                try
                {
                    conn.Open();
                    cmd.Transaction = conn.BeginTransaction();//开启事务
                    int result = 0;
                    foreach (string sql in sqlList)
                    {
                        cmd.CommandText = sql;
                        result += cmd.ExecuteNonQuery();//执行sql语句
                    }
                    cmd.Transaction.Commit();//提交事务
                    return result;
                }
                catch (Exception ex)
                {
                    //写入日志
                    if (cmd.Transaction != null)
                    {
                        cmd.Transaction.Rollback();//回滚事务
                    }
                    throw new Exception("调用事务更新方法时出现异常:" + ex.Message);
                }
                finally
                {
                    if (cmd.Transaction!=null)
                    {
                        cmd.Transaction = null;
                    }
                    conn.Close();
                }
            }
    C#中事务的使用
    using System;
    using System.Collections.Generic;
    using System.Data;
    using System.Data.SqlClient;
    namespace DAL
    {
        class SQLHelper
        {
            private static string ConnStr = "Server=.;DataBase=StudentManageDB;Uid=sa;Pwd=****";
    
            /// <summary>
            /// 返回单一结果查询
            /// </summary>
            /// <param name="sql"></param>
            /// <returns></returns>
            public static object GetSignalResult(string sql)
            {
                SqlConnection conn = new SqlConnection(ConnStr);
                SqlCommand cmd = new SqlCommand(sql,conn);
                conn.Open();
                object re = cmd.ExecuteScalar();
                conn.Close();
                return re;
            }
    
            /// <summary>
            /// 更新数据操作(删、增、改)
            /// </summary>
            /// <param name="sql"></param>
            /// <returns></returns>
            public static int GetUpdate(string sql)
            {
                SqlConnection conn = new SqlConnection(ConnStr);
                SqlCommand cmd = new SqlCommand(sql,conn);
                conn.Open();
                int re = cmd.ExecuteNonQuery();
                conn.Close();
                return re;
            }
    
            /// <summary>
            /// 返回一个结果集的查询
            /// </summary>
            /// <param name="sql"></param>
            /// <returns></returns>
            public static SqlDataReader GerReader(string sql)
            {
                SqlConnection conn = new SqlConnection(ConnStr);
                SqlCommand cmd = new SqlCommand(sql, conn);
                conn.Open();
                return cmd.ExecuteReader(CommandBehavior.CloseConnection);
            }
    
            /// <summary>
            /// 多条sql语句事务的应用
            /// </summary>
            /// <param name="sqlList">多条sql语句</param>
            /// <returns></returns>
            public static int UpdateByTran(List<string> sqlList)
            {
                SqlConnection conn = new SqlConnection(ConnStr);
                SqlCommand cmd = new SqlCommand();
                cmd.Connection = conn;
                try
                {
                    conn.Open();
                    cmd.Transaction = conn.BeginTransaction();//开启事务
                    int result = 0;
                    foreach (string sql in sqlList)
                    {
                        cmd.CommandText = sql;
                        result += cmd.ExecuteNonQuery();//执行sql语句
                    }
                    cmd.Transaction.Commit();//提交事务
                    return result;
                }
                catch (Exception ex)
                {
                    //写入日志
                    if (cmd.Transaction != null)
                    {
                        cmd.Transaction.Rollback();//回滚事务
                    }
                    throw new Exception("调用事务更新方法时出现异常:" + ex.Message);
                }
                finally
                {
                    if (cmd.Transaction!=null)
                    {
                        cmd.Transaction = null;
                    }
                    conn.Close();
                }
            }
        }
    }
    SqlHelper_连接字符串直接写在类中
            public DataTable ExecuteDataTable1(string conStr, string sql, CommandType type, params SqlParameter[] param)
            {
                DataTable dt = new DataTable();
                using (SqlConnection con = new SqlConnection(conStr))
                {
                    using (SqlCommand command = new SqlCommand())
                    {
                        using (SqlDataAdapter adapter = new SqlDataAdapter(sql, con))
                        {
                            command.Connection = con;
                            command.CommandType = type;
                            command.CommandText = sql;
                            if (!(param == null || param.Length == 0))
                            {
                                foreach (SqlParameter parm in param)
                                {
                                    command.Parameters.Add(parm);
                                }
                            }
                            //添加参数
                            adapter.SelectCommand = command;
                            //1.打开链接,如果连接没有打开,则它给你打开;如果打开,就算了
                            //2.去执行sql语句,读取数据库
                            //3.sqlDataReader,把读取到的数据填充到内存表中
                            adapter.Fill(dt);
                        }
                    }
                }
                return dt;
            }
    sql语句或存储过程返回DataTable

    26.清空数据库日志

        --MES_DB_Utility修改为自己想要操作的数据库
        --MES_DB_IO_log修改为自己想要操作的数据库日志文件
        USE [master]
        GO
        ALTER DATABASE MES_DB_Utility SET RECOVERY SIMPLE WITH NO_WAIT
        GO
        ALTER DATABASE MES_DB_Utility SET RECOVERY SIMPLE   --简单模式
        GO
        USE MES_DB_Utility
        GO
        DBCC SHRINKFILE (N'MES_DB_IO_log' , 0, TRUNCATEONLY)  --设置压缩后的日志大小为2M,可以自行指定
        GO
        USE [master]
        GO
        ALTER DATABASE MES_DB_Utility SET RECOVERY FULL WITH NO_WAIT
        GO
        ALTER DATABASE MES_DB_Utility SET RECOVERY FULL  --还原为完全模式
        GO 
    清空数据库日志

     27.ADO.NET命令执行方式比较

    1. 使用完整的SQL语句:Sql语句编写困难、容易出错;网络传输不安全,很容易发生“注入式攻击”;执行效率低
    2. 使用带参数的SQL语句:Sql语句编写容易,网络传输安全,执行效率一般
    3. 调用存储过程:不需要编写SQL语句,网络传输非常安全,执行效率非常高

    28.一般SQL语句与带参数的SQL语句

     1         public static int InsertStudent(Student objStu)
     2         {
     3             string sql = $@"insert into Students (StudentName,Gender,Birthday,StudentIdNo,Age,PhoneNumber,StudentAddress,ClassId)values 
     4                       ('{objStu.StudentName}','{objStu.Gender}','{objStu.Birthday}',{objStu.StudentIdNo},{objStu.Age},'{objStu.PhoneNumber}','{objStu.StudentAddress}',{objStu.ClassId})";
     5             return SQLHelper.GetUpdate(sql);
     6         }
     7 
     8         public static int GetUpdate(string sql,params SqlParameter[] paras)
     9         {
    10             SqlConnection conn = new SqlConnection(ConnStr);
    11             SqlCommand cmd = new SqlCommand(sql,conn);
    12             try
    13             {
    14                 if (paras.Length > 0)
    15                 {
    16                     cmd.Parameters.AddRange(paras);
    17                 }
    18                 conn.Open();
    19                 int re = cmd.ExecuteNonQuery();
    20                 conn.Close();
    21                 return re;
    22             }
    23             catch (Exception ex)
    24             {
    25                 return -1;
    26             }
    27         }
    一般SQL语句
     1         public static int InsertStudent_Paras(Student objStu)
     2         {
     3             string sql = "insert into Students (StudentName,Gender,Birthday,StudentIdNo,Age,PhoneNumber,StudentAddress,ClassId)values"; 
     4             sql+=" (@StudentName,@Gender,@Birthday,@StudentIdNo,@Age,@PhoneNumber,@StudentAddress,@ClassId)";
     5             SqlParameter[] paras = new SqlParameter[] {
     6                 new SqlParameter("@Studentname",objStu.StudentName),
     7                 new SqlParameter("@Gender",objStu.Gender),
     8                 new SqlParameter("@Birthday",objStu.Birthday),
     9                 new SqlParameter("@StudentIdNo",objStu.StudentIdNo),
    10                 new SqlParameter("@Age",objStu.Age),
    11                 new SqlParameter("@PhoneNumber",objStu.PhoneNumber),
    12                 new SqlParameter("@StudentAddress",objStu.StudentAddress),
    13                 new SqlParameter("@ClassId",objStu.ClassId)
    14             };
    15             return SQLHelper.GetUpdate(sql, paras);
    16         }
    17 
    18         public static int GetUpdate(string sql,params SqlParameter[] paras)
    19         {
    20             SqlConnection conn = new SqlConnection(ConnStr);
    21             SqlCommand cmd = new SqlCommand(sql,conn);
    22             try
    23             {
    24                 if (paras.Length > 0)
    25                 {
    26                     cmd.Parameters.AddRange(paras);
    27                 }
    28                 conn.Open();
    29                 int re = cmd.ExecuteNonQuery();
    30                 conn.Close();
    31                 return re;
    32             }
    33             catch (Exception ex)
    34             {
    35                 return -1;
    36             }
    37         }
    带参数的SQL语句

     29.ADO.NET调用存储过程

    1. 先在服务器端编写需要的存储过程,如果有参数,需要@定义好参数
    2. 编写调用存储过程的通用数据访问方法。注意cmd.CommandType=CommandType.StoredProcedure;  //声明是存储过程cmd.CommandText=text;  //指定存储过程的名称cmd.Parameters.AddRange(paras);  //添加输入参数
    3. 编写调用存储过程的方法
     1         /// <summary>
     2         /// 调用存储过程返回结果集(可以是多条结果集)
     3         /// </summary>
     4         /// <param name="procedureName">存储过程名</param>
     5         /// <param name="paras">参数</param>
     6         /// <returns></returns>
     7         public static SqlDataReader GetReader(string procedureName, SqlParameter[] paras)
     8         {
     9             SqlConnection conn = new SqlConnection();
    10             SqlCommand cmd = new SqlCommand();
    11             try
    12             {
    13                 conn.Open();
    14                 cmd.Connection = conn;
    15                 cmd.CommandType = CommandType.StoredProcedure;
    16                 cmd.CommandText = procedureName;
    17                 cmd.Parameters.AddRange(paras);
    18                 return cmd.ExecuteReader(CommandBehavior.CloseConnection);
    19             }
    20             catch (Exception ex)
    21             {
    22                 conn.Close();
    23                 throw ex;
    24             }
    25         }
    调用存储过程返回结果集(可以是多条结果集)
     1         //执行存储过程(多个返回值与多个返回列表)
     2         public List<StudentExt> GetScoreInfo(string className, out Dictionary<string, string> dicParam, out List<string> absentList)
     3         {
     4             //定义输入参数,参数名+参数值
     5             SqlParameter inputClassName = new SqlParameter("@classname",className);
     6             inputClassName.Direction = ParameterDirection.Input;
     7             //定义输出参数,参数名+参数类型
     8             SqlParameter outStuCount = new SqlParameter("@stuCount", SqlDbType.Int);
     9             outStuCount.Direction = ParameterDirection.Output;
    10             SqlParameter outAvgDB = new SqlParameter("@avgDB",SqlDbType.Int);
    11             outAvgDB.Direction = ParameterDirection.Output;
    12             //执行查询
    13             SqlParameter[] paras = new SqlParameter[] { inputClassName,outAvgDB};
    14             SqlDataReader objReader = SQLHelper.GetReader("usp_ScoreQuery",paras);
    15             //读取考试成绩列表
    16             List<StudentExt> scoreList = new List<StudentExt>();
    17             while (objReader.Read())
    18             {
    19                 scoreList.Add(new StudentExt()
    20                 {
    21                     StudentId=objReader["StudentId"].ToString(),
    22                     Age=Convert.ToInt32(objReader["Age"])
    23                 });
    24             }
    25             //读取缺考人员列表
    26             absentList = new List<string>();
    27             if (objReader.NextResult())
    28             {
    29                 while (objReader.Read())
    30                 {
    31                     absentList.Add(objReader["StudentName"].ToString());
    32                 }
    33             }
    34             objReader.Close();
    35             //当执行完后,输出参数自动的已经赋值啦
    36             //获取输出参数
    37             dicParam = new Dictionary<string, string>();
    38             dicParam["StuCount"] = outStuCount.Value.ToString();
    39             dicParam["AvgDB"] = outAvgDB.Value.ToString();
    40             return scoreList;
    41         }
    执行存储过程(多个返回值与多个返回列表)

     30.SQLHelper类中方法的总结

    1. 执行格式化的SQL语句(使用占位符)
    2. 执行带参数的SQL语句(类似存储过程参数,效率和安全性较高)
    3. 执行带参数的存储过程(效率最高,安全性最高)
    4. 启动事务执行更新(保证数据的一致性)
    5. 项目开发中应按照以上分类编写SQLHelper类中的方法,并在适时场合调用不同的的方法
  • 相关阅读:
    Lucene实践之IndexFile
    java利用pdfbox处理pdf
    java通过dom4j处理xml文档
    CouchBase 2.5Kb数据无法编辑的解决办法
    Strutes2标签url
    Strutes2标签iterator
    2.23Java基础总结 ①内存图,内存加载过程②内存叠加③动态绑定
    2.23 Java基础总结 ①toString方法②equals③this和super④final⑤常量
    数学趣题——魔幻方阵
    数学趣题——谁在说谎
  • 原文地址:https://www.cnblogs.com/yangmengke2018/p/11667432.html
Copyright © 2011-2022 走看看