Я попал в дебаты на работе, и мне нужен совет по поводу возможных ловушек, которые я мог бы пропустить.
Представьте себе сценарий, в котором триггер используется для копирования удаленных записей в таблицу аудита. Триггер использует SELECT *. Все указывают и кричат и говорят нам, как это плохо.
Однако, если в структуру основной таблицы внесены изменения, а таблица аудита пропущена, то триггер выдаст ошибку, сообщающую людям, что таблица аудита также нуждается в модификации.
Ошибка будет обнаружена во время тестирования на наших серверах DEV. Но нам нужно обеспечить соответствие производственного процесса DEV, поэтому мы разрешаем SELECT * в производственных системах (только триггеры).
Итак, мой вопрос: меня подталкивают к удалению SELECT *, но я не уверен, как еще обеспечить автоматическую фиксацию ошибок разработки такого рода, каких-либо идей или это лучшая практика?
Я собрал пример ниже:
--Create Test Table
CREATE TABLE dbo.Test(ID INT IDENTITY(1,1), Person VARCHAR(255))
--Create Test Audit Table
CREATE TABLE dbo.TestAudit(AuditID INT IDENTITY(1,1),ID INT, Person VARCHAR(255))
--Create Trigger on Test
CREATE TRIGGER [dbo].[trTestDelete] ON [dbo].[Test] AFTER DELETE
NOT FOR REPLICATION
AS
BEGIN
SET NOCOUNT ON;
INSERT dbo.TestAudit([ID], [Person])
SELECT *
FROM deleted
END
--Insert Test Data into Test
INSERT INTO dbo.Test VALUES
('Scooby')
,('Fred')
,('Shaggy')
--Perform a delete
DELETE dbo.Test WHERE Person = 'Scooby'
ОБНОВЛЕНИЕ (перефразировать вопрос):
Я администратор базы данных и должен убедиться, что разработчики не предоставляют плохо продуманные сценарии развертывания, внося вклад в нашу документацию по передовому опыту. SELECT * вызывает ошибку в DEV, когда разработчик пропускает таблицу аудита (это защитная сеть), поэтому ошибка обнаруживается на ранней стадии процесса разработки. Но где-то в Конституции SQL - вторая поправка гласит: «Не используйте SELECT *». Так что теперь есть толчок, чтобы избавиться от сети безопасности.
Как бы вы заменили сеть безопасности, или я должен считать это лучшей практикой для триггеров?
ОБНОВЛЕНИЕ 2: (решение)
Спасибо за ваш вклад, я не уверен, что у меня есть четкий ответ, потому что это, кажется, очень серый вопрос. Но вместе вы предоставили темы для обсуждения, которые могут помочь нашим разработчикам продвинуться вперед в определении своей лучшей практики.
Спасибо Daevinза ваш вклад, ваш ответ обеспечивает основу для некоторых механизмов тестирования, которые могут реализовать наши разработчики. +1
Спасибо CM_Dayton, ваши предложения, способствующие передовому опыту, могут быть полезны всем, кто разрабатывает триггеры аудита. +1
Большое спасибо ypercube, вы много размышляли о проблемах, связанных с изменениями в определениях таблиц. +1
В заключении:
Is Select * ok in a tigger? Да, это серая зона, не слепо следуйте идеологии «Выбрать * - это плохо».
Am I asking for Trouble? Да, мы делаем больше, чем просто добавляем новые столбцы в таблицы.
SELECT *чтобы быть ленивым, но, поскольку у вас есть законная причина использовать его, он скорее серый, чем черно-белый. Вы должны попытаться сделать что-то вроде этого , но настроить его таким образом, чтобы не только иметь одинаковое количество столбцов, но и чтобы имена столбцов и типы данных были одинаковыми (поскольку кто-то может изменить типы данных и при этом вызвать проблемы в БД, которые обычно не перехватываются с вашей SELECT *«сеткой безопасности».
SELECT *в качестве защитной сетки, но она не охватит все случаи. Например, если вы уроните столбец и добавите его снова. Это изменит порядок столбцов и (если все столбцы не относятся к одному и тому же типу) вставки в таблицу аудита завершатся неудачно или приведут к потере данных из-за неявных преобразований типов.