首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 数据库 > SQL Server >

关于sqlserver临时表的有关问题,

2013-08-23 
关于sqlserver临时表的问题,请教高手!现在在做一个项目,用到的功能是这样的!每个表都有触发器,在更新,追加

关于sqlserver临时表的问题,请教高手!
现在在做一个项目,用到的功能是这样的!
每个表都有触发器,在更新,追加的时候,会给记录的登陆用户,登陆机器名这两个字段设定值!这两个值是在触发器中从本地临时表中取到的!
而临时表是在应用程序中创建的,因为sqlserver的本地临时表是根据会话来的,会话结束了,这个临时表就被删除掉了,所以在应用程序中,使用ExcuteNoQuery()创建临时表时(在存储过程中创建也一样 执行EXEC后会话结束),会话就结束了,临时表就被删除了,
这时更新数据库数据库数据,触发触发器触发时根本找不到之前创建的临时表了,所以不能正确设定登陆用户,登陆机器名了!
如果用全局临时表的话,又怕有并发问题,
有没有高手知道有什么设定或是别的解决办法,请指教啊! SQL?Server 数据库
[解决办法]
如果用全局临时表的话,又怕有并发问题?什么问题?
楼主再描述一下,你最根本的意图吧。如果存在多用户登陆(并发登陆),那么你的触发器,如何知道,哪个临时表是自己的?感觉设计得有问题,跟临时表没关系
[解决办法]
没用过postgresql数据库。不太明白它的用法。
想问一下,楼主是否这样:先创建一个临时表,然后,往某些表中INSERT或UPDATE,同时要记录这个操作是哪个登陆用户所为。上面这些操作,是在同一个存储过程中?
[解决办法]
每一次登录后,你都返回用户名ID和机器名,并且把它当成全局变量。
下次操作时直接用这个全局变量去更新别的就可以了。

每个表都建用触器,这样不好。
[解决办法]

引用:
Quote: 引用:

没用过postgresql数据库。不太明白它的用法。
想问一下,楼主是否这样:先创建一个临时表,然后,往某些表中INSERT或UPDATE,同时要记录这个操作是哪个登陆用户所为。上面这些操作,是在同一个存储过程中?

不在一个存储过程。
这样说吧,首先开启了个数据库事物,然后执行一个sql(sqlserver里只能是存储过程或是PLSQL语句)创建了一个临时表,然后执行另一个往某个表中INSERT或UPDATE的sql语句,这个语句执行时会触发触发器,在触发器里对当前更新或追加的数据做一些修改(就是设定用户名和机器名),然后更新或插入到数据库,然后提交事物。

楼主只需要把创建临时表的SQL和INSERT或UPDATE的SQL语句,放在同一个事务里,即可。参考下面的测试:
USE CSDN
go
--测试数据
CREATE TABLE trigger_test(id INT,SPID INT, name CHAR(8000))--加个name字段,让插入的2条数据,分别放在2个页面上,防止闩锁对测试的影响
go
--创建触发器
CREATE TRIGGER tr_test1 ON dbo.trigger_test
AFTER INSERT, UPDATE
as
BEGIN
UPDATE A
SET a.spid = (SELECT TOP(1) spid FROM #temp)--请明这里访问的#temp表,只是当前登陆用户的
from trigger_test A
INNER JOIN INSERTED B
ON a.id = b.id
END
go

--第一个连接,分两步执行:
BEGIN TRAN
--#1.创建临时表
IF object_id('tempdb..#temp', 'u') IS NOT NULL
DROP TABLE #temp
CREATE TABLE #TEMP (SPID INT) 
INSERT #temp(SPID) SELECT @@SPID--第一步执行到这儿时,停止,再去另外一个连接中的所有SQL。然后再回来,执行完下面的SQL



--#2.执行insert或update语句
INSERT dbo.trigger_test (id, name) VALUES(5, '5')

--#3.触发触发器
COMMIT TRAN


--第二个连接,一下子执行完
USE CSDN
go

BEGIN TRAN
--#1.创建临时表
IF object_id('tempdb..#temp', 'u') IS NOT NULL
DROP TABLE #temp
CREATE TABLE #TEMP (SPID INT) 
INSERT #temp(SPID) SELECT @@SPID

--#2.执行insert或update语句
INSERT dbo.trigger_test (id, name) VALUES(0, '0')

--#3.触发触发器
COMMIT TRAN

--查看结果
SELECT * FROM trigger_test
/*
idSPIDname
0650
5525
*/


[解决办法]
引用:
代码结构大概是这样

string strsql = "select @userid,@userNm into #pro_set";

//这里追加一些参数

com.Parameters.Add(prmFuncName);

//执行创建临时表的sql
com.ExecuteNonQuery();

//这里调用了一个更新或追加的sql(执行这个sql时会触发触发器  before insert
也是在触发的时候更改要反映到数据库的记录,这时临时表已经看不到了)

object obj = invocation.Proceed();

//提交数据库事物

current.Commit();

临时表只在当前作用域可见,所以楼主需要把两步合并为一步,即可
[解决办法]
--SQL SERVER 的临时表达不到postgresql的效果,建议:
--方法1
com.ExecuteNonQuery();--生成一个guid+机器名+登陆名,三个字段缓存到实体表
object obj = invocation.Proceed();--把GUID传给这个函数,从上面的实体表中取到相应数据

--方法2
com.ExecuteNonQuery();--删除这行
object obj = invocation.Proceed(); --把删除的那行代码放在这个里面的SQL中

热点排行