
SQL Server临时表有两种类型:本地和全局。它们在名称、可见性以及可用性上有区别。本地临时表的名称以单个数字符号 (#)
打头;它们仅对当前的用户连接是可见的;当用户从 SQL Server 实例断开连接时被删除。全局临时表的名称以两个数字符号 (##)
打头,创建后对任何用户都是可见的,当所有引用该表的用户从 SQL Server 断开连接时被删除。
如果数据库会话创建了本地临时表 #temtable,则仅会话可以使用该表,会话断开连接后就将该表删除。如果创建了
##temtable全局临时表,则数据库中的任何用户均可使用该表。如果该表在您创建后没有其他用户使用,则当您断开连接时该表删除。如果您创建该表后另一个用户在使用该表,则SQL Server 将在您断开连接并且所有其他会话不再使用该表时将其派液删除。
如果本地临时表由存储过程创建或由多个用户同时执行的应用程序创建,则SQL Server 必须能够区分由不同用户创建的表。为此,SQL Server 在内部为每个本地临时表的表名追加一个数字后缀。存储在tempdb 数据库的 sysobjects 表中的临时表,其全名由 CREATE TABLE 语句中指定的表名和系统生成的数字后缀组成。为了允许追加后缀,为本地临时表指定的表名table_name不能超过 116 个字符。
当存储过程完成时,将自动除去在存储过程中创建的本地临时表。由创建表的存储过程执行的所有嵌套存储过程都可以引用此表。但调用创建此表的存储过程的进程无法引用此表。
临时表位于tempdb系统数据库。
使用SELECT INTO语句可以把任何查询结果集放置到一个新表中,还可以通过使用SELECT
INTO语句解决复杂的问题。例如,需要从不同数据源中得到数据集,如果一开始先创建一个临时表,那么在该表上执行查询比在多表或多数据库中执行查询更简单。
在使用SELECT INTO语句时,应该注意如下的事项和原则:
可以使用SELECT INTO语句创建一个表并且在单独 *** 作中向表中插入行。确保在SELECT INTO语句中指定的表名是惟一的。如果表名出现重复,SELECT
INTO语句将失败。
可以创建本地或全局临时表。要创建一个本地临时表,需要在表名前加符号(#);要创建一个全局临时表,需要在表名前加两个符号(##)。本地临时表只在当前的会话中可见,全局临时表在所有的会话中都可见。
当使饥羡团用者结束会话时,本地临时表的空间会被回收。
当创建表的会话结束且当前参照表的最后一个Transact-SQL语句完成时,全局临时表的空间会被回收。
使用SELECT INTO语句的基本语法如下:
SELECT <select_list>
INTO new_table
FROM {<table_source>}[,…n]
WHERE <search_condition>
例如:select * into #newTable from news where s_date>'2010-3-1'
利用SQL Server的全局临时表防止用户重复登录
在我们开发商务软件的时候,常常会遇到这样的一个问题:怎样防止用户重复登录我们的系统?特别是对于银行或是财务部门,更是要限制用户以其工号身份多次登入。
可能会有人说在用户信息表中加一字段判断用户工号登录的状态,登录后写1,退出时写0,且登录时判断其标志位是否为1,如是则不让该用户工号登录。但是这样那势必会带来新的问题:如发生象断电之类不可预知的现象,系统是非正常退出,无法将标志位置为0,那么下次以该用户工号登录则不可登入,这该怎么办呢?
或许我们可以换一下思路:有什么东西是在connection断开后可以被系统自动回收的呢?对了,SQL
Server的临时表具备这个特性!但是我们这里的这种情况不能用局部临时表,因为局部临时表对于每一个connection来说都是一个独立的对象,因此只能用全局临时表来达到我们的目的。
好了,情况烂橘已经明朗话了,我们可以写一个象下面这样简单的存储过程:
create procedure gp_findtemptable -- 2001/10/26 21:36 zhuzhichao in nanjing
/* 寻找以 *** 作员工号命名的全局临时表
* 如无则将out参数置为0并创建该表,如有则将out参数置为1
* 在connection断开连接后,全局临时表会被SQL Server自动回收
* 如发生断电之类的意外,全局临时表虽然还存在于tempdb中,但是已经失去活性
* 用object_id函数去判断时会认为其不存在. */
@v_userid varchar(6), -- *** 作员工号
@i_out int out -- 输出参数 0:没有登录 1:已经登录
as
declare @v_sql varchar(100)
if object_id('tempdb.dbo.##'+@v_userid) is null
begin
set @v_sql = 'create table ##'+@v_userid+'(userid varchar(6))'
exec (@v_sql)
set @i_out = 0
end
else
set @i_out = 1
在这个过程中,我们看到如果以用户工号命名的全局临时表不存在时过程会去创建一张并把out参数置为0,如果已经存在则将out参数置为1。
这样,我们在我们的应用程序中调用该过程时,如果取得的out参数为1时,我们可以毫不客气地跳出一个message告诉用户说”对不起,此工号正被使用!”
判断方法范例:
select @sTmpWareA="tempdb..[##MARWareA"+ @ComputerName+"]"
if exists (select * from tempdb..sysobjects where id = object_id(@sTmpWareA) and
type = "U")
begin
set @sTmpWareA="[##MARWareA"+ @ComputerName+"]"
exec( "drop table " )
end
else
set @sTmpWareA="[##MARWareA"+ @ComputerName+"]"
@sTmpWareA 就是临时表的名称,过程中使用exec来 *** 作
Insert是T-sql中常用语句,Insert INTO table(field1,field2,...) values(value1,value2,...)这种形式的在应用程序开发中必不可少。但在实际开发、测试过程中,经常会遇到需要表复制的情况,如将一个table1的数据的部分字段复制到table2中,或者将整个table1复制到table2中,这时候就要使用SELECT INTO 和 INSERT INTO SELECT 表复制语句了。
1.INSERT INTO SELECT语句
语句形式为:Insert into Table2(field1,field2,...) select value1,value2,... from Table1
要求目标表Table2必须存在,由于目标表Table2已经存在,所以我们除了插入源表Table1的字段外,还可以插入常量。棚迅团示例如下:
--1.创建测试表create TABLE Table1
(
a varchar(10),
昌友b varchar(10),
c varchar(10),
CONSTRAINT [PK_Table1] PRIMARY KEY CLUSTERED
(
a ASC
)
) ON [PRIMARY]
create TABLE Table2
(
a varchar(10),
c varchar(10),
d int,
CONSTRAINT [PK_Table2] PRIMARY KEY CLUSTERED
(
a ASC
)
) ON [PRIMARY]
GO
--2.创建测试数据
Insert 链橘into Table1 values('赵','asds','90')
Insert into Table1 values('钱','asds','100')
Insert into Table1 values('孙','asds','80')
Insert into Table1 values('李','asds',null)
GO
select * from Table2
--3.INSERT INTO SELECT语句复制表数据
Insert into Table2(a, c, d) select a,c,5 from Table1
GO
--4.显示更新后的结果
select * from Table2
GO
--5.删除测试表
drop TABLE Table1
drop TABLE Table2
2.SELECT INTO FROM语句
语句形式为:SELECT vale1, value2 into Table2 from Table1
要求目标表Table2不存在,因为在插入时会自动创建表Table2,并将Table1中指定字段数据复制到Table2中。示例如下:
--1.创建测试表create TABLE Table1
(
a varchar(10),
b varchar(10),
c varchar(10),
CONSTRAINT [PK_Table1] PRIMARY KEY CLUSTERED
(
a ASC
)
) ON [PRIMARY]
GO
--2.创建测试数据
Insert into Table1 values('赵','asds','90')
Insert into Table1 values('钱','asds','100')
Insert into Table1 values('孙','asds','80')
Insert into Table1 values('李','asds',null)
GO
--3.SELECT INTO FROM语句创建表Table2并复制数据
select a,c INTO Table2 from Table1
GO
--4.显示更新后的结果
select * from Table2
GO
--5.删除测试表
drop TABLE Table1
drop TABLE Table2
CREATE OR REPLACE PROCEDURE PROADMININFO(ADMINNAME in varchar2,ADMINPWD in varchar2)ISBEGINselect * from userinfo where loginid=ADMINNAME and password=ADMINPWD
END PROADMININFO
PROCEDURE ZXDRB.PROADMININFO 编译错误
错误:PLS-00428: 在此 SELECT 语句中缺少 INTO 子句行:5文本:橡哗select * from userinfo where loginid=ADMINNAME and password=ADMINPWD
------解决方案--------------------------------------------------------要么使用游标,要么有几个字段定义几个变量如:SQL code CREATE OR REPLACE PROCEDURE PROADMININFO(ADMINNAME in varchar2, ADMINPWD in varchar2) IS cur_restdata tbl_rest_waiting_queue%rowtype--定义游标 begin select * into cur_restdata from userinfo where loginid=ADMINNAME and password=ADMINPWDendEND PROADMININFO
------解决方案--------------------------------------------------------select 后面缺少赋值into给变量
------解决方案--------------------------------------------------------探讨要么使用游标,要么有几个字段定义几个变量如:SQL code
CREATE OR REPLACE PROCEDURE PROADMININFO(ADMINNAME in varchar2,
ADMINPWD in varchar……
------解决方案--------------------------------------------------------END PROADMININFO 前面来个灶局end
------解决方案--------------------------------------------------------在pl/sql程序中不允许出现不带into子句的select语句。
参考代码如下:如果查询出来只有一条记录
SQL code CREATE OR REPLACE PROCEDURE PROADMININFO (adminName in varchar2, adminPWD in varchar2) IS rec userinfo%ROWTYPEBEGIN SELECT * INTO rec FROM UserInfo WHERE loginid = adminName AND password = adminPWDEND PROADMININFO
------解决方案--------------------------------------------------------procedure 不能仅仅只执行一个select语句。------解决方案--------------------------------------------------------查出来的隐如让数据应该有个容器来装它
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)