カーソルを書こうとしています。 sys.dm_exec_sessionsからログイン名と時刻を取得するためのテーブルを作成しました。ここで、ログインがすでに存在する場合、ログイン時間を最後のログイン時間に更新するカーソルを記述し、ログインがテーブルに存在しない場合に行を挿入する必要があります。私は以下を思いつきましたが、残念ながら、サブクエリが複数の値を返すというエラーが発生します。何か案は???
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
この行が原因でエラーが発生していると思います
If (Select Login from [dbo].[LoginsForDBUserList]) = @log
等号の左側から複数の行が返され、単一の値@log
と比較しようとしています。
元のクエリにいくつかの調整を加えましたが、うまくいきました。これを試してみてください:
--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
@スコットはあなたの質問に対する回答をすでに与えています。しかし、そのカーソルを捨てて、SETベースのコードをここで使用できることを願っています。
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;