J'essaie d'écrire un curseur. J'ai créé un tableau pour capturer le nom et l'heure de connexion à partir de sys.dm_exec_sessions. Maintenant, je dois écrire un curseur pour mettre à jour l'heure de connexion à la dernière heure de connexion si la connexion existe déjà et insérer une ligne au cas où la connexion n'existe pas dans ma table. J'ai trouvé la suite, mais malheureusement, je reçois une erreur avec la sous-requête renvoyant plus d'une valeur pour elle. Des idées???
declare @log as varchar(200)
declare @log_time as datetime
declare LoginsSize cursor for
SELECT login_name, login_time
FROM sys.dm_exec_sessions
open LoginsSize
fetch next from LoginsSize into @log, @log_time
while( @@fetch_status = 0)
begin
If (Select Login from [dbo].[LoginsForDBUserList]) = @log
Begin
UPDATE [dbo].[LoginsForDBUserList]
SET LastLoginTime = @log_time
WHERE [login]= @log
END
Else
Begin
Insert Into [dbo].[LoginsForDBUserList]
SELECT login_name, login_time
FROM sys.dm_exec_sessions
END
fetch next from LoginsSize into @log, @log_time
close LoginsSize
deallocate LoginsSize
end
Je pense que cette erreur est générée à cause de cette ligne
If (Select Login from [dbo].[LoginsForDBUserList]) = @log
Plusieurs lignes sont renvoyées du côté gauche du signe égal et tentent d'être comparées à la valeur unique @log
.
J'ai apporté quelques ajustements à votre requête d'origine et cela fonctionne pour moi. Essayez ceci:
--demo setup
DROP TABLE IF EXISTS LoginsForDBUserList
GO
CREATE TABLE LoginsForDBUserList (
LOGIN VARCHAR(200)
,LastLoginTime DATETIME
)
--Adjustments to your original process
DECLARE @log AS VARCHAR(200)
DECLARE @log_time AS DATETIME
DECLARE LoginsSize CURSOR
FOR
SELECT login_name
,login_time
FROM sys.dm_exec_sessions
OPEN LoginsSize
FETCH NEXT
FROM LoginsSize
INTO @log
,@log_time
WHILE (@@fetch_status = 0)
BEGIN
IF EXISTS (
SELECT LOGIN
FROM LoginsForDBUserList
WHERE LOGIN = @log
)
BEGIN
UPDATE LoginsForDBUserList
SET LastLoginTime = @log_time
WHERE [login] = @log
END
ELSE
BEGIN
INSERT INTO LoginsForDBUserList
SELECT login_name
,login_time
FROM sys.dm_exec_sessions
END
FETCH NEXT
FROM LoginsSize
INTO @log
,@log_time
END
CLOSE LoginsSize
DEALLOCATE LoginsSize
SELECT *
FROM LoginsForDBUserList
@Scott a déjà donné la réponse à votre question. Mais j'espère que vous pourrez abandonner ce curseur et utiliser un code basé sur SET ici.
UPDATE a
SET LastLoginTime = b.login_time
FROM [dbo].[LoginsForDBUserList] a
JOIN sys.dm_exec_sessions b
ON a.login = b.login_name;
IF EXISTS ( SELECT 1
FROM sys.dm_exec_sessions b
LEFT JOIN [dbo].[LoginsForDBUserList] a
ON a.login = b.login_name
WHERE a.login IS NULL)
BEGIN
INSERT INTO [dbo].[LoginsForDBUserList]
SELECT login_name,
login_time
FROM sys.dm_exec_sessions b
LEFT JOIN [dbo].[LoginsForDBUserList] a
ON a.login = b.login_name
WHERE a.login IS NULL;
END;