Я использую SQL Server в качестве хранилища для анализа файлов журнала. Эти файлы журналов имеют своего рода иерархию бизнес-процессов (в данном примере это работник):
Log Entry Id, Log Message
1 , Start Worker
2 , Do Cool Stuff
3 , Start Worker
4 , Do further cool stuff
5 , Start Worker
6 , This is a lot of working
7 , End worker
8 , End worker
9 , End worker
Мне нужно связать записи в журнале с текущим работником. Правило довольно простое: как только будет найдено сообщение «Начать работу», назначьте этому сотруднику все последующие записи журнала. В примере иерархии это означает:
Log Entry Id, Log Message , Worker
1 , Start Worker , 1 (we take the entry id as worker id)
2 , Do Cool Stuff , 1
3 , Start Worker , 3
4 , Do further cool stuff , 3
5 , Start Worker , 5
6 , This is a lot of working , 5
7 , End worker , 5
8 , End worker , 3
9 , End worker , 1
В настоящее время я использую хранимую процедуру, перебирающую все записи журнала с курсором, который в основном использует стек для установления связи между записями журнала и рабочими:
CREATE PROCEDURE CalculateRelations
AS
BEGIN
DECLARE entries_cur CURSOR FOR
SELECT Id, LogMessage
FROM LogEntries
ORDER BY Id;
DECLARE @Id BIGINT;
DECLARE @LogMessage VARCHAR(128);
DECLARE @ParentWorker BIGINT;
DECLARE @WorkerStack VARCHAR(MAX) = '';
OPEN entries_cur;
FETCH NEXT FROM entries_cur INTO @Id, @LogMessage;
WHILE @@FETCH_STATUS = 0
BEGIN
EXEC dbo.GetParentWorker @WorkerStack OUT, @Id, @LogMessage, @ParentWorker OUT;
UPDATE LogEntries
SET ParentWorker = @ParentWorker
WHERE Id = @Id;
FETCH NEXT FROM entries_cur INTO @Id, @LogMessage;
END;
CLOSE entries_cur;
DEALLOCATE entries_cur;
END;
GO
GetParentWorker
- это хранимая процедура, которая использует данную VARCHAR
переменную WorkerStack
в качестве стека. Это значит
- Сообщение «Начать работу» приводит к добавлению (push)
Id
к этому VARCHAR
- Сообщение «Конечный работник» приводит к удалению и возврату (всплывающего) последнего
Id
из этого VARCHAR
- все остальные сообщения приводят к тому, что просто возвращаются (читаются) последние
Id
из этого VARCHAR
без его изменения
Теперь мне интересно, можно ли заменить эту конструкцию курсора на оператор UPDATE
. Я не настолько глубоко разбираюсь в SQL и SQL Server, но может быть возможно реализовать это с помощью динамического присваивания переменной CASE
и использования возвращаемого значения GetParentWorker
?