字符串用单引号',判断用单等号=,两个单引号''转义为一个单引号'
不等号是<>
不区分大小写
[]括起来的要不是关键字,要不是非法变量,比如空格隔起来的变量
创建与删除数据库
1 --创建数据库 2 create database School; 3 --删除数据库 4 drop database School; 5 --创建数据库的时候指定一些选项 6 create database School; 7 on primary--配置主数据文件 8 ( 9 name='School',--逻辑名称,数据库内部用的名字10 filename='',--保存路径11 size=5MB,--设置初始化大小12 filegrowth=10MB或10%,--设置增长速度13 maxsize=100MB--设置最大大小14 )15 log on--配置主日志文件16 (17 name='',--设置逻辑名称18 filename='',--设置路径19 size=3MB,20 filegrowth=3%,21 maxsize=20MB22 )
创建表
1 --每个项设置后面都加逗号 最后一项不加 2 --切换数据库 3 use School; 4 --在School数据库中创建一个学生表 5 create table TblStudent 6 ( 7 --表中的定义在这对的小括号中 8 --开始创建列 9 --列名 数据类型 自动编号(从几开始,增长步长) 是否为空(不写默认允许,或者写null 不允许空写 not null)10 --tsid int identity(1,1) not null11 --设置名为tsid 类型为int 从1开始增长,每次增长1的主键列12 tsid int identity(1,1) primary key,13 )
插入数据
1 --查询表 2 select * from TblClass 3 --insert向表插入数据(一次只能插一条) 4 insert into TblClass(tclassName,tclassDesc) values('tclassName的值','tclassDesc的值') 5 --TblClass后面的括号设置在哪些列插入数据,value后面的括号要与前面的一一对应.如果要给除自动编号的所有列插入数据,TblClass后面的括号可省 6 --插入同时返回指定列的数据:在value前加上output inserted.列名 7 8 9 --向自动编号列插入数据10 --先把一个选项打开 倒数第二个是列名11 set IDENTITY_INSERT tblclass on12 insert........13 --最后记得把选项关掉14 --听过一条语句插入多条数据15 insert into TblClass(tclassName,tclassDesc)16 select '...','...' union17 select '...','...' union18 select '...','...' union19 select '...','...' --最后一项不用union20 --把一个表的书数据插入另一个表21 insert into 被插表(列名,列名)22 select 列名,列名 from 数据来源表23 --插入汉字记得在字符串前加入N
更新数据
1 update 表名 set 列名=值,列名2=值2 where 条件 and..or...2 --如果没有条件,所有数据都会更新
删除数据
1 --删除 2 delete from 表名 where 条件 3 --删除整表数!据!与drop不同,两种 4 --1,delete from 表名 5 --速度慢 6 --自动编号依然保留当前已经增长的位置 7 delete from 表名 8 --2,truncate table 表名 9 --速度快10 --自动编号重置11 truncate table 表名
修改表设置
1 --修该列 2 --删除指定列 3 alter table 表名 drop column 列名 4 --增加指定列 5 alter table 表名 add 列名(这里跟创建表一样) 6 7 --修改指定列 8 alter table 表名 alter column 列名 9 --增加约束10 --给指定列添加主键约束11 alter table 表名 add constraint 约束名 primary key(列名)12 --给指定列添加非空约束13 alter table 表名 alter column 列名 数据类型 not null14 --给指定列添加唯一约束15 alter table 表名 add constrainy UQ开头的约束名 unique(列名)16 --给指定列添加默认约束17 alter table 表名 add constraint 约束名 default(值) for 列名18 --给指定列添加检查约束19 alter table 表名 add constraint 约束名 check(表达式) 20 --增加外键约束21 alter table 表名 add constraint FK_约束名 foreign key(外键列名)references 主键表名(列名)22 23 --删除多个约束24 alter table 表名 drop constraint 约束名,...,...25 26 --创建多个约束27 alter table 表名 add28 constraint 约束名 unique(列名),29 constraint 约束名 check(表达式),30 constraint 约束名 foreign key(要引用列)31 references 被引用表(列) 32 on delete cascade on update cascade --设置级联删除和更新
查询数据(select,top,distinct)
1 --数据检索,查询指定列的数据,不加where返回所有2 select 列名,列名,... from 表名 where 条件3 --用select显示东西,列名可省略,列名可以不''起来,除非名字有特殊符号4 select 值 (空格或者as) 列名5 --top获得前几条数据,选到的都是向上取整6 select top (数字或数字 percent) * from 表名 order by 列名 (asc//升序,默认值 desc//降序)7 --Distinct去除查询出的重复数据,只要有一点不同(显示出来的列的内容不同)不算重复,比如自动增长的那列8 select distinct 要显示的列 from 表名 ...
联合查询(union,union all)
合并行叫做"联合"
联合必须保证每行的数据数目与第一行一致,数据类型兼容
列名为第一行的列名
union all 在联合时不会去除重复数据,也不自动排序
不能分别排序
常用:底部总和
例:
select
商品名称,
销售总价格=(sum(销售数量*销售价格))
fromMyOrders
groupby商品名称
union all
select'销售总价:',sum(销售数量*销售价格)fromMyOrders
连接查询(join....on...)
A表 join B表 on 两表关系
例:
1 select*from TblClass2 jion tblstudent on TblClass.tClassId=TblStudent.tSClassId3 --查询出两个表符合TblClass.tClassId=TblStudent.tSClassId的数据行,并显示其所有数据
连接分为内连接和外连接
内连接:
1,普通内连接
inner join.. on..
仅筛选两个表都有匹配的数据,例如:
1 select*from TblClass2 jion tblstudent on TblClass.tClassId=TblStudent.tSClassId
//这里先把两个表的数据拿出,把TblClass.tClassId,与TblStudent.tSClassId相同的那 行构成新的行,
//进一步构成新的表,如果TblClass.tClassId有个值为3,而TblStudent.tSClassId没有,那么新的表不会有这行数据,另外这个表是临时存在于内存
1 select * from TestJoin1Emp emp inner join TestJoin2Dept dept on emp.EmpDeptid=dept.DeptId2 --两者等效3 select * from TestJoin1Emp emp , TestJoin2Dept dept 4 --假设emp与dept,行数分别是3,5.select * from 这两个表,实际会形成3*5=15行的临时表5 --再在这个表中筛选,而这个表叫做笛卡尔表6 where7 emp.EmpDeptid=dept.DeptId
自连接
特点:关系列的值引用的本表中主键列信息
例子:
1 create table groups 2 ( 3 gid int identity(1,1) primary key not null, 4 gname nvarchar(10), 5 gparent int 6 ) 7 select * from groups 8 insert into groups values('总部',0) 9 insert into groups values('北京分公司',1)10 insert into groups values('上海分公司',1)11 insert into groups values('.net部门',2)12 insert into groups values('.net部门',3)13 --查询部门对应的上级部门14 use Temp15 select deparment.gname as '部门名称',company.gname as '所属部门'16 from groups as deparment17 inner join groups as company18 on deparment.gparent=company.gid
外连接:
1,左外连接
语法:左表 left join右表on...
左表的信息全部输出,右表的信息在左表有匹配才输出
未匹配的用null填充
原理:先连接两个表为笛卡尔表,再找到匹配行,把左表剩下的补上
2,右外连接
语法:左表 right join 右表 on ...
类似左外连接
3,完全外连接
语法:full outer join 简写为join
信息全部显示,没有的用null填充
多表查询案例
1 ------多表查询案例分析: 2 3 -- dbo.Branch:结构表: 银行,开发商,政府房管局 4 5 --dbo.BuildingInfo: 建筑信息表。 天堂花园 1号楼。 6 7 --dbo.ProjectInfo:项目信息表。天堂花园1期。 8 9 --dbo.UserInfo:用户信息表10 11 ---查询建筑信息表,顺便:建筑信息所属的项目名,项目所属的机构名字,项目创建人的名字12 13 select B.*,P.ProjectName,BR.BranchName,u.UName as SubBy from dbo.BuildingInfo as B14 left join dbo.ProjectInfo as P on B.ProjectId=P.Id15 left join dbo.Branch as Br On P.BranchId=BR.Id16 left join dbo.UserInfo as U On P.SubBy=U.Id
模糊查询,通配符
1 --模糊查询,通配符,当使用通配符必须使用like,可以在like前面加no 表示除了匹配数据的数据 2 --%,表示匹配任意多个字符 3 --例子,查询以张开头的字符串 4 select * from 表名 where 列名 like N'张%' 5 --查询包含%的字符串 6 select * from 表名 where 列名 like '%[%]%' 7 8 -- _ ,表示一个任意字符 9 -- [ ],表示匹配一个字符,这个字符是[]访问内的通常是[0-9][a-z]10 -- ^ 非
排序(order by)
order by 一定是放在最后
order by 列或(列+列),列,列.. desc/asc
--可多个列
判断NULL值
在数据库中,NULL更任何数据对比或运算都返回null
与任何值运算返回null
使用特殊的运算符 is
.....where 列名 is null
.....where 列名 is not null
分组(group by)
当在查询中使用了group by分组后,select选择的列必须是group by中包含的列或者该列必须在聚合函数中
1 --例子,统计学生表中每个班的男生人数,且显示id 2 select 3 班级id=tsclassId 4 男同学人数=count(*) 5 from TblStudent 6 where tsgender='男' 7 group by (tsclassId,这就是group by包含的列,可以逗号添加多个列,意味着分组后在分组) 8 --有时候要把一些信息放到group by后才能放到select,这时不一定担心,在group by 语句写过多会造成过多的分组, 9 --例子如下10 --列1 列2 列 311 --A aa 少壮不努力12 --B bb 老大LOL13 --如果group 列1,列2 因为当列1为A,列2必须aa,列1B,列2必须bb时最终只会会分成两个组,所以有时候不用担心分组过多14 15 16 --对得到的组进一步筛选(having)17 18 --例子:按笔记编号分组,筛选出班级人数大于10的班级19 select20 tsclassId as 班级编号21 count(*) as 人数22 from TbStudent23 --如果这里有where,where这不能用聚合函数24 group by tsclassId25 having count(*)>10//having的内容只能是select选择的内容
select 列 into 新表 语法
1,insert into 表1(列1,列2) select 列1,列2 from 表2 where
//向已经存在的表中插入其他表的数据
2,select * into 表2 from 表1 where
//执行完这句话,表2才生成,如果表2存在则报错,复制数据类型,增长特性,约束不复制
子查询
把一个查询的结果在另一个查询中使用就叫子查询。(将一个查询语句做为一个结果集供其他SQL语句使用)
子查询的几种情况:子查询作为数据源,子查询作为where条件,子查询作为列select 列=(子查询)
当子查询作为数据源时必须给它器别名
子查询基本分类:
独立子查询
子查询可以独立运行
相关子查询
子查询中引用了父查询中的结果
例:
select * from TblStudent as tswhere exists//如果查到数据返回true(select * from TblClass as tc wheretc.tclassId=ts.tsclassId and(tc.tclassname='高一一班'or tc.tclassname='高二二班'))
返回TblStudent中根据tsclassid在TblClass中找到的班级名称为高一一班或高二二班的整行数据
只有返回且仅返回一行、一列数据的子查询才能当成单值子查询。
子查询返回的值不止一个。当子查询跟随在=、!=、<、<=、>、>= 之后,或子查询用作表达式时,这种情况是不允许的。
如果子查询是多行单列的子查询,这样的子查询的结果集其实是一个集合。可以使用in关键字代替=号
分页(row_number())
分页要统一排序
这里有两种方法
1,通过top
设每页数据5条,第一页,top 5
第二页除了第一页查到的,剩下的数据集的前5条
第三页除了前两页查到的,剩下的数据集的前5条
......
1 select top 5 * from Customers where CustomerId not in2 (select top (n-1)*5 CutomerID from Customers order by CustomerId asc)3 order by CustomerId asc
2,通过row_number()
1 --每页7条,看第4页。 2 select * from 3 ( 4 select 5 row_number() over(order by CustomerId asc) as Rn , 6 * 7 --over()子句把数据按CustomerId排序 8 --通过row_number()函数吧查到的数据添加一条编号列,列名为Rn 9 --再通过编号得到想要的数据10 from Customers11 ) as Tbl where Tbl.Rn between (4-1)*7+1 and 4*7
分页有多种方法,针对不同需求选择不同方法,具体要靠Profiler查看性能
over子句
在应用具体的聚合函数、排名函数前对行集的分区和排序。over子句,用于支持窗口的计算,所以一般与排名开窗函数、聚合开窗函数一起使用。
窗口是用户指定的一组行。开窗函数计算从窗口派生的结果集中各行的值。
可以把over()子句理解成是“后台运行的数据”,只是为了让聚合函数或者是排名函数“用一下”.
over( partition by ..)其效果类似于group by,select中的列必须是被group by的或者在聚合函数中.
例,两者等效
1 select b.studentid,b.score ,b.courseName ,2 (select count(*) from StudentScore where courseName=b.courseName group by courseName) as '参加该科目考试的额人数为'3 from StudentScore as b4 order by b.studentid,courseName5 --等效于6 select studentid,score,courseName,7 count(*) over (partition by courseName) as'参加该科目考试的额人数为'8 from StudentScore9 order by studentid,courseName
over子句的两种使用方式:
1.over子句与排名开窗函数一起用,
语法:
over([partition by 列1] order by 列2)//必须有order by 子句
2.over子句与聚合开窗函数一起用,
语法:
over([partition by 列1])//不能使用order by子句了。可以用也没意义,因为都聚合了,有顺序有什么用
注:
当over()子句与聚合函数一起使用时,也可以直接写count(*) over()不在over()子句中进行任何分区,表示把整个表分为一个区。
视图
定义
视图是一张虚拟表,它表示一张表的部分数据或多张表的综合数据,其结构和数据是建立在对表的查询基础上
是sql语句的封装
视图的目的是方便查询,所以一般情况下不能对视图进行增删改
与数据表的异同
视图在操作上和数据表没有什么区别,但两者的差异是其本质是不同:数据表是实际存储记录的地方,然而视图并不保存任何记录。
优点
筛选表中的行,降低数据库的复杂程度
防止未经许可的用户访问敏感数据
建立视图
create view v_Area
as
select * from 表
修改视图
alter view v_Area
as
select * from 表
删除视图
drop view v_Area
查看视图
select * from
v_Area
注意
1,视图是虚拟表,表示一个集合,表本质是无序的,平时的select是自动排了序的
所以视图中的select语句不能有order by,除非前面有top,而在这种情况下使用top与order by意思是,将表的数据按指定顺序排序,并取出前n条作为视图的内容,而这里,并没有保证视图中的数据是怎样排序的
但使用视图时能用order by,使之有序显示
select * from v_Area
order by....
2,视图的每一个列都有列名,且列名必须唯一,它会自动把被select列的列名设为视图的列名,但是如果
1 select a1.AreaId,a1.AreaName,a2.AreaName2 from TblArea as a1 inner join TblArea as a2 on a2.AreaId=a1.AreaPId3 --这个select用了两个AreaName,这样不能确定视图的列名,会报错
事务
定义
同生共死 指访问并可能更新数据库中各种数据项的一个程序执行单元(unit)--也就是由多个sql语句组成,必须作为一个整体执行 这些sql语句作为一个整体一起向系统提交,要么都执行、要么都不执行
1 update bank set balance=balance-1000 where cid='0001'2 update bank set balance=balance + 1000 where cid='0002'3 --模拟银行转账,如果第一条出错,第二条还是会执行4 --所以这里需要用到事务
语法
开始事务:BEGIN TRANSACTION
事务提交:COMMIT TRANSACTION
事务回滚:ROLLBACK TRANSACTION
sql是默认自动提交事务
判断事务执行是否出错:
全局变量@@ERROR
@@ERROR只能判断当前一条T-SQL语句执行是否有错,为了判断事务中所有T-SQL语句是否有错,我们需要对错误进行累计
例:
SET @[email protected]+@@error
ACID特性
原子性(Actomicity):事务是一个完整的操作,事务的各步操作是不可分的(原子的):要么执行,要么不执行
一致性(Consistency):当数据完成时,数据必须处于一至状态
隔离性(Isolation):对数据进行修改的所有并发事务时彼此隔离的,一个事物在执行结束前不会执行另一个事物
永久性(Durability):事务完成后,它对数据库的修改被永久保持,事务日志能够保持事务的永久性
隐式事务
因为sql是默认提交的,这里就是隐式事务
可以通过下面代码进行修改
SET IMPLICIT_TRANSACTIONS { ON | OFF } --不怎么用
例子
1 begin transaction 2 declare @sumErrors int=0 3 --执行操作 4 update bank set balance=balance-1190 where cid='0001' 5 --立刻验证一下这句话是否执行成功了。。 6 set @sumErrors=@sumErrors+@@error 7 update bank set balance=balance+1190 where cid='0002' 8 set @sumErrors=@sumErrors+@@error 9 10 --验证是否执行成功11 if @sumErrors=012 begin13 --表示没有出错14 commit transaction --将事务提交15 end16 else17 begin18 rollback --失败则回滚19 end
存储过程
就像数据库中运行方法(函数)
由存储过程名/存储过程参数组成/可以有返回结果。
优点
1、比使用DotNet直接写Sql脚本执行少了一块解析编译的过程。效率更快一点点。
2、使用存储过程的时候,业务 改变只需要改存储过程,然后业务逻辑就发生变化了,不需要修改C#代码。
3、传递sql脚本数据相对小。
缺点
1、使用存储过程,数据库可移植性差。(SqlServer的sql脚本移植到Oracle中要重新写)
2、把业务放到了存储过程里面去,相当于业务处理的压力放到数据库里面去。业务层去处理,数据库只是来存储数据。(数据库是最慢的)
为啥这么做:(1)解放数据库的压力(2)数据库本身做集群很困难,业务去做分流,做集群很容易。
综上所述
以后尽量把Sql语句写在C#代码中,老项目可能还要用存储过程
存储过程创建
1 create procedure usp_Add1 2 @num1 int, 3 @num2 int 4 as 5 begin 6 print @num1+@num2 7 end 8 --带默认值的存储过程 9 create procedure usp_Add2 10 @num1 int=3,11 @num2 int12 as13 begin14 print @num1+@num215 end16 --带输出参数的存储过程17 create procedure usp_Add3 18 @num1 int,19 @num2 int,20 @num3 int output21 as22 begin23 @num3=@num1+@num224 end
存储过程调用
1 exec usp_Add1 5,4 --输出92 3 exec sp_helptext 'sp_databases' --看指定存储过程源码的4 5 exec usp_Add2 @num2=8 --输出11,[email protected]@num2=...,[email protected]6 7 delcare @answer int--跟c#里面out参数差不多,声明与调用都要写output8 exec usp_Add3 6,6,@answer ouput
例子
分页存储过程
1 alter procedure usp_fenye 2 @pageSize int,--每页的记录条数 3 @pageIndex int,--用户当前要查看第几页 4 @pageCount int output --输出参数,返回总共有几页 5 as 6 begin 7 select * 8 from 9 (10 select *,Rn=row_number()over(order by tSid) 11 from TblStudent12 ) as stu 13 where Rn between (@pageIndex-1)*@pageSize+1 and @pageIndex* @pageSize14 15 --设置输出参数的值16 declare @datacount int=(select count(*) from TblStudent)17 set @pageCount=ceiling(@datacount/(@pageSize*1.0))18 --向较大的数取整19 end
注意
如果要拿到多个表的数据,则直接在存储过程中select
在ADO.Net中用DataSet.table[],获得指定的表
而且如果不想用out返回一个数据,也可以select当做表返回
系统储存过程
索引
使用索引能提高查询效率,但是索引也是占据空间的,而且添加、更新、删除数据的时候也需要同步更新索引,因此会降低Insert、Update、Delete的速度。
(现在都是用填充因子去实现索引,每个表中都空些内容,你插入数据就不必更新那么多了)
只在经常检索的字段上(Where)创建索引
索引分两种:
理解:
把字典的内容比喻为数据,目录则为索引.
字典的内容是按照拼音排序的
通常会根据按拼音,或边旁部首来找到想要找到字.
拼音检索目录中的字的顺序与字典内容字的顺序一样,这里把拼音检索目录理解为聚集索引
而边旁部首检索目录中的字的顺序与字典内容的不一样,这里把它理解为非聚集索引
1.聚集索引(聚簇索引),建立主键时默认吧主键设为聚集索引
一个表中只能有一个聚集索引。
一般在建表以后要先建一个聚集索引,然后在建立其他索引。
其他索引依赖于聚集索引。
建立聚集索引的时候尽量避免选择那些频繁更新的列。
2.非聚集索引(非聚簇索引)
非聚集索引不唯一
非聚集索引依赖于聚集索引
查找条件---->非聚集索引------>聚集索引---->想要找的数据
注意
即使创建了索引,仍然有可能全表扫描,比如like、函数、类型转换等。
ntext、text、varchar(max)、nvarchar(max)不能建索引数据太大了
字符串也尽量别建
语法
1 --聚集索引创建2 create clustered index 名字 on 表(列)3 --非聚集索引创建4 create index 名字 on 表(列)5 --删除索引(略有不同) 6 drop index 表名.索引名
inserted表与deleted表
当执行insert语句时,把插入的数据保存到一个临时的inserted表和指定表,当这个事务执行完后销毁这个inserted临时表
当执行deleted,把要删除的数据剪切到deleted表中,当这个事务执行完后销毁这个deleted临时表
当执行update是,把数据剪切到deleted表,再把新数据复制到inserted表和指定表,事务执行完了销毁两个表
inserted表包含新数据
insert、update触发器会用到
deleted表包含旧数据
delete、update触发器会用到
触发器(像C#的事件)
自动化操作,减少了手动操作以及出错的几率。
在SQL Server里面也就是对某一个表的一定的操作,触发某种条件,从而执行的一段程序。触发器是一个特殊的存储过程。
DML触发器:
Insert、delete、update(不支持select)
after触发器(for)、instead of触发器
(*)DDL触发器
Create table、create database、alter、drop…
after触发器
在语句执行完毕之后触发 按语句触发,而不是所影响的行数,无论所影响为多少行,只触发一次。
只能建立在常规表上,不能建立在视图和临时表上。(*)
可以递归触发,最高可达32级。
update(列),在update语句触发时,判断某列是否被更新,返回布尔值。
instead of触发器
用来替换原本的操作
不会递归触发
可以在约束被检查之前触发
可以建在表和视图上(*)
语法
1 --create trigger 触发器名 on 表名2 create trigger tri_delete_TblPerson on TblPerson3 --for/after/instead of(for与after都表示after触发器) delete/insert/update,可以写多个触发器类型用逗号隔开4 instead of delete,insert5 as6 begin7 --执行内容,会用到selected表或inserted表8 end
游 标
缺点:
性能低!!!!!
语法
1.declare 游标名 cursor [local | global][游标选项] for 查询语句
2.open 游标名
3.fetch [next] from 游标名 into @v1,@v2…
4.判断@@fetch_status状态,继续fetch
5.close 游标名 –关闭游标
6.deallocate 游标名 –删除游标中数据库中保存的数据结构(彻底释放资源)
例子
使用游标来查看100条数据
1 --1.定义一个游标 2 declare cur_Area cursor fast_forward for select top 100 * from Area 3 --2.打开游标 4 open cur_Area 5 6 --3.查询使用游标 7 fetch next from cur_Area 8 while @@fetch_status=0 9 begin10 fetch next from cur_Area11 end12 13 --4.关闭游标14 close cur_Area15 --5。释放资源16 deallocate cur_Area
SQL语句执行顺序
⑤select ⑦distinct ⑨top ⑥选择列
①From 表
②where 条件
③Group By 列
④Having 条件
⑧Order By 列 下面内容为转载
sql的临时表使用小结
1、创建方法:
方法一:
create table TempTableName
或
select [字段1,字段2,...,] into TempTableName from table
方法二:
create table tempdb.MyTempTable(Tid int)
说明:
(1)、临时表其实是放在数据库tempdb里的一个用户表;
(2)、TempTableName必须带“#”,“#"可以是一个或者两个,以#(局部)或##(全局)开头的表,这种表在会话期间存在,会话结束则自动删除;
(3)、如果创建时不以#或##开头,而用tempdb.TempTable来命名它,则该表可在数据库重启前一直存在。
2、手动删除
drop table TempTableName
说明:
use testdb
--创建局部临时表
create table #tmpStudent(Tid int,Name varchar(50),Age int)
insert into #tmpStudent values('xiaowang',25)
select * from #tmpStudent
--创建局部临时表 另一种写法
select * into #tmpStudent from student
select * from #tmpStudent第二种创建方法:
方法一:
create table TempTableName
或
select [字段1,字段2,...,] into TempTableName from table
方法二:
create table tempdb.MyTempTable(Tid int)
说明:
(1)、临时表其实是放在数据库tempdb里的一个用户表;
(2)、TempTableName必须带“#”,“#"可以是一个或者两个,以#(局部)或##(全局)开头的表,这种表在会话期间存在,会话结束则自动删除;
(3)、如果创建时不以#或##开头,而用tempdb.TempTable来命名它,则该表可在数据库重启前一直存在。
2、手动删除
drop table TempTableName
说明:
DROP TABLE 语句显式除去临时表,否则临时表将在退出其作用域时由系统自动除去:
(1)、当存储过程完成时,将自动除去在存储过程中创建的本地临时表。由创建表的存储过程执行的所有嵌套存储过程都可以引用此表。但调用创建此表的存储过程的进程无法引用此表;
(2)、所有其它本地临时表在当前会话结束时自动除去;
(3)、全局临时表在创建此表的会话结束且其它任务停止对其引用时自动除去。任务与表之间的关联只在单个Transact-SQL语句的生存周期内保持。换言之,当创建全局临时表的会话结束时,最后一条引用此表的Transact-SQL语句完成后,将自动除去此表。
3、示例代码
(1)创建

use testdb
--创建局部临时表
create table #tmpStudent(Tid int,Name varchar(50),Age int)
insert into #tmpStudent values('xiaowang',25)
select * from #tmpStudent
--创建局部临时表 另一种写法
select * into #tmpStudent from student
select * from #tmpStudent
create table tempdb.MyTempTable(Tid int) --有对应权限才可以这么写
(2)删除drop table #tmpStudent