Necesito escribir un desencadenador Insertar, Actualizar en la tabla A que eliminará todas las filas de la tabla B cuya columna (digamos Desc) tiene valores como el valor insertado / actualizado en la columna de la tabla A (digamos Col1). ¿Cómo podría escribirlo para poder manejar los casos de actualización e inserción? ¿Cómo determinaría si el disparador se ejecuta para una actualización o inserción?
fuente
fuente
Muchas de estas sugerencias no se tienen en cuenta si ejecuta una declaración de eliminación que no elimina nada.
Supongamos que intenta eliminar donde una ID equivale a algún valor que no existe en la tabla.
Todavía se llama a su desencadenador, pero no hay nada en las tablas eliminadas o insertadas.
Use esto para estar seguro:
Un agradecimiento especial a @KenDog y @Net_Prog por sus respuestas.
Construí esto a partir de sus guiones.
fuente
Estoy usando lo siguiente, también detecta correctamente las declaraciones de eliminación que no eliminan nada:
fuente
Después de mucha búsqueda, no pude encontrar un ejemplo exacto de un solo desencadenador de SQL Server que maneje las (3) tres condiciones de las acciones de activación INSERTAR, ACTUALIZAR y ELIMINAR. Finalmente encontré una línea de texto que hablaba sobre el hecho de que cuando ocurre una ELIMINACIÓN o ACTUALIZACIÓN, la tabla BORRADA común contendrá un registro para estas dos acciones. Basado en esa información, creé una pequeña rutina de Acción que determina por qué se activó el disparador. Este tipo de interfaz a veces se necesita cuando hay una configuración común y una acción específica que se produce en un disparador INSERT vs. UPDATE. En estos casos, crear un disparador separado para la ACTUALIZACIÓN y la INSERCIÓN se convertiría en un problema de mantenimiento. (es decir, ¿se actualizaron ambos disparadores correctamente para la corrección necesaria del algoritmo de datos comunes?)
Con ese fin, me gustaría dar el siguiente fragmento de código de evento de disparador múltiple para manejar INSERT, UPDATE, DELETE en un disparador para un Microsoft SQL Server.
fuente
Creo que anidado es un poco confuso y:
;)
fuente
fuente
Prueba esto..
fuente
Si bien también me gusta la respuesta publicada por @Alex, ofrezco esta variación a la solución de @ Graham anterior
esto usa exclusivamente la existencia de registros en las tablas INSERTED y UPDATED, en lugar de usar COLUMNS_UPDATED para la primera prueba. También proporciona alivio al programador paranoico sabiendo que el caso final se ha considerado ...
obtendrá NOOP con una declaración como la siguiente:
fuente
END
está sangrado incorrectamente! (haciendo que se pregunte dóndeBEGIN
está cerrado el primero )Esta podría ser una forma más rápida:
fuente
Un problema potencial con las dos soluciones ofrecidas es que, dependiendo de cómo estén escritas, una consulta de actualización puede actualizar registros cero y una consulta de inserción puede insertar registros cero. En estos casos, los conjuntos de registros insertados y eliminados estarán vacíos. En muchos casos, si los conjuntos de registros insertados y eliminados están vacíos, es posible que desee salir del disparador sin hacer nada.
fuente
Encontré un pequeño error en la solución Grahams, de lo contrario genial:
Debería ser IF COLUMNS_UPDATED () < > 0 - insertar o actualizar en
lugar de> 0 probablemente porque el bit superior se interpreta como el bit de signo entero FIRMADO ... (?). Entonces en total:
fuente
Esto hace el truco para mí:
Como no todas las columnas se pueden actualizar a la vez, puede verificar si una columna en particular se está actualizando de la siguiente manera:
fuente
fuente
Me gustan las soluciones que son "elegantes en informática". Mi solución aquí golpea los pseudotables [insertado] y [eliminado] una vez cada uno para obtener sus estados y coloca el resultado en una variable mapeada de bits. Luego, cada combinación posible de INSERTAR, ACTUALIZAR y ELIMINAR se puede probar fácilmente a lo largo del disparador con evaluaciones binarias eficientes (excepto la improbable combinación INSERTAR o ELIMINAR).
Asume que no importa cuál sea la instrucción DML si no se modificaron las filas (lo que debería satisfacer la gran mayoría de los casos). Entonces, aunque no es tan completa como la solución de Roman Pekar, es más eficiente.
Con este enfoque, tenemos la posibilidad de un disparador "PARA INSERTAR, ACTUALIZAR, BORRAR" por tabla, lo que nos da A) control completo sobre el orden de acción yb) una implementación de código por acción aplicable a múltiples acciones. (Obviamente, cada modelo de implementación tiene sus pros y sus contras; deberá evaluar sus sistemas individualmente para determinar qué es lo que realmente funciona mejor).
Tenga en cuenta que las declaraciones "existe (seleccione * de« insertado / eliminado »)" son muy eficientes ya que no hay acceso al disco ( https://social.msdn.microsoft.com/Forums/en-US/01744422-23fe-42f6 -9ab0-a255cdf2904a ).
fuente
Solución rápida MySQL
Por cierto: estoy usando MySQL PDO.
(1) En una tabla de incremento automático, solo obtenga el valor más alto (mi nombre de columna = id) de la columna incrementada una vez que cada script se ejecute primero:
(2) Ejecute la consulta MySQL como lo haría normalmente, y convierta el resultado a entero, por ejemplo:
(3) Después de la consulta "INSERTAR EN ... EN LA ACTUALIZACIÓN DE LA CLAVE DUPLICADA", obtenga la última identificación insertada de la forma que prefiera, por ejemplo:
(4) Compare y reaccione: si el lastInsertId es más alto que el más alto en la tabla, probablemente sea un INSERT, ¿verdad? Y viceversa.
Sé que es rápido y tal vez sucio. Y es una publicación vieja. Pero, oye, estuve buscando una solución durante mucho tiempo, y tal vez alguien encuentre mi camino algo útil de todos modos. ¡Todo lo mejor!
fuente
de manera simple
fuente
En el primer escenario, supuse que tu tabla tenía una columna IDENTITY
En el segundo escenario, no es necesario usar la columna IDENTIDAD
fuente
SI su actualización
si su inserción
fuente
He usado esas
exists (select * from inserted/deleted)
consultas durante mucho tiempo, pero aún no es suficiente para las operaciones CRUD vacías (cuando no hay registrosinserted
nideleted
tablas). Entonces, después de investigar un poco este tema, encontré una solución más precisa:También es posible usar
columns_updated() & power(2, column_id - 1) > 0
para ver si la columna se actualiza, pero no es seguro para tablas con gran cantidad de columnas. He usado una forma un poco compleja de calcular (ver artículo útil a continuación).Además, este enfoque todavía clasifica incorrectamente algunas actualizaciones como inserciones (si cada columna de la tabla se ve afectada por la actualización), y probablemente clasifique las inserciones donde solo se insertan valores predeterminados como eliminaciones, pero esos son el rey de las operaciones raras (en arrendamiento en mi sistema son). Además de eso, no sé cómo mejorar esta solución en este momento.
fuente
fuente
hago esto:
1 -> insertar
2 -> borrar
3 -> actualizar
fuente
fuente