в моем проекте (автоматизированное тестирование) я добавляю много данных в свою базу данных, которые должны быть удалены после запуска всех сценариев, но в редких случаях, когда происходит сбой выполнения, у меня иногда остаются записи, которые не были удалены.
По этой причине я решил дополнительно хранить все созданные записи в дополнительной таблице, где я храню:
Теперь я пытаюсь выбрать все записи из приведенной выше таблицы и использовать ее для создания запросов на удаление.
Можно ли это сделать в одном запросе?
SELECT * FROM AutomationTestingData AS atd
DELETE FROM atd.TableName WHERE atd.DeleteByField = atd.RecordId
Будем признательны за любую помощь, с уважением.
Привет, я думаю, вам нужно использовать EXECUTE и динамический запрос, построить курсор с помощью SELECT 'DELETE FROM' + atd.TableName + 'WHERE' + atd.DeleteByField + '= ' + atd.RecordId + ';'
вы можете использовать этот синтаксис:
delete T1
from Table1 T1 join Table2.T2 on T1.SomeField=T2.SomeField
where Some Condition
Привет, если я понимаю все, что вы пытаетесь, я думаю, что это может ответить:
SET NOCOUNT ON;
DECLARE @query varchar(4000);
PRINT '-------- Deleting rows --------';
DECLARE deleting_cursor CURSOR FOR
SELECT 'DELETE FROM ' + atd.TableName + ' WHERE ' + atd.DeleteByField + ' = ' + atd.RecordId + ';'
FROM AutomationTestingData AS atd
OPEN deleting_cursor
FETCH NEXT FROM deleting_cursor
INTO @query
WHILE @@FETCH_STATUS = 0
BEGIN
EXEC(@Query)
FETCH NEXT FROM deleting_cursor
INTO @query
END
CLOSE deleting_cursor;
DEALLOCATE deleting_cursor;
ВЫПОЛНИТЬ динамический SQL Server: https://docs.microsoft.com/en-us/sql/t-sql/language-elements/execute-transact-sql?view=sql-server-2017
Спасибо за ответ, не могли бы вы сказать мне, где вы объявляете «atd»?
@Matthewek, да, извините, я пропал, у меня есть обновленный ответ.
Это жизнеспособный способ сделать это полностью автоматическим. Одно улучшение: вам не нужно писать оператор удаления для каждой строки в объявлении, см. редактирование в моем ответе.
Я получаю сообщение «Сообщение 245, уровень 16, состояние 1, строка 13. Преобразование не удалось при преобразовании значения varchar»; к типу данных int.' Попробую разобраться, еще раз спасибо за отличное решение.
вам нужно преобразовать ` + adt.RecordId + ` вот так ` + convert (varchar (10), adt.RecordId) + `, чтобы исправить это
Рассмотрите возможность изменения определения курсора, как в редактировании моего ответа, оно должно быть быстрее и не требует преобразований.
Вы можете написать оператор удаления для каждой таблицы, например
delete from Company
where id in ( select RecordId from adt where adt.TableName = 'Company')
delete from PickListValues
where id in ( select RecordId from adt where adt.TableName = 'PickListValues')
Конечно, это не очень динамично, но все же быстрее, чем динамический sql и курсор.
Редактировать
ЕСЛИ вам нужен полностью автоматический режим, используйте dynamic sql
, как предложил @pascalsanchez.
Я бы изменил курсор вот так
declare deleting_cursor cursor for
select 'delete from ' + adt.TableName +
'where ' + adt.DeleteByField + ' in (select RecordID from adt where adt.TableName = ''' + adt.TableName + ''')
from AutomationTestingData AS atd
group by adt.TableName, adt.DeleteByField
Это жизнеспособное решение, но, поскольку оно используется для «автоматизированного тестирования», я хотел бы максимально автоматизировать его :), поэтому мне не нужно каждый раз обновлять этот запрос новыми таблицами, как я понял. out, будет выбирать все из моей таблицы, используя java, создавая новый класс, который содержит все три поля, сортирует их и создает несколько DELETE FROM dbo." + tableName + " WHERE (" + whereColumn + " IN (" + ids +" )) Однако, спасибо
Нет проблем, в этом случае вы также можете подумать о том, чтобы сделать это на сервере sql, используя курсор и динамический sql, как это было предложено @pascalsanchez.
Вы можете использовать динамический sql для этого