Estou preso em um debate no trabalho e preciso de alguns conselhos sobre possíveis armadilhas que eu poderia estar ignorando.
Imagine um cenário em que um acionador é usado para copiar registros excluídos em uma tabela de auditoria. O gatilho usa SELECT *. Todo mundo aponta e grita e nos diz o quanto isso é ruim.
No entanto, se uma modificação for feita na Estrutura da tabela principal, e a tabela de auditoria for ignorada, o gatilho gerará um erro informando às pessoas que a tabela de auditoria também precisa de modificação.
O erro será detectado durante o teste em nossos servidores DEV. Mas precisamos garantir a DEV de correspondências de produção, para que permitamos SELECT * em sistemas de produção (somente gatilhos).
Portanto, minha pergunta é: estou sendo pressionado a remover o SELECT *, mas não tenho certeza de que outra forma garantir que estamos capturando automaticamente erros de desenvolvimento dessa natureza, de alguma idéia ou é uma prática recomendada?
Reunimos um exemplo abaixo:
--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'
UPDATE (reformular a pergunta):
Sou DBA e preciso garantir que os desenvolvedores não forneçam scripts de implantação mal pensados, contribuindo para a documentação de práticas recomendadas. SELECT * causa um erro na DEV quando o desenvolvedor ignora a tabela de auditoria (esta é uma rede de segurança), portanto o erro é detectado no início do processo de desenvolvimento. Mas em algum lugar na Constituição do SQL - a segunda alteração diz "Não usaremos SELECT *". Então agora há um esforço para se livrar da rede de segurança.
Como você substitui a rede de segurança ou devo considerar essa prática recomendada para os acionadores?
ATUALIZAÇÃO 2: (solução)
Obrigado por todas as suas contribuições, não tenho certeza se tenho uma resposta clara, porque este parece ser um assunto muito cinzento. Mas, coletivamente, você forneceu pontos de discussão que podem ajudar nossos desenvolvedores a avançar na definição de suas Melhores Práticas.
Obrigado Daevin
por sua contribuição, sua resposta fornece as bases para alguns mecanismos de teste que nossos desenvolvedores podem implementar. +1
Obrigado CM_Dayton
, suas sugestões que contribuem para as práticas recomendadas podem ser benéficas para qualquer um que esteja desenvolvendo os Acionadores de Auditoria. +1
Muito obrigado ypercube
, você refletiu bastante sobre os problemas relacionados a tabelas que sofrem diferentes formas de alteração de definição. +1
Em conclusão:
Is Select * ok in a tigger?
Sim, é uma área cinzenta, não siga cegamente a ideologia "Selecionar * é ruim".
Am I asking for Trouble?
Sim, fazemos mais do que apenas adicionar novas colunas às tabelas.
SELECT *
ser preguiçoso, mas como você tem um motivo legítimo para usá-lo, é mais cinza que preto e branco. O que você deve tentar fazer é algo como isso , mas ajustá-lo para não só têm a mesma contagem de coluna, mas que os nomes de colunas e tipos de dados são os mesmos (desde que alguém poderia alterar os tipos de dados e ainda causa problemas no db normalmente não pegou com sua SELECT *
'rede de segurança'.
SELECT *
como rede de segurança, mas ela não pega todos os casos. Por exemplo, se você soltar uma coluna e adicioná-la novamente. Isso mudará a ordem das colunas e (a menos que todas as colunas sejam do mesmo tipo) as inserções na tabela de auditoria falharão ou resultarão em perda de dados devido às conversões implícitas de tipo.