Estoy atrapado en un debate en el trabajo, y necesito algunos consejos sobre posibles trampas que podría pasar por alto.
Imagine un escenario en el que se utiliza un disparador para copiar registros eliminados a una tabla de auditoría. El activador usa SELECT *. Todos señalan y gritan y nos dicen lo malo que es esto.
Sin embargo, si se realiza una modificación en la Estructura de la Tabla principal, y se pasa por alto la Tabla de auditoría, entonces el Disparador generará un error para que las personas sepan que la tabla de Auditoría también necesita modificación.
El error se detectará durante las pruebas en nuestros servidores DEV. Pero debemos asegurarnos de que los Matches de producción sean DEV, por lo que permitimos SELECCIONAR * en los Sistemas de producción (solo disparadores).
Entonces, mi pregunta es: me están presionando para eliminar SELECT *, pero no estoy seguro de qué otra manera asegurarme de que estamos capturando automáticamente errores de desarrollo de esta naturaleza, ¿alguna idea o es esta mejor práctica?
He reunido un ejemplo a continuación:
--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'
ACTUALIZACIÓN (reformulación de la pregunta):
Soy un DBA y necesito asegurarme de que los Desarrolladores no proporcionen scripts de implementación mal pensados al contribuir a nuestra Documentación de mejores prácticas. SELECT * provoca un error en DEV cuando el desarrollador pasa por alto la tabla de auditoría (esta es una red de seguridad), por lo que el error se detecta al principio del proceso de desarrollo. Pero en algún lugar de la Constitución de SQL: la segunda enmienda dice "No usarás SELECT *". Así que ahora hay un impulso para deshacerse de la red de seguridad.
¿Cómo reemplazaría la red de seguridad, o debería considerar que esta es la mejor práctica para los activadores?
ACTUALIZACIÓN 2: (solución)
Gracias por todos sus comentarios, no estoy seguro si tengo una respuesta clara porque parece ser un tema muy gris. Pero colectivamente, ha proporcionado puntos de discusión que pueden ayudar a nuestros desarrolladores a avanzar en la definición de sus mejores prácticas.
Gracias Daevinpor su contribución, su respuesta proporciona la base para algunos mecanismos de prueba que nuestros Desarrolladores pueden implementar. +1
Gracias CM_Dayton, sus sugerencias que contribuyen a las mejores prácticas pueden ser beneficiosas para cualquier persona que esté desarrollando Desencadenadores de auditoría. +1
Muchas gracias a ypercube, has pensado mucho sobre los problemas relacionados con las tablas que experimentan diferentes formas de cambios de definición. +1
En conclusión:
Is Select * ok in a tigger? Sí, es un área gris, no siga ciegamente la ideología "Seleccionar * es malo".
Am I asking for Trouble? Sí, hacemos más que solo agregar nuevas columnas a las tablas.
SELECT *ser perezoso, pero como tienes una razón legítima para usarlo, es más gris que blanco y negro. Lo que debe intentar hacer es algo como esto , pero ajústelo para que no solo tenga el mismo recuento de columnas, sino que los nombres de columna y los tipos de datos sean los mismos (ya que alguien podría cambiar los tipos de datos y aún causar problemas en la base de datos que normalmente no se detectan) con su SELECT *'red de seguridad'.
SELECT *como red de seguridad, pero no atrapará todos los casos. Por ejemplo, si suelta una columna y la agrega nuevamente. Esto cambiará el orden de las columnas y (a menos que todas las columnas sean del mismo tipo) las inserciones en la tabla de auditoría fallarán o provocarán la pérdida de datos debido a las conversiones de tipo implícitas.