我在工作中陷入一场辩论,我需要一些有关我可能会忽略的陷阱的建议。
想象一下使用触发器将已删除记录复制到审核表的情况。触发器使用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'
更新(重新表达问题):
我是一名DBA,并且需要通过贡献给我们的最佳做法文档来确保开发人员不会提供经过深思熟虑的部署脚本。当开发人员忽略审核表(这是一个安全网)时,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 *
用作安全网的想法,但并不能解决所有情况。例如,如果您删除一列并再次添加它。这将更改列的顺序,并且(除非所有列均为同一类型),由于隐式类型转换,插入到审计表中将失败或导致数据丢失。