SqlServer初级学习笔记

1、structured Query Language:结构化查询语言,

2、Tsq=Transasct_Sql:交互式的Sql语句,是Sql的加强版,对功能进行了扩充:如变量的说明、   流程的控制、功能函数。

  (1)数据的完整性是指数据库中的数据能正确反映实际情况,数据库中存在不正确、不准确的数据、及数据库“失去了完整性”,数据库允许有一定的冗余,但必须保证数据的完整性。

 (2)元数据:描述数据的数据,如,数据的属性和属性的类型;

 (3)获取元数据,可以用sql中提供的系统函数与系统存储过程

      系统函数:SELECT DB_NAME(0)

      系统存储过程:exec sp_help ; sp_databases

 (4)数据库中分为:系统数据库和用户自定义的数据库;

      系统数据库

      (1)master:控制用户和数据库的操作

      (2)moder:用作创建模板数据库

      (3)tempdb:为临时表和其他临时工作存储需求提供一个过渡的存储区域

      (4)msdb:调度信息和作业历史存储区域

 (5)架构(Schema):为什么要用架构?为了方便权限的管理。多个用户可以拥有 一个架      构,简化了权限管理,简化了删除数据库用户的操作;提高应用程序的可维护性;

 (6)良好的数据库设计有那些好处?

      (1)节省数据的存储空间

      (2)能够保证数据的完整性

      (3)方便系统的开发

 (7)E——R图形

      正方形:实体名称,一般为名词

      菱形:关系类型,一般为动词,例如:我 爱 你

      椭圆型:属性,一般为名词

 (8)三种范式:

     (1)第一范式:为了确保每列的原子性,例如:属性名为:河南洛阳,就不满足第一范式

     (2)第二范式:满足第一范式的基础上,其他的属性都依赖与主键

     (3)第三范式:不存在传递函数的依赖,确保每列都是直接相关而不是间接相关

3、(1)DML(数据操作语句data manger Language)

   查询、插入、删除和修改数据库中的数据;

   SELECT、INSERT、 UPDATE 、DELETE等;

   (2) DCL(数据控制语句control)

   用来控制存取许可、存取权限等;

   GRANT(赋予)、REVOKE(取消) 等;grant select ojn table1 to public;

   (3)DDL(数据定义语句define 定义)

   用来建立数据库、数据库对象和定义其列

   CREATE TABLE 、DROP TABLE 等

4、数据库调优的第一个条件是看数据库设计的合理不合理;

5、Sql Server数据类型分为两种:内置的,和自定义的;

6、字符串的六种数据类型,最常用的是:

  (1)Nchar(固定长度的Unicode(具有很强的通用性,万国码)数据),例如:char(5)无          论用几个都给你分5个位置,取值差别小用Nchar

  (2)Nvarchar(可变长度的Unicode数据),动态的给你分几个位置,取值差别大的时候用            Nvarchar

  (3)库:大于8000字节=4000个Unicode字符,考虑用ntext类型

  (4)系统:保存在文件中,库中保存文件的路径

  (5)汉字需要两个字节,非Unicode

       Unicode特点:一个字符都要放两个字节

       非Unicode特点:一个字符或数字给一个字节,汉字就放不进去

  (6)乱用性能会降低

7、numeric(38,3)decimal最高精度38位后面的是小数位;nchar的默认长度为1;(精确的会四   舍五入)

   real单精度 (8)   C#中    float 32(不精确的不会四舍五入而是直接截取)

   float 双精度           double 64

   十进制被截取以后转换为二进制,有从二进制转换为十进制导致数据的丢失

   money没有小数位

   Smallmoney精确4位,四舍五入

   真正的项目中很少用byte(表示是否的数据)可以用Nchar代替

   datetime时间

   二进制数据类型 binary(固定)、varbinary(不固定)、image(存放大的长的)一般用来存储图片

   在真正做项目时,大图片一般不往数据库放,应该存储图片文件的路径,图片放到文件夹中。

8、(1)若列为整数一般用int,谨慎使用 tinyint 

   (2)若列为字符串且值的长度相差很大,使用变长数据类型

   (3)对于小数数据来说,多使用numeric (等价于 decimal)

   (4)货币数据,使用 money 数据类型

   (5)若列值不大于8 000字节,可用char、varchar或binary数据类 型

   (6)若列值超过8 000字节,使用 text 或者 image

   (7)不要使用类型为 float 或者 real 的列作为主键

9、自定义数据类型(别名数据类型)不友好;

   图形化创建:表中的可编程性里面的类型里面的用户自定义数据类型

  (1)图形化做点击右键,新建用户定义类型

  (2)还可以代码做

10、常量和变量

   (1)字符串和日期常量都加单引号

   (2)

11、变量是可以存储数据值的对象,SQL Server 在T-SQL 中支持下列两种类型的变量

   (1)全局变量:全局变量都以两个 @即‘@@’标记作为前缀。

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

        SELECT @@VERSION      AS ‘SQLServer的版本信息’

        SELECT @@ SERVERNAME AS ‘本地服务器的名称’

   (2)局部变量:局部变量名必须以 ‘@’ 为前缀,使用局部变量可将数据传递到 SQL语句

        局部变量的使用是先声明,再赋值(SET 或 SELECT 用于给局部变量赋值)

        声明: DECLARE   @变量名  数据类型  DECLARE @cust VARCHAR(20)

        赋值: SET/SELECT @变量名 =值         SET @cust= 'FRANK‘

        SELECT * FROM CUSTOMERS   WHERE CUSTOMERID = @CUST 

12、函数

    (1)标量函数对单个值进行操作,并返回单个值。这些函数是可以在表达式中使 用的函数。

    (2)聚合函数:用以计算一个值,如总和或标准差(对一组值进行运算,但返回一个汇总值)

    (3)行集函数:返回的像一个表一样多行多列;

    (4)排名函数

    函数调用的方法(和C#中的一样):

    (5)一些常见的函数,right("asdfg",2) 返回fg;

        stuff("asdfgg",3,3,"123")返回结果as123g,从第几个开始,并删除几个。

        getdate(),DATEADD(mm,4,’01/01/99’) 结果为:05/01/99

        DATEDIFF(mm,’01/01/99’,’05/01/99’) 返回:4

        SELECT DATEPART(day, ’01/15/2000’)返回:15 返回日期中想要的

13、类型转换:转换函数用于将一种数据类型的值转换为另一种类型的值。 

    SQL Server 提供了转换函数,即 CONVERT( ), CAST ()

    语法: CONVERT(datatype[(length)],expression[,style]) 其中  前对象,后目标

    datatype 为数据类型,length 为数据长度, 有长度不小心的话会被截断

    expression 为表达式,

    style 为样式。 基本不用

    例如:SELECT CONVERT (VARCHAR (5),12345) 12345也可以是字段名

    返回:字符串12345

14、count(*)总的行数 count(表名)字段不为空的总的行数

15、用户自定义函数:

    CREATE  FUNCTION 函数名称(形式参数名称 AS 数据类型) ---AS有时候可以省略

    RETURNS 返回数据类型

    AS

    BEGIN

    函数内容

    RETURN 表达式 ---和返回类型兼容一致

    END 

    更改函数: ALTER FUNCTION …用新的函数定义 代替原来的函数定义

    删除函数:DROP FUNCTION …

    调用用户自定义函数的基本语法为:

    变量=用户名.函数名称(架构名)

16、通配符

    '_' 表示一个字符  A like ‘C_’

    %   任意长度的字符串 [] 范围里面的字符串 ^不是

17、批处理:一次执行一批命令的方式被称为批处理

    两个go之间的语句被称为一个批处理

    (1)SQLServer规定:如果是建库、建表语句、以及我们后面学习的存储 过程和视图等     ,则必须在语句末尾添加 GO 批处理标志 ,若你用选择的方式执行则不需要;

 

                                                                                                库的实现

1、数据库的存储结构分为逻辑存储结构和物理存储结构两种。

2、日志文件:用来恢复数据库的,包含

3、文件组:是 SQL Server 中一个或多个文件的命名集合,它构成分配或用于数 据库管理的   单个单元    作用:提高服务器的性能.当有多个磁盘,把文件分布在这些磁盘上以提高性能。

文件组织包含数据文件,不能包含事务日志文件,主文件组和用户文件组

4、数据库文件的磁盘管理:页,是SQL Server数据存储的基本单位,页的大小为8kb

   区:是SQL管理空间的基本单位,用来有效地管理页,页都存储在区中.一个 区是   八个   物理上连续的页的集合(64 KB)分为统一区和混合区

5、脚本

   alter只能修改少量的特性,一个盘不够用在另一个盘中加一个次数据文件;

6、创建数据库的脚本语言

(1)创建数据库

CREATE DATABASE stuDB ---可以加中括号,用以防止不正确的数据库名

   ON  PRIMARY  --默认就属于PRIMARY主文件组,可省略

(

 NAME='stuDB_data',  --主数据文件的逻辑名

 FILENAME='D:\project\stuDB_data.mdf',  --主数据文件的物理名

 SIZE=5mb,  --主数据文件初始大小

 MAXSIZE=100mb,  --主数据文件增长的最大值

 FILEGROWTH=15%   --主数据文件的增长率

)

LOG ON

(

  NAME='stuDB_log',

  FILENAME='D:\project\stuDB_log.ldf',

  SIZE=2mb,

  FILEGROWTH=1MB

)

(2)修改数据库

添加:

ALTER DATABASE Test

ADD FILE 

  (

     NAME = TestNow2,   FILENAME='d:\XX.ndf', SIZE=5MB,   MAXSIZE=20MB

  )

修改:

ALTER DATABASE Sample    

MODIFY FILE  (修改文件)

( NAME = ‘XXLog', 

  SIZE = 15MB)

(3)分离与附加

EXEC sp_detach_db StuMgr   ---EXEC可以省略

EXEC sp_attach_db @dbname = N'StuMgr', ---N是Unicode也可以省略乱码时可以用

    @filename1 = N'E:\StuMgr.mdf',--文件放置的位置,必须存在 

    @filename2 = N'E:\StuMgr_log.ldf'

(4)备份与还原

   backup DATABASE DBstu  TO DISK = 'D:\db1\学生管理数据库.bak'

   restore database dbstu from disk='d:\db1\学生管理数据库.bak'

                                  表

1、表是包含数据的数据库对象,列为属性,行为一个一个的实例

2、表对象可以一次删除多个。

   添加列

   ALTER TABLE stuInfo ADD Note varchar(100) NULL --Note备注

   修改列  修改列的属性:类型,设置

   ALTER TABLE stuInfo ALTER COLUMN Note text  NULL

   删除列

   ALTER TABLE stuInfo DROP COLUMN Note

   删除表的语法:DROP TABLE 表名

   (1)在表中只有增加列的时候不用column,其他时候都要用column

                              表的完整性

1、约束:强制数据完整性,为了保证数据库中的数据的质量,强制数据完整性的机制。

   (1)所谓的数据的完整性是指要保证数据的可靠性和正确性

  (2)完整性分为:〈1〉域完整性:对输入到列中的数据进行限制(限制数据类型,默认约束,检查约束)

                   〈2〉实体完整性:像主键约束,唯一约束,标识约束等

                   〈3〉引用完整性:外键约束

2、SQLSERVER在创建表的过程中规定列的属性的过程,也是实施约束的过程。

3、(1)实体完整性数据行不能存在重复

        约束方法:标识约束、主键约束、唯一约束

   (2)域完整性实现了对输入到特定列的数值的限制

        约束方法:限制数据类型、检查约束、默认值、非空约束

   (3)引用完整性要求子表中的相关项必须在主表中存在

        约束方法:外键约束

   (4)自定义约束(约束方法:规则、存储过程、触发器 )

4、当添加约束的时候,SQL Server 将检查现有数据是否违反约束 ,可以让数据为空或者保证约束的正确性

5、用太多的约束能降低系统的性能,适当的使用可以提高系统的完整性,检查适当;

6、(1)Identity,GUID(全局惟一标识)标识约束为该列生成表中唯一的值。(只能是值类型和primarry的比较 )两者常和 DEFAULT 约束配合使用

      Identity :数据类型(integer、numeric 和 decimal(小数位数为0))

      特性:   自增长,自动生成数据;每个表只能有一个Identity列,

              不能更新不允许空值,该属性的起始值设置为 1(默认)

      例子: ID int IDENTITY(50,1) NOT NULL,

   (2)GUID :数据类型( uniqueidentifier) 

      newid()函数 : 产生一个 GUID,确保 ID 的全局惟一性

      例子: GID uniqueidentifier ROWGUIDCOL  NOT NULL  DEFAULT (newid())

      思考:如果标识列ID的初始值为1,增长量为2,则输入三行数据以后,

             再删除两行,下次再输入数据行的时候,标识值从多少开始?

   (3)主键和Uniqe的比较Uniqe可以有一个空值;

7、外键:从表的外键就是主表的主键;(本质)不要让从表中的值孤立;

8、约束的禁用:禁用约束检查,只能禁用检查约束(check)和外键约束。

9、脚本写约束

create table asd

(

id int not null primary key,  //主键约束

add_re_d text not null default ('地址不详'),//默认值约束

age_check int not null check(age_check>15 and age_check<50),//check约束

num_checik nchar(6) not null check(num_checik like 'msn_[0-9][0-9]'),

//check约束模式

a_u int  unique,    //唯一性约束

a_identifer int not null identity(100,3),//indentity约束

a_guider  uniqueidentifier not null Rowguidcol default(newid()),

//GUID 约束

)

create table a1

(

id int not null primary key,

name nchar(4) not null

)

create table a2

(

a_num int not null primary key,

a_id int not null foreign key references a1(id)

)

10、列级约束:用于单个列,表级约束:约束引用了多列

11、声明式的约束(一般的简单的约束)和过程是约束(需写复杂脚本,如触发器和存储过程);

                                     DML数据管理

1、数据的导入导出(直接备份数据):

  (1)工具sqlserver自带服务支持

  (2)select语句

  (3)备份还原

------切换数据库就在那一个数据库,左上角和use+数据库名

2、创建表

   use pubs

   create table t2

  (

    a int identity(1,1),

    id int,

    str nchar(5),

    date datetime

  )

(1)插入:

     <1>insert into t2 (id,str,date) values (02,'add','2010-2-5')

     //自增长列自己生成,不用插入,into可省略,且后面的表名可省略。

    //字符串和日期必须用单引号括起来

     <2> insert ta1 values (01,'asd',getdate())//可以不写列名,获取当前的时间

     <3>insert ta3 values

        (select * from ta2

        union

        select id,str,date from ta1)

     <4>select * into C(不存在的新表)from A;

      例子:select id,Str+cast(date as nchar(20)) into E from A;//E为新表

      select id,"MSD"+Convert(nverchar(3),stuid) into E from A;//stuid为所要转换的     字段

(2)修改成绩每个人的成绩+5分

    update stumarks set writeExam=100  //必须先加大于95的

    where writeExam>95

    update stumarks set writeExam=writeexam+5 ,labExam=labExam+5

    where writeExam<=95 and labExam<=95

(3)删除数据行

    DELETE FROM <表名> [WHERE <删除条件>]

    例子:DELETE FROM Students WHERE SName ='张青裁'

    TRUNCATE TABLE Students

    <1>使用TRUNCATE TABLE来删除所有数据时,效率要比DELETE语句高

    <2>使用DELETE删除数据时,不能删除被外键值所引用的数据行

    <3>使用turncate 能重置子增长,没有where条件

(3)select语句

    〈1〉top关键字

      --select top 5 *from products

      --select top 5 percent *from products

      --select top 5 with ties* from student order by stuid//with ties显示并列

     <2>count关键字

     --select count(distinct country) from suppliers    //默认为all不消除重复

     <3>oreder by排序

     oreder by 字段名+asc(默认升)或desc(降序)

     oreder by 中出现的字段名在select中可以不出现,并且不能出现大数据像图片和text       类型

     例子:select * from products

           order by categoryid ,unitprice desc//现在第一个字段的基础上进行第二个

    <3>where关键字

       数字的比较,字符串的比较,时间的比较。取反的时候用not

       --select * from products

       --where unitprice>16 and (productname like 'T%' or productid=16)

       in关键字 选择是japan或Italy,也就是多个or的连接

       例子: select * from suppliers

              where country in ('Japan','Italy')

       between....and.....含有边缘值;若要不含边缘用〉〈;

       like子句: select companyname from customers

                  where companyname like '%restaurant%'

       null子句:where address is null  不能用等号,等号可能产生意想不到的结果;

    <4>where...... group by()......having.......

      例1 SELECT ColA, SUM(ColC) AS SumC  FROM TableX

          GROUP BY ColA

      例2 SELECT ColA,  SUM(ColC) AS SumC   FROM TableX 

          WHERE ColA = 2

          GROUP BY  ColA

      例3 SELECT ColA, SUM(ColC) AS SUMC FROM TableX

          GROUP BY ColA

          HAVING SUM(ColC)>=30

     总结:先分组,再聚合,group by 中写的是按照什么来分组

           having 时再次过滤结果;

 

like 'A1[^a]%'以A1开头且第三个字符不是a

like '_an'包含以an结尾的三个字母的文字

‘[0-9][0-9][0-9][0-9]’

                                    高级查询

一、多表连接查询

*******(1)关键字 JOIN 指定要联接的表,以及这些表联接的方式

       (2)关键字 ON 指定联接条件

1、SELECT * FROM server(服务器名).database(数据库名).schema(架构名).table     AS table_alias

2、内连接(inner join):内连接所拼接的大表只含有两个表的公共记录;

例子:SELECT O.orderid, O.customerid, C.CompanyName,O.orderDate

      FROM orders O  INNER(可省) JOIN  customers C

      ON O.customerid = C.customerid

3、外连接

(1)left join 左边外连接:公共记录和左边的

     SELECT buyer_name, sales.buyer_id, qty 

     FROM buyers  LEFT OUTER JOIN sales  

     ON buyers.buyer_id = sales.buyer_id

(2)right join右边外连接:公共记录和右边的

(3)full join完整连接:公共记录和两表不共有的记录

4、交叉连接:cross join 

例子:SELECT buyer_name, qty 

      FROM buyers  CROSS JOIN sales

  (1)可以为数据库生成测试数据

  (2)为清单及企业模板生成所有可能的组合数据

5、多表连接

 SELECT buyer_name, prod_name, qty

 FROM buyers INNER JOIN sales

 ON buyers.buyer_id = sales.buyer_id

 INNER JOIN produce

 ON sales.prod_id = produce.prod_id

 

3、自连接语法

  (1)消除重复

  (2)树形结构

  delete  a

  From   成绩表   L    Join  成绩表   R   

  ON     L."学生ID" =  R."学生ID"     

  AND    L."课程ID" =  R."课程ID"  AND   L.   ID>   R.   ID

*****使用连接的速度比执行子查询的速度快

二、子查询

1、from前使用

   SELECT O.orderid, O.customerid,

   (SELECT C.CompanyName, C. orderDate from customers as C where O.customerid =       C.customerid) AS customername  FROM orders AS O 

2、把查询结果当作一个表

   SELECT T.orderid, T.customerid

   FROM  ( SELECT orderid, customerid FROM orders ) AS T

3、把子查询用作表达式

   所有使用表达式的地方,都可以使用子查询代替;

   SELECT title, price , ( SELECT AVG(price) FROM titles) AS average, price-   (SELECT AVG(price) FROM titles) AS difference FROM titles WHERE       type=‘popular_comp’

4、使用EXISTS 和NOT EXISTS 子句

  (1)SQL Server 处理过程

      <1>外层子查询测试子查询返回的记录是否存在 

      <2>根据条件,子查询返回 TRUE 或 FALSE

      <3>子查询不产生任何记录

 

  

 

                                   SQL语言之存储过程(procedure)

一、基本概念:

1、存储过程是一个命名的存储在服务器上的预编译T-SQL语句集合;

2、存储过程在创建时就被编译和优化,调用一次以后,

   相关信息就保存在内存中,下次调用时可以直接执行

3、存储过程的优点:

  (1)存储过程具有对数据库立即访问的功能。

  (2)可以加快程序的执行速度

  (3)可以减少网络流量

  (4)提高系统安全性

  (5)实现了模块化编程

4、存储过程的分类

   l系统存储过程

   由系统定义,存放在master数据库中

   类似C语言中的系统函数

   系统存储过程的名称都以“sp_”开头或”xp_”开头

   l用户自定义存储过程

   由用户在自己的数据库中创建的存储过程

   类似C语言中的用户自定义函数

5、存储过程:

create proce 名字

@参数in     数据类型 = 默认值 , 

@参数out   数据类型  OUT [ PUT ]

......

as

select * from  表明

go

存储过程的调用:

exec 存储过程名 参数

(2)返回值只返回整数值,默认情况下为0

     返回值必须将其值返回到变量中

    declare @parm int

    set @parm=0

例子:

create proc asd

as

select * from products

go

exec asd

例子2

create proc youcan

@ina int=0,

@outb  int output,

@outb1  int output

as

begin

select *from student where class="1"

select @outb=avg(writtenexam),@outb1=avg(labexam)from marks

end

go

--调用

declare @shuchu int

declare @shuchu1 int

exec youcan 1 ,@shuchu output,@shuchu1 output

print @shuchu

print @shuchu1                             

                                    视图

1、视图的优点

   改进性能

   简化用户管理权限,提高数据的安全性,对用户只显示特定数据,限制对敏感数据的访问

   定制数据方便调用

2、只能在当前数据库中创建视图,创建视图时不能使用临时表

   不能为试图建立索引,即使表被删除,视图的定义也不会被删除;

   创建的时候不能用order by 在运用的时候可以用

3、例子:

   create view a2    //视图名

   as

   select top 2 stuname ,writeexam,labexam ,(writeexam+labexam)/2 平均分

   from  stuINfos s join stumarks m

   on    s.stuno=m.stuno     //两个表连接时,必须用on关键字

   select * from a2 order by 平均分 desc

                                  索引

1、聚集索引:拼音目录;索引页,物理顺序页一致;

   进行大量更新操作的表

   经常排序访问的数据

   限制聚集索引中列的个数

   尽可能使用小的数据类型

2、非聚集索引:部首目录;你好!

   若未指定索引类型,则默认为非聚集索引

   叶节点页的次序和表的物理存储次序不同

   每个表最多可以有249个非聚集索引

   非聚集索引最好在具有高选择性的列上创建

   在非聚集索引创建之前创建聚集索引

3、组合索引:

(1)create  index asd1

     on [order details] (orderid,productid)

     drop index [order details].asd1

(2)create NONCLUSTERED index nclindx1-----NONCLUSTERED非聚集索引CLUSTERED聚集索引

     on titles (title_id,pub_id)

     WITH FILLFACTOR=20----填充因子,看看占百分之几

(3)删除索引drop index +索引名

                                事物

1、SQL SERVER中的事物一种高级约束机制,用于强制数据完整性的。

   (1)事物可以定义更为复杂的约束;可以包含复杂的sql语句,通常用于在多表之间执行特殊业务规则的约束

2、事物是作为一个不可分割的逻辑单元执行的一组操作命令,这些命令作为一个整体一起系统提交,要么都执行,要么都不执行[撤销,回滚];

3、事物的四大特性ACDI:

   (1)原子性(atomicity):一起执行,一起撤销,不可分割;

   (2)一致性(Isolation):当事务完成时,数据必须处于一致状态

   (3)隔离性(isolation):事务必须是独立的,它不应以任何方式依赖 于或影响其他事务。

   (4)持续性(durability):一个事物一旦提交,他对数据库中的数据改变将是永久性的

4、事物可以实现特殊的业务规则约束;

5、显式事物[自定义]

用begin tran[saction]明确指定事务的开始,

以 commit或 rollback语句显式结束.这是最常用的事务类型

   create table bank   //创建表

   (

   cusomername nchar(10) not null,

   curmoney numeric(6,2) not null

   check (curmoney>=1)

   )

例子1、

   declare @sum int    //声明变量

   set @sum=0          //设置变量的默认值

   insert bank values('zs',1000)

   set @sum=@sum+@@error

   insert bank values('ls',100)

   set @sum=@sum+@@error

   if(@sum=0)

   print 'ok'

   else

   print

   print 'no'

例子2、

   declare @sum int

   set @sum=0      ---变量的值必须赋值否则他就是一个null

(1)begin tran         ---开始事物

   update bank      ----sql语句

   set curmoney=curmoney-1000

   where cusomername='zs'

   set @sum=@sum+@@error  --设置值必须加上set

   update bank

   set curmoney=curmoney+1000

   where cusomername='ls'

   set @sum=@sum+@@error

   if(@sum=0)            ---判断是否能提交

(2)commit tran ---提交事物

   else

(3)rollback tran ---回滚事物

6、隐式事物:用set implicit_transactions on将隐性事务模式设置为打开,在前一个事务      完成时新事务隐式启动,

7、并发问题:

   如果有多个用户同时访问一个数据库,当他们的事务同时使用相同的数据时可能会发生问题。

   (1)丢失更新,当两个或多个事物选择同一行,然后基于最初选定的值更新改行时,会发生丢失问题;(锁)

  (2)脏读,未确认的相关性,当第二个事务选择其他事务正在更新的行时,会发生未确认的相关性问题

  (3)不一致的分析(非重复读)当第二个事务多次访问同一行,而且每次读取不同的数据时,会发生不一致的分析问题

   (4)幻像读,当对某行执行插入或删除操作,而该行属于某个事务正在读取的行的范围的时候,会发生幻像读问题

SQl已经不存在这种并发问题了

8、锁定:实在多用户情况下解决并发问题对数据访问限制的一种机制;

   使得事务的串行成为可能,用户需要对表的排它访问,  同一时间只有一个人 可以修改数据元素,防止更新冲突,用户不能读取或修改其他用户正在进行修 改的数据

 

   共享锁 :用于不更改或不更新数据的操作,如 SELECT

   排它锁 :用于数据修改操作(自己这个表在修改),如 INSERT、UPDATE 或 DELETE

HOLDLOCK: 将共享锁 其他的表只能查,但不能修改

TABLOCKX: 表的排它锁,其他的表不能查

9、死锁:事物1请求了事物2加锁的资源,事物2有请求了事物1加锁的资源

   接触死锁:set deadlock_PRIORITY ;SET LOCK_TIMEOUT

 

10、并发控制的第二种方法(事物的隔离优先级)

   隔离级别越高,   产生错误的几率越少。但开销越大,并发性越差。

 

ANSI SQL-92隔离级别        低   脏读    不可重复读 幻像

Read uncommitted 未提交读   可能    可能            可能

Read committed 提交读         避免    可能            可能

Repeatable read 可重复读        避免    避免            可能

serializable    可串行读   高   避免    避免            避免

语法:

SET TRAN[SACTION] ISOLATION LEVEL  REPEATABLE READ

GO

BEGIN TRAN[SACTION]

SELECT * FROM publishers

SELECT * FROM authors

COMMIT TRANSACTION

                               触发器

1、触发器:是一种高级约束机制,用于强制数据的完整性(触发器是在对表进行插入、更新或删除操作时自动执行的存储过程)

2、触发器是一个事物,可回滚,具备事物的功能;

触发器的其他特点:与特定的表和视图紧密相连,表中的数据发生变化时自动调用;

3、触发器触发时:系统自动在内存中创建deleted表或inserted表

   只读不允许修改;触发器执行完成后自动删除

(1)inserted 表:临时保存了插入或更新后的记录行

   deleted 表 : 临时保存了删除或更新前的记录行

修改操作            inserted表      deleted表

增加(INSERT)记录    存放新增的记录       ------

删除(DELETE)记录    -----                存放被删除的记录

修改(UPDATE)记录    存放更新后的记录     存放更新前的记录

4、触发器的语法:

(1)创建

create trigger 名字

on 表或视图  。。。。触发器所属的表

[WITH<dml_trigger_option>[,...n ]属性]       ... 往往不用

after|for[delete,insert,update]

as

begin

语句体        ...往往要用到delete,或 insert表

例子:SELECT COUNT(*) FROM Deleted

end

-----------调用

(2)禁用或启用触发器

ALTER TABLE 表名{ENABLE|DISABLE}TRIGGER{ALL|触发器名[, …n]}

(3)删除

drop trigger

例子:

create table bank1

(

name nchar(10) not null,

cardid  int not null,

curmoney numeric(6,2)

)

create table traInfo

(

tranid int identity(1,1),

cardid  int not null,

tranType nchar(2) not null,

tranmoney numeric(6,2),

date datetime not null

)

//创建触发器

create trigger trig_bank 

on bank1  after update

as

begin

declare @old numeric(6,2)

declare @new numeric(6,2)

declare @cha numeric(6,2)

declare @cardid1 int

declare @tranType nchar(2)

select @old=curmoney,@cardid1=cardid  from deleted

select @new=curmoney from inserted

if(@old>@new)

begin

set @cha=@old-@new

set @tranType='取出'

end

else

begin

set @cha=@old-@new

set @tranType='存进'

end

insert trainfo values(@cardid1 ,@tranType,@cha,getdate())

end

---调用

update bank1 set curmoney=curmoney-100

where name='zs'

 

你可能感兴趣的:(sqlserver)