Ich bin in eine Debatte bei der Arbeit verwickelt und brauche Ratschläge zu möglichen Fallstricken, die ich übersehen könnte.
Stellen Sie sich ein Szenario vor, in dem ein Trigger verwendet wird, um gelöschte Datensätze in eine Überwachungstabelle zu kopieren. Der Trigger verwendet SELECT *. Jeder zeigt und schreit und sagt uns, wie schlimm das ist.
Wenn jedoch eine Änderung an der Struktur der Haupttabelle vorgenommen wird und die Überwachungstabelle übersehen wird, generiert der Auslöser einen Fehler, der die Benutzer darüber informiert, dass die Überwachungstabelle ebenfalls geändert werden muss.
Der Fehler wird beim Testen auf unseren DEV-Servern abgefangen. Wir müssen jedoch sicherstellen, dass die Produktion DEV entspricht, damit wir SELECT * in Produktionssystemen zulassen (nur Trigger).
Meine Frage lautet also: Ich werde dazu gedrängt, SELECT * zu entfernen, aber ich bin mir nicht sicher, wie ich sonst sicherstellen kann, dass wir automatisch Entwicklungsfehler dieser Art, Ideen oder Best Practices erfassen.
Ich habe unten ein Beispiel zusammengestellt:
--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 (Frage umformulieren):
Ich bin ein DBA und muss sicherstellen, dass Entwickler keine schlecht durchdachten Bereitstellungsskripte bereitstellen, indem sie zu unserer Best-Practice-Dokumentation beitragen. SELECT * verursacht einen Fehler in DEV, wenn der Entwickler die Audit-Tabelle übersieht (dies ist ein Sicherheitsnetz), sodass der Fehler früh im Entwicklungsprozess erkannt wird. Aber irgendwo in der SQL-Verfassung - 2. Änderung heißt es "Du sollst SELECT * nicht verwenden". Jetzt gibt es also einen Anstoß, das Sicherheitsnetz loszuwerden.
Wie würden Sie das Sicherheitsnetz ersetzen, oder sollte ich dies als Best Practice für Trigger betrachten?
UPDATE 2: (Lösung)
Vielen Dank für all Ihre Beiträge. Ich bin mir nicht sicher, ob ich eine klare Antwort habe, da dies ein sehr graues Thema zu sein scheint. Gemeinsam haben Sie jedoch Diskussionspunkte bereitgestellt, die unseren Entwicklern helfen können, ihre Best Practice zu definieren.
Vielen Dank Daevin
für Ihren Beitrag. Ihre Antwort liefert die Grundlage für einige Testmechanismen, die unsere Entwickler implementieren können. +1
Vielen Dank CM_Dayton
, Ihre Vorschläge, die zu Best Practices beitragen, können für jeden von Vorteil sein, der Audit-Trigger entwickelt. +1
Vielen Dank ypercube
, Sie haben viel über die Probleme mit Tabellen nachgedacht, bei denen verschiedene Formen von Definitionsänderungen vorgenommen wurden. +1
Abschließend:
Is Select * ok in a tigger?
Ja, es ist eine Grauzone. Folgen Sie nicht blind der Ideologie "Select * is Bad".
Am I asking for Trouble?
Ja, wir fügen Tabellen nicht nur neue Spalten hinzu.
SELECT *
Faulheit zu, aber da Sie einen legitimen Grund haben, es zu benutzen, ist es grauer als schwarz-weiß. Was sollten Sie versuchen, etwas zu tun , wie diese , aber es nur einstellen , die gleiche Spaltenanzahl nicht hat, sondern dass die Spaltennamen und Datentypen gleich sind (da jemand Typen Daten ändern könnte und immer noch zu Problemen in der db normalerweise nicht gefangen mit Ihrem SELECT *
'Sicherheitsnetz'.
SELECT *
als Sicherheitsnetz zu verwenden, aber es wird nicht alle Fälle erfassen. Zum Beispiel, wenn Sie eine Spalte löschen und erneut hinzufügen. Dadurch wird die Reihenfolge der Spalten geändert, und (sofern nicht alle Spalten vom gleichen Typ sind) die Einfügungen in die Prüftabelle schlagen fehl oder führen aufgrund der impliziten Typkonvertierungen zu Datenverlust.