{"id":170,"date":"2012-05-09T22:38:33","date_gmt":"2012-05-09T21:38:33","guid":{"rendered":"http:\/\/www.jbahillo.com\/?p=170"},"modified":"2012-06-11T09:34:08","modified_gmt":"2012-06-11T08:34:08","slug":"como-saltarse-limitaciones-de-triggers-en-mysql","status":"publish","type":"post","link":"https:\/\/www.jbahillo.com\/?p=170","title":{"rendered":"Como saltarse limitaciones de triggers en MYSQL"},"content":{"rendered":"<p>En mi ultimo trabajo, migrando una base de datos MS SQL a MySQL, me encontr\u00e9 con un peque\u00f1o inconveniente, deb\u00eda aplicar un disparador que en caso que deb\u00eda actualizar un campo  de la tabla que generaba dicho disparador.<br \/>\nComo sabr\u00e9is un disparador se trata de una secuencia SQL que se ejecutar\u00e1 antes o despu\u00e9s de un evento determinado (al estilo de, para los que lo conozcan los famosos events del mIRC Scripting, el principio en el scripting de muchos) El problema es que en MYSQL la incorporaci\u00f3n de los disparadores es relativamente reciente, y a d\u00eda de hoy existe, entre otras, la limitaci\u00f3n que no pueden modificar la tabla que los genera<br \/>\nPues bien, la soluci\u00f3n si lo pens\u00e1is es bastante sencilla:<\/p>\n<p>Pong\u00e1monos en situacion. Necesitamos que cada vez que se haga un UPDATE de una tabla, por ejemplo, se nos actualice la columna lastedit con la fecha actual (por ejemplo).<br \/>\nSi lo intent\u00e1semos de una forma \u00abest\u00e1ndar\u00bb, es decir, codificando el trigger de la siguiente forma:<\/p>\n<pre class=\"brush: sql; gutter: true; first-line: 1; highlight: []; html-script: false\">DELIMITER $\nCREATE TRIGGER disparador BEFORE UPDATE ON tabla\nFOR EACH ROW \nBEGIN\nUPDATE tabla SET lastedit = CURDATE();\nEND$\nDELIMITER;<\/pre>\n<p>Recibir\u00edamos un error indicando que un disparador no puede modificar la tabla que lo origina.<\/p>\n<p>MS SQL genera para gestionar los cambios una o varias tablas temporales, <em>inserted<\/em> y <em>deleted<\/em> (como es l\u00f3gico la primera para los datos a introducir, y la segunda para los datos a eliminar, si existiesen)<br \/>\nEn MySQL esto se realiza de un modo muy similar, con la diferencia que estas tablas temporales tienen el nombre de NEW y OLD, respectivamente.<br \/>\nAhora bien, tampoco intent\u00e9is, como me ocurri\u00f3 a mi en primer lugar, el hacer un UPDATE de la tabla temporal:<\/p>\n<pre class=\"brush: sql; gutter: true; first-line: 1; highlight: []; html-script: false\">UPDATE NEW SET lastedit = CURDATE();<\/pre>\n<p>La soluci\u00f3n es definir la columna dentro de esta tabla temporal como una variable, es decir:<\/p>\n<pre class=\"brush: sql; gutter: true; first-line: 1; highlight: []; html-script: false\">SET NEW.lastedit = CURDATE();<\/pre>\n<p>Con esto habr\u00e9is conseguido que el disparador modifique la columna lastedit de la tabla tabla, ya que cuando finalizado el trigger se aplique el update, recorrer\u00b4a la tabla temporal NEW, y esta albergar\u00e1 un valor para la columna lastedit, por lo que lo aplicar\u00e1, junto con los valores que se hubiesen definido en el update (o la sentencia que generase el disparador) original<\/p>\n","protected":false},"excerpt":{"rendered":"<p>En mi ultimo trabajo, migrando una base de datos MS SQL a MySQL, me encontr\u00e9 con un peque\u00f1o inconveniente, deb\u00eda aplicar un disparador que en caso que deb\u00eda actualizar un campo de la tabla que generaba dicho disparador. Como sabr\u00e9is&hellip;<\/p>\n<p class=\"more-link-p\"><a class=\"more-link\" href=\"https:\/\/www.jbahillo.com\/?p=170\">Read more &rarr;<\/a><\/p>\n","protected":false},"author":21,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"ep_exclude_from_search":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":false,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2},"jetpack_post_was_ever_published":false},"categories":[38],"tags":[44,41,43,42,39,45,46,40],"class_list":["post-170","post","type-post","status-publish","format-standard","hentry","category-sql","tag-deleted","tag-disparador","tag-inserted","tag-limitacion","tag-mysql","tag-new","tag-old","tag-trigger"],"aioseo_notices":[],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_shortlink":"https:\/\/wp.me\/p74T96-2K","jetpack-related-posts":[],"jetpack_sharing_enabled":true,"jetpack_likes_enabled":true,"_links":{"self":[{"href":"https:\/\/www.jbahillo.com\/index.php?rest_route=\/wp\/v2\/posts\/170","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.jbahillo.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.jbahillo.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.jbahillo.com\/index.php?rest_route=\/wp\/v2\/users\/21"}],"replies":[{"embeddable":true,"href":"https:\/\/www.jbahillo.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=170"}],"version-history":[{"count":3,"href":"https:\/\/www.jbahillo.com\/index.php?rest_route=\/wp\/v2\/posts\/170\/revisions"}],"predecessor-version":[{"id":427,"href":"https:\/\/www.jbahillo.com\/index.php?rest_route=\/wp\/v2\/posts\/170\/revisions\/427"}],"wp:attachment":[{"href":"https:\/\/www.jbahillo.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=170"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.jbahillo.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=170"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.jbahillo.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=170"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}