У меня есть очень общий набор из трех таблиц, в которых хранятся все мои данные, которая работает блестяще (речь идет небольшое количество данных здесь)SQL Server: рекурсивная хранимая процедура
DataContainer - Управляет «запись»
PK - DataContainerId
FK - ParentDataContainerId
FM - ModelEntityId
DataInstance - Руководит управления версиями
PK - DataInstanceId
FK - DataContainerId
IsCurrent [bit] NOT NULL CONSTRAINT [DF_DataInstance_IsCurrent] DEFAULT ((1)),
ModifiedBy [nvarchar](50) NOT NULL CONSTRAINT [DF_DataInstance_ModifiedBy] DEFAULT (suser_sname()),
ModifiedDateTime [datetime] NOT NULL CONSTRAINT [DF_DataInstance_ModifiedDateTime] DEFAULT (getdate()),
DataValue
PK - DataValueId
FK - DataInstanceId
FK - ModelEntityId
ValueText --the actual values
Проблема: Когда запись удаляется мне нужно пометить все дочерние записи для удаления.
Покушение
--flag current record as deleted
update DataInstance
set IsCurrent = 0
Where DataContainerId = @DataContainerId
And (@ModelContainerId is null or @ModelContainerId = ModelContainerId)
--remove all child records
declare db_cursor for
select sc.DataContainerId as 'ChildDataContainerId' from DataInstance di
inner join datacontainer dc on dc.datacontainerId = di.datacontainerId
where parentdatacontainerId = @DataContainerId
declare @ChildDataContainerId int
open db_cursor
fetch next from db_cursor into @ChildDataContainerId
while @@fetch_status = 0
begin
exec dataInstance_Delete null, @ChildDataContainerId --current sp
end
close db_cursor
deallocate db_cursor
Проблема заключается в том, что я не могу использовать курсоры recursivly (как я получаю сообщение об ошибке, что курсор уже открыт), так что это СП будет работать только один уровень.
Есть ли более хитрый способ сделать это?
Хранение всех данных в одной таблице, а затем, используя курсоры для обработки ваших записей практики, которые вы должны получить от , Вы просите головную боль, когда игнорируете мудрость нормализации ваших данных и силу установленной логики, для которой был разработан SQL ... Возможно, вам стоит подумать о рефакторинге для вашей собственной пользы позже? – Tahbaza
Поскольку я ненавижу палочки в грязи, которые просто публикуют отрицательные замечания, а затем уходят, вот одно решение вашей проблемы, если вы решите вспахать вперед: используйте язык программирования приложений вне SQL для выполнения рекурсии. Они обычно не ограничены правилами рекурсивных вызовов, и вы можете легче обрабатывать записи с помощью набора записей или эквивалента, если вы предпочитаете логику строки. Счастливое кодирование ... – Tahbaza
Я должен согласиться с Tahbaza, но если вы настаиваете на этом маршруте, я бы использовал триггер. Триггеры могут выполняться рекурсивно (до определенного (настраиваемого уровня)). –