{"id":385,"date":"2017-09-19T22:40:04","date_gmt":"2017-09-19T22:40:04","guid":{"rendered":"http:\/\/www.manualsqlserver.com\/?p=385"},"modified":"2021-08-03T00:20:22","modified_gmt":"2021-08-03T00:20:22","slug":"triggers","status":"publish","type":"post","link":"https:\/\/manualsqlserver.com\/?p=385","title":{"rendered":"Triggers DML en SQL Server"},"content":{"rendered":"\n<figure class=\"wp-block-image size-large is-resized\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/manualsqlserver.com\/wp-content\/uploads\/2017\/09\/ManualSQL_Triggers_D.png\" alt=\"\" class=\"wp-image-992\" width=\"248\" height=\"230\"\/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>\u00a0Triggers<\/strong> DML en SQL Server<\/h2>\n\n\n\n<p>Un desencadenador o Trigger es una clase de procedimiento almacenado que se ejecuta autom\u00e1ticamente cuando se realiza una transacci\u00f3n en la bases de datos. En este art\u00edculo explicamos los tipos de Triggers existentes y desarrollamos ejemplos de Triggers DML.<\/p>\n\n\n\n<!--more-->\n\n\n\n<h3 class=\"wp-block-heading\">Tipos de Triggers<\/h3>\n\n\n\n<p><strong>Existen los siguientes tipos de Triggers<\/strong><\/p>\n\n\n\n<ol class=\"wp-block-list\"><li>Los Triggers DML se ejecutan cuando se realizan operaciones de manipulaci\u00f3n de datos (DML). Los eventos DML son instrucciones INSERT, UPDATE o DELETE realizados en una tabla o vista.<\/li><li>Los Triggers DDL se ejecutan al realizar eventos de lenguaje de definici\u00f3n de datos (DDL). Estos eventos corresponden a instrucciones CREATE, ALTER y DROP.<\/li><li>Los Triggers Logon, que se disparan al ejecutarse un inicio de sesi\u00f3n en SQL Server.<\/li><\/ol>\n\n\n\n<script async=\"\" src=\"\/\/pagead2.googlesyndication.com\/pagead\/js\/adsbygoogle.js\"><\/script>\n<ins class=\"adsbygoogle\" style=\"display:block; text-align:center;\" data-ad-layout=\"in-article\" data-ad-format=\"fluid\" data-ad-client=\"ca-pub-2636008503986218\" data-ad-slot=\"1902193434\"><\/ins>\n<script>\n     (adsbygoogle = window.adsbygoogle || []).push({});\n<\/script>\n\n\n\n<p style=\"font-size:24px\"><strong>Para m\u00e1s informaci\u00f3n sobre Triggers ver:<\/strong><\/p>\n\n\n\n<p><a rel=\"noreferrer noopener\" href=\"https:\/\/manualsqlserver.com\/?p=1468\" target=\"_blank\">Triggers Logon.<\/a><br><a href=\"https:\/\/manualsqlserver.com\/?p=1431\">Triggers, activar y desactivar.<\/a><br><a href=\"https:\/\/manualsqlserver.com\/?p=1445\">Triggers, historial de registros eliminados.<\/a><br><a href=\"https:\/\/manualsqlserver.com\/?p=1452\">Triggers, historial de cambios en una tabla<\/a><br><a href=\"https:\/\/manualsqlserver.com\/?p=1461\" target=\"_blank\" rel=\"noreferrer noopener\">Triggers DDL<\/a><\/p>\n\n\n\n<p style=\"font-size:30px\"><strong>Triggers DML<\/strong><\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Consideraciones para el uso de Triggers DML<\/h3>\n\n\n\n<ul class=\"wp-block-list\"><li>Una tabla puede tener un m\u00e1ximo de tres triggers: uno de actualizaci\u00f3n, uno de inserci\u00f3n y uno de eliminaci\u00f3n.<\/li><li>Cada trigger puede aplicarse a una sola tabla o vista. Por otro lado, un mismo trigger se puede aplicar a las tres acciones: UPDATE, INSERT y DELETE.<\/li><li>No se puede crear un trigger en una vista ni en una tabla temporal, pero el trigger puede hacer referencia a estos objetos.<\/li><li>Los trigger no se permiten en las tablas del sistema.<\/li><\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Las tablas Inserted y Deleted<\/h3>\n\n\n\n<p>Son tablas especiales que tienen la misma estructura de las tablas que han desencadenado la ejecuci\u00f3n del trigger. Estas tablas se utilizar para el manejo de la informaci\u00f3n de los registros afectados por las instrucciones Insert, Update o Delete, depende para que acci\u00f3n fue creada el Trigger.<\/p>\n\n\n\n<p style=\"font-size:24px\"><strong>Importante<\/strong><\/p>\n\n\n\n<p>Al realizar una inserci\u00f3n: se puede usar la tabla <strong>inserted.<\/strong><br>Al realizar una actualizaci\u00f3n: la tabla <strong>inserted <\/strong>tiene los datos nuevos, es decir, los datos que se van a actualizar,  y la tabla <strong>deleted <\/strong>los datos originales, los que ser\u00e1n reemplazados.<br>Al realizar un borrado, la tabla <strong>deleted <\/strong>contiene los datos del registro borrado.<\/p>\n\n\n\n<p><strong>Note que para una operaci\u00f3n de actualizaci\u00f3n, las dos tablas pueden ser utilizadas.<\/strong><\/p>\n\n\n\n<p style=\"font-size:28px\"><strong>Creando Triggers  DML<\/strong><\/p>\n\n\n\n<p><strong>Para crear un Trigger DML se utiliza:<\/strong><\/p>\n\n\n\n<p>CREATE [ OR ALTER ] TRIGGER [ Esquema . ]NombreTrigger<br>ON { tabla | vista }<br>{ FOR | AFTER | INSTEAD OF }<br>{ [ INSERT ] [ , ] [ UPDATE ] [ , ] [ DELETE ] }<br>AS<br>Begin<br>Instrucciones T-SQL<br>End<\/p>\n\n\n\n<p class=\"has-larger-font-size\"><strong>Ejercicios<\/strong><\/p>\n\n\n\n<p><strong>Usando Northwind<\/strong><br>use Northwind<br>go<\/p>\n\n\n\n<p style=\"font-size:24px\"><strong>Ejercicio 1<\/strong><\/p>\n\n\n\n<p><strong>Trigger que evita que se borren en la tabla categorias mas de un registro<\/strong><br>Create Trigger trEliminaSoloUnaCategoria<br>on Categories for delete<br>As<br>&#8212; Se cuentan cuantos registros se eliminaron<br>IF (Select COUNT(*) from Deleted)&gt;1<br>BEGIN<br>Raiserror(&#8216;NO PUEDE ELIMINAR M\u00c1S DE UN REGISTRO&#8217;,16,1)<br>Rollback Tran<br>END<br>go<\/p>\n\n\n\n<p><em><strong>Raiserror \u00a0 \u00a0Raiserror(&#8216;Mensaje&#8217;,Severidad,Estado)<\/strong><\/em><br><em><strong>Genera un mensaje de error e inicia el procesamiento de errores \u00a0de la sesi\u00f3n. RAISERROR puede hacer referencia a un mensaje <\/strong><\/em><em><strong>definido por el usuario almacenado en la vista de cat\u00e1logo \u00a0sys.messages o puede generar un mensaje din\u00e1micamente.<\/strong><\/em><\/p>\n\n\n\n<p><strong>Para visualizar los triggers de la base de datos<\/strong><br>select * from sys.triggers<br>go<\/p>\n\n\n\n<p style=\"font-size:28px\"><strong>Provocando que el Trigger se dispare<\/strong><\/p>\n\n\n\n<p><strong>Para probar si el Trigger creado trEliminaSoloUnaCategoria funciona<\/strong><br><strong>se insertar\u00e1n dos categor\u00edas con nombre Pisos y Carros<\/strong><br><strong>Insertar Categorias<\/strong><br>insert into Categories (CategoryName) values (&#8216;Pisos&#8217;),(&#8216;Carros&#8217;)<br>go<\/p>\n\n\n\n<p><strong>Eliminar una categoria<\/strong><br>delete Categories where CategoryID = 10<br>go<br><strong>Se elimina sin inconvenientes porque es una sola categor\u00eda.<\/strong><\/p>\n\n\n\n<p><strong>Al eliminar varias categorias el Trigger se dispara y no lo permite.<\/strong><br>delete Categories where CategoryID in (12,13,15)<br>go<\/p>\n\n\n\n<p><strong>Mens 50000, Nivel 16, Estado 1, Procedimiento trEliminaSoloUnaCategoria, L\u00ednea 62<\/strong><br><strong>NO PUEDE ELIMINAR M\u00c1S DE UN REGISTRO<\/strong><br><strong>Mens. 3609, Nivel 16, Estado 1, L\u00ednea 56<\/strong><br><strong>La transacci\u00f3n termin\u00f3 en el desencadenador. Se anul\u00f3 el lote.<\/strong><\/p>\n\n\n\n<p><strong>Borrar una sola categoria<\/strong><br>delete Categories where CategoryID = 17<br>go<br><strong>La categor\u00eda se borra con \u00e9xito<\/strong><\/p>\n\n\n\n<p style=\"font-size:24px\"><strong>Ejercicio 2<\/strong><\/p>\n\n\n\n<p style=\"font-size:28px\"><strong>Trigger de Inserci\u00f3n<\/strong><\/p>\n\n\n\n<p><strong>Crear un Trigger que permita comprobar que se inserta una categor\u00eda con nombre diferente.<\/strong><br><strong>La tabla Inserted ser\u00e1 utilizada para comprobar si ya hay una categor\u00eda con el mismo\u00a0nombre que la insertada.<\/strong><\/p>\n\n\n\n<p>Create trigger trCategoriaInsertaSinRepetidos ON Categories For Insert<br>AS<br>IF (Select COUNT (*) From Inserted, Categories<br>WHERE Inserted.CategoryName = Categories.CategoryName) &gt;1<br>BEGIN<br>Rollback Transaction<br>return -1<br>PRINT &#8216;El Nombre de la Categoria ya existe&#8230;&#8217;<br>END<br>ELSE<br>return 0<br>PRINT &#8216;Categor\u00eda ingresada a la Base de datos&#8217;<br>go<\/p>\n\n\n\n<p><strong>Insertar categor\u00eda con nombre repetido: Pisos<\/strong><br>insert into Categories (CategoryName) values (&#8216;Pisos&#8217;)<br>go<br><strong>El Nombre de la Categoria ya existe&#8230;<\/strong><br><strong>Mens. 3609, Nivel 16, Estado 1, L\u00ednea 87<\/strong><br><strong>La transacci\u00f3n termin\u00f3 en el desencadenador. Se anul\u00f3 el lote.<\/strong><\/p>\n\n\n\n<script async=\"\" src=\"\/\/pagead2.googlesyndication.com\/pagead\/js\/adsbygoogle.js\"><\/script>\n<ins class=\"adsbygoogle\" style=\"display:block; text-align:center;\" data-ad-layout=\"in-article\" data-ad-format=\"fluid\" data-ad-client=\"ca-pub-2636008503986218\" data-ad-slot=\"1902193434\"><\/ins>\n<script>\n     (adsbygoogle = window.adsbygoogle || []).push({});\n<\/script>\n\n\n\n<p style=\"font-size:24px\"><strong>Ejercicio 3\u00a0<\/strong><\/p>\n\n\n\n<p style=\"font-size:24px\"><strong>Trigger Instead Of<\/strong><\/p>\n\n\n\n<p><strong>Realizar acciones despu\u00e9s de las instrucciones &nbsp;de un procedimiento o las escritas directamente &nbsp;por el usuario.<\/strong><\/p>\n\n\n\n<p><strong>Por ejemplo, copiar los datos a una vista de Clientes al insertar uno en la tabla Customers<\/strong><\/p>\n\n\n\n<p><strong>Primero se crea la vista con los clientes.<\/strong><br>Create View ClientesVista as<br>Select CustomerID,CompanyName,Address,City,Phone from Customers<br>go<\/p>\n\n\n\n<p><strong>Al agregar un Cliente en Customers se desea que se inserte en ClientesVista<\/strong><br><strong>Crear un Trigger Instead of para la tabla Customers.<\/strong><\/p>\n\n\n\n<p>Create trigger trClienteInsertaVista ON Customers Instead of Insert<br>AS<br>BEGIN<br>Insert Into ClientesVista<br>SELECT CustomerID, CompanyName, Address, City, Phone<br>FROM Inserted<br>Print &#8216;Insertado correctamente en la vista&#8217;<br>END<br>go<\/p>\n\n\n\n<p><strong>Insertar un cliente en Customers<\/strong><br>insert into Customers (CustomerID, CompanyName,ContactName,<br>ContactTitle,Address, City, Phone)<br>Values (&#8216;TQ884&#8217;,&#8217;Trainer SQL Pro &#8216;,&#8217;SQL Professional&#8217;,<br>&#8216;Gerente General&#8217;,&#8217;Av. Larco 94994&#8242;,&#8217;Espa\u00f1a&#8217;,&#8217;209834534&#8242;)<br>go<\/p>\n\n\n\n<figure class=\"wp-block-image size-large is-resized\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/manualsqlserver.com\/wp-content\/uploads\/2020\/05\/ManualSQL_Triggers01.png\" alt=\"\" class=\"wp-image-990\" width=\"795\" height=\"349\" srcset=\"https:\/\/manualsqlserver.com\/wp-content\/uploads\/2020\/05\/ManualSQL_Triggers01.png 792w, https:\/\/manualsqlserver.com\/wp-content\/uploads\/2020\/05\/ManualSQL_Triggers01-300x132.png 300w, https:\/\/manualsqlserver.com\/wp-content\/uploads\/2020\/05\/ManualSQL_Triggers01-768x337.png 768w\" sizes=\"auto, (max-width: 795px) 100vw, 795px\" \/><\/figure>\n\n\n\n<p>Visualizar la vista para comprobar que el cliente ha sido insertado.<br>select * from ClientesVista where CustomerID like &#8216;T%&#8217;<br>go<\/p>\n\n\n\n<figure class=\"wp-block-image size-large is-resized\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/manualsqlserver.com\/wp-content\/uploads\/2017\/09\/ManualSQL_Triggers02-1024x366.png\" alt=\"\" class=\"wp-image-991\" width=\"901\" height=\"322\" srcset=\"https:\/\/manualsqlserver.com\/wp-content\/uploads\/2017\/09\/ManualSQL_Triggers02-1024x366.png 1024w, https:\/\/manualsqlserver.com\/wp-content\/uploads\/2017\/09\/ManualSQL_Triggers02-300x107.png 300w, https:\/\/manualsqlserver.com\/wp-content\/uploads\/2017\/09\/ManualSQL_Triggers02-768x275.png 768w, https:\/\/manualsqlserver.com\/wp-content\/uploads\/2017\/09\/ManualSQL_Triggers02.png 1124w\" sizes=\"auto, (max-width: 901px) 100vw, 901px\" \/><\/figure>\n","protected":false},"excerpt":{"rendered":"<p>\u00a0Triggers DML en SQL Server Un desencadenador o Trigger es una clase de procedimiento almacenado que se ejecuta autom\u00e1ticamente cuando se realiza una transacci\u00f3n en la bases de datos. En este art\u00edculo explicamos los tipos de Triggers existentes y desarrollamos ejemplos de Triggers DML.<\/p><p><a class=\"more-link btn\" href=\"https:\/\/manualsqlserver.com\/?p=385\">Seguir leyendo<\/a><\/p>\n","protected":false},"author":1,"featured_media":992,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[8,143],"tags":[53,59,68,64],"class_list":["post-385","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-programacion","category-triggersql","tag-sqlserver","tag-triggers","tag-triggers-en-sql-server","tag-vistas","nodate","item-wrap"],"_links":{"self":[{"href":"https:\/\/manualsqlserver.com\/index.php?rest_route=\/wp\/v2\/posts\/385","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/manualsqlserver.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/manualsqlserver.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/manualsqlserver.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/manualsqlserver.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=385"}],"version-history":[{"count":3,"href":"https:\/\/manualsqlserver.com\/index.php?rest_route=\/wp\/v2\/posts\/385\/revisions"}],"predecessor-version":[{"id":2550,"href":"https:\/\/manualsqlserver.com\/index.php?rest_route=\/wp\/v2\/posts\/385\/revisions\/2550"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/manualsqlserver.com\/index.php?rest_route=\/wp\/v2\/media\/992"}],"wp:attachment":[{"href":"https:\/\/manualsqlserver.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=385"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/manualsqlserver.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=385"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/manualsqlserver.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=385"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}