好吧,所以这个有点令人困惑,我不太确定如何使用TSQL或者甚至可以使用TSQL。
我有一个使用Microsoft SQL Server 2008的软件。有一个名为“iLicuserinfo”的表,其中包含已登录用户的列表,用于为该人员分配并发用户许可证。该表的一个例子如下......
根据要求,样本数据为文本而非图像......
WSID LoginName SessionID Last_Login
WK-221 asmith 370 2015-11-17 13:51:32.543
WK-221 asmith 380 2015-11-17 14:30:05.473
WK-220 jcavan 70 2015-11-17 07:20:21.573
WK-230 ccarmore 450 2015-11-17 08:14:42.747
WK-247 jspoon 160 2015-11-17 11:22:07.060
WK-238 mcalhone 10 2015-11-17 14:24:05.133
WK-250 bcasey 270 2015-11-17 10:48:51.230
WK-203 camel 260 2015-11-17 13:19:36.613
WK-205 kwilson 130 2015-11-17 13:32:52.010
会发生的情况是,最多允许有25个并发用户,并且会强制执行。该软件很糟糕(并且供应商拒绝纠正它),并且经常会崩溃并且不会清除iLicuserinfo列表中的许可证。
更正此问题的过程是查询该表,查找具有匹配的WSID的任何行(这是许可证所绑定的工作站的主机名),找到两个或更多个副本中哪个是最旧的,取该行的SessionID,然后运行以下查询将其清除....
EXEC dbo.CleanAppSessions
WAITFOR DELAY '00:00:03'
EXEC dbo.login_proc
WAITFOR DELAY '00:00:03'
EXEC dbo.sysCleanAppSessions
WAITFOR DELAY '00:00:03'
EXEC dbo.sysReleaseAppSession @pAppSessionId = NULL
其中“NULL”替换为发现的副本的会话ID。
我想要做的是创建一个拉取许可证表的查询,按WSID排序,找到重复项,然后重复这些查询获取SessionID,然后使用该会话ID代替“NULL”运行上面的查询。 / p>
使用上面链接中显示的表数据的屏幕截图,会手动清除SessionID为370的行,因为上一次登录是在SessionID 380之前一小时。
到目前为止,我找不到一种方法来形成一个查询,其中包含比较行所需的逻辑,并标记哪些是可以清除的实际挂起的许可证,然后通过上面的脚本运行一个或多个SessionID一次一个。
这看起来对我来说是一项非常重要的工作,但也许有一个SQL quru可以指出我正确的方向实现我想做的事情?
答案 0 :(得分:0)
要查找欺骗并获取最早的时间戳,请使用汇总查询。
SELECT SessionID
FROM Table INNER JOIN (
SELECT WSID,
MIN(timestampField) AS timestampField
FROM Table
GROUP BY WSID
HAVING COUNT(*) > 1
) t ON Table.WSID = t.WSID AND
Table.timestampField = t.timestampField
要将其循环通过其余代码,请使用cursor。
答案 1 :(得分:0)
使用ROW()函数,你可以得到重复的记录(注意我抓住那些> 1)然后循环调用你的函数。我假设您只需要运行其他SP一次,这样它们就不在循环中了。
DECLARE @Table as table(WSID varchar(50),LoginName varchar(50),SessionID int,Last_Login datetime)
INSERT INTO @Table values ('WK-221','asmith',370,'2015-11-17 13:51:32')
INSERT INTO @Table values ('WK-221','asmith',380,'2015-11-17 14:30:05')
INSERT INTO @Table values ('WK-220','jcavan',70,'2015-11-17 07:20:21')
INSERT INTO @Table values ('WK-230','ccarmore',450,'2015-11-17 08:14:42')
DECLARE @SessionId int
EXEC dbo.CleanAppSessions
WAITFOR DELAY '00:00:03'
EXEC dbo.login_proc
WAITFOR DELAY '00:00:03'
EXEC dbo.sysCleanAppSessions
WAITFOR DELAY '00:00:03'
DECLARE crsr_Tmp CURSOR SCROLL FOR
SELECT SessionID FROM (
SELECT *,ROW_NUMBER() OVER(PARTITION BY WSID ORDER BY Last_Login desc) Row FROM @Table
) Tmp
where Row > 1
OPEN crsr_Tmp;
--Start FETCH process
FETCH NEXT FROM crsr_Tmp
INTO @SessionId
WHILE @@FETCH_STATUS = 0
BEGIN
EXEC dbo.sysReleaseAppSession @pAppSessionId = @SessionId
--Grab next record from cursor
FETCH NEXT FROM crsr_Tmp
INTO @SessionId
END
DEALLOCATE crsr_Tmp --clean up cursor