{"id":568,"date":"2023-10-20T14:13:20","date_gmt":"2023-10-20T12:13:20","guid":{"rendered":"http:\/\/eines-informatiques.recursos.uoc.edu\/gestion-de-datos\/?page_id=568"},"modified":"2025-06-13T10:48:48","modified_gmt":"2025-06-13T08:48:48","slug":"1-15-triggers-procediments-i-funcions","status":"publish","type":"page","link":"http:\/\/eines-informatiques.recursos.uoc.edu\/gestion-de-datos\/1-15-triggers-procediments-i-funcions\/","title":{"rendered":"1.15. <em>Triggers<\/em>, procediments i funcions"},"content":{"rendered":"<p>La majoria de bases de dades relacionals ofereixen la possibilitat d\u2019emmagatzemar subprogrames. Es denominen funcions, procediments i <em>triggers<\/em> o disparadors, i s\u00f3n molt \u00fatils per automatitzar tasques i guardar instruccions SQL que s\u2019han d\u2019utilitzar freq\u00fcentment. S\u00f3n objectes que contenen codi SQL, com breus <em>scripts<\/em> de codi SQL, que poden acceptar par\u00e0metres i declarar variables.<\/p>\n<p>S\u2019assigna un nom al subprograma i s\u2019executa perqu\u00e8 quedi emmagatzemat a la base de dades. Despr\u00e9s el podem invocar o <em>cridar<\/em> pel seu nom perqu\u00e8 s\u2019executi el codi emmagatzemat en els subprogrames.<\/p>\n<ul>\n<li><strong>Procediment<\/strong> emmagatzemat. \u00c9s un objecte que es crea amb la sent\u00e8ncia <code>CREATE PROCEDURE<\/code> i s\u2019invoca amb la sent\u00e8ncia <code>CALL<\/code>. Els procediments poden acceptar par\u00e0metres i no fan cap retorn, \u00e9s a dir, no retornen cap<\/li>\n<li><strong>Funci\u00f3<\/strong> emmagatzemada. \u00c9s un objecte que es crea amb la sent\u00e8ncia <code>CREATE FUNCTION<\/code> i s\u2019invoca amb la sent\u00e8ncia <strong>SELECT <\/strong>o dins d\u2019una expressi\u00f3. Les <strong>funcions<\/strong> poden acceptar par\u00e0metres i retornen sempre un valor. Aquest valor retornat pot ser un valor nul i en aquest cas es comportaria com un procediment.<\/li>\n<li><strong><em>Trigger<\/em><\/strong>. \u00c9s un objecte que es crea amb la sent\u00e8ncia <code>CREATE TRIGGER<\/code> i ha d\u2019estar associat a una taula. Un <em>trigger<\/em> s\u2019activa, es dispara, quan ocorre un esdeveniment d\u2019inserci\u00f3, actualitzaci\u00f3 o esborrat, sobre la taula a la qual est\u00e0 associat.<\/li>\n<\/ul>\n<p>Vegem-ne alguns exemples:<\/p>\n<div class=\"featured featured-grey\"><\/p>\n<h3>Procediments<\/h3>\n<ol>\n<li>Creem un procediment a la base de dades <strong>cataleg<\/strong> per comptar el nombre de gens diferents de la taula <strong>refGene<\/strong>, que anomenem <strong>numGens<\/strong>.<\/li>\n<\/ol>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"raw\" data-enlighter-theme=\"droide\">CREATE PROCEDURE numGens()\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\r\nSELECT COUNT(distinct name2) FROM refGene;<\/pre>\n<p>Aquest procediment no t\u00e9 par\u00e0metres () i mostra per pantalla el nombre de gens diferents que trobem al camp <strong>name2 <\/strong>de la taula <strong>refGene<\/strong>. En executar el codi, el procediment s\u2019emmagatzema a la base de dades com un objecte m\u00e9s, com les taules, i no s\u2019executa la consulta <strong><code>SELECT<\/code> <\/strong>que cont\u00e9 fins que l\u2019anomenem.<\/p>\n<p>Per anomenar el procediment <strong>numGens <\/strong>escrivim:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"raw\" data-enlighter-theme=\"droide\">CALL numGens();<\/pre>\n<p>Si volem veure els procediments emmagatzemats a la base de dades escrivim:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"raw\" data-enlighter-theme=\"droide\">SHOW PROCEDURE STATUS WHERE db = 'cataleg';<\/pre>\n<p>Si volem eliminar un procediment creat escrivim:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"raw\" data-enlighter-theme=\"droide\">DROP PROCEDURE IF EXISTS numGens;<\/pre>\n<ol start=\"2\">\n<li>Ara utilizarem variables, el resultat del <strong>SELECT<\/strong> el guardarem en la variable local <strong>gens<\/strong>, que hem de declarar i de la qual hem de definir el tipus de dades.<\/li>\n<\/ol>\n<p>Com que en el procediment hi ha sent\u00e8ncies que acaben en \u00ab;\u00bb, primer assignarem un nou delimitador. Escrivim:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"raw\" data-enlighter-theme=\"droide\">\u00a0DELIMITER \/\/<\/pre>\n<p>Ara MySQL interpretar\u00e0 que el final de les sent\u00e8ncies SQL \u00e9s el s\u00edmbol \/\/<\/p>\n<p>Crearem un nou procediment anomenat <strong>numGens2<\/strong>.<\/p>\n<p>Per declarar la variable <strong>gens<\/strong> necessitem escriure <code>BEGIN<\/code> abans de <code>DECLARE<\/code> i acabar amb <code>END<\/code>.<\/p>\n<p>En declarar les variables locals cal especificar quin tipus de dada guardaran, INT, CHAR, VARCHAR, etc. En aquest cas \u00e9s un INT.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"raw\" data-enlighter-theme=\"droide\">DECLARE gens INT;<\/pre>\n<p>Per guardar el resultat del <code>SELECT<\/code> en la variable local <strong>gens<\/strong> fem:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"raw\" data-enlighter-theme=\"droide\">INTO gens.<\/pre>\n<p>Per mostrar el contingut de la variable <strong>gens<\/strong> fem:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"raw\" data-enlighter-theme=\"droide\">SELECT gens;<\/pre>\n<p>Veiem tot el codi per crear el nou procediment usant variables:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"raw\" data-enlighter-theme=\"droide\">CREATE PROCEDURE numGens2()\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0        \r\nBEGIN\r\nDECLARE gens INT;\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0              \r\nSELECT COUNT(distinct name2)\r\nINTO gens\r\nFROM refGene;\u00a0\u00a0\r\nSELECT gens;\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0            \r\nEND \/\/<\/pre>\n<p>Tornem a canviar el delimitador per poder fer servir \u00ab;\u00bb en finalitzar la sent\u00e8ncia <code>DELIMITER<\/code> ;<\/p>\n<p>Invoquem el procediment:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"raw\" data-enlighter-theme=\"droide\"> CALL numGens2();<\/pre>\n<ol start=\"3\">\n<li>Ara passarem un par\u00e0metre al procediment i l\u2019utilitzarem en la condici\u00f3 <code>WHERE<\/code> de la consulta <code>SELECT<\/code>.<\/li>\n<\/ol>\n<p>Creem un nou procediment anomenat <strong>numTrans<\/strong> que ens servir\u00e0 per comptar el nombre de transcrits segons el tipus de transcrit que li passem com a par\u00e0metre.<\/p>\n<p>Igual que les variables locals, cal especificar als par\u00e0metres quin tipus de dades esperen, INT, CHAR, VARCHAR&#8230; En aquest cas, <code>CHAR( 50)<\/code>.<\/p>\n<p>El par\u00e0metre el posem al costat del nom del procediment entre par\u00e8ntesis <code>numTrans(transcritType CHAR(50))<\/code>.<\/p>\n<p>Hi assignem una altra vegada un delimitador <code>\/\/<\/code>:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"raw\" data-enlighter-theme=\"droide\">DELIMITER \/\/<\/pre>\n<p>Vegem el codi:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"raw\" data-enlighter-theme=\"droide\">CREATE PROCEDURE numTrans ( transcritType CHAR(50))\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\r\nBEGIN\r\nDECLARE numT INT;\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0                     \r\nSELECT COUNT(*) INTO numT FROM refGene \r\nWHERE name LIKE transcritType;\u00a0\u00a0\r\nSELECT numT;\r\nEND \/\/<\/pre>\n<p>Canviem una altra vegada el delimitador:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"raw\" data-enlighter-theme=\"droide\">DELIMITER ;<\/pre>\n<p>Invoquem el procediment passant-li el par\u00e0metre NR:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"raw\" data-enlighter-theme=\"droide\">CALL numTrans('%NR%');<\/pre>\n<p>Ara invoquem el procediment passant-li el par\u00e0metre NM:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"raw\" data-enlighter-theme=\"droide\">CALL numTrans('%NM%');<\/pre>\n<p>En usar el comod\u00ed % ens assegurem que no perdem cap registre amb el contingut del par\u00e0metre.<\/p>\n<ol start=\"4\">\n<li>En comptes de declarar una variable local dins d\u2019un procediment, tamb\u00e9 podem utilitzar un par\u00e0metre com a variable de sortida. Indiquem que \u00e9s un par\u00e0metre de sortida amb la cl\u00e0usula <strong>OUT<\/strong>. Per defecte, els par\u00e0metres s\u00f3n nom\u00e9s d\u2019entrada, per\u00f2 tamb\u00e9 els podem indicar amb la cl\u00e0usula <strong>IN<\/strong>.<\/li>\n<\/ol>\n<p>Hi assignem un delimitador \/\/:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"raw\" data-enlighter-theme=\"droide\">DELIMITER \/\/<\/pre>\n<p>Creem un nou procediment anomenat <strong>numTrans2<\/strong> que ens servir\u00e0 tamb\u00e9 per comptar el nombre de transcrits segons el tipus de transcrit que li passem com a par\u00e0metre, i amb un segon par\u00e0metre que ens servir\u00e0 per guardar el resultat de la consulta.<\/p>\n<p>Vegem el codi:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"raw\" data-enlighter-theme=\"droide\">CREATE PROCEDURE numTrans2(IN transcritType CHAR(50), OUT numT INT)\u00a0\u00a0\u00a0      \r\nBEGIN\r\nSELECT COUNT(*) INTO numT FROM refGene \r\nWHERE name LIKE transcritType;   \r\nEND \/\/<\/pre>\n<p>Canviem el delimitador:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"raw\" data-enlighter-theme=\"droide\">DELIMITER ;<\/pre>\n<p>Invoquem el procediment passant-li els dos par\u00e0metres. Fem servir una variable definida per l\u2019usuari amb <code>@<\/code> trucada <code>@transcritos<\/code> per guardar el valor que retorna el <strong>SELECT<\/strong> del procediment:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"raw\" data-enlighter-theme=\"droide\">CALL numTrans2('%NR%', @transcrits);<\/pre>\n<p>Fem un <strong>SELECT<\/strong> de la variable <code>@transcritos<\/code> que cont\u00e9 el nombre de transcrits:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"raw\" data-enlighter-theme=\"droide\">SELECT @transcrits;<\/pre>\n<p>\n<\/div>\n<div class=\"featured featured-grey\"><\/p>\n<h3>Funcions<\/h3>\n<p>Les funcions retornen un valor, aix\u00ed que, per anomenar una funci\u00f3 emmagatzemada, en comptes de fer <code>CALL<\/code> fem directament <code>SELECT nombre_de_la_funci\u00f3n<\/code> i ens mostra el valor que retorna la funci\u00f3.<\/p>\n<p>Hi assignem un delimitador \/\/:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"raw\" data-enlighter-theme=\"droide\">DELIMITER \/\/<\/pre>\n<p>Creem una nova funci\u00f3 anomenada <strong>numTrans3<\/strong> que ens servir\u00e0 tamb\u00e9 per comptar el nombre de transcrits segons el tipus de transcrit que li passem com a par\u00e0metre.<\/p>\n<p>En les funcions hem d\u2019indicar, despr\u00e9s del nom i dels par\u00e0metres, el tipus de dada que retorna la funci\u00f3, en aquest cas un INT, i escrivim:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"raw\" data-enlighter-theme=\"droide\">RETURNS INT<\/pre>\n<p>Al final de la funci\u00f3 li indiquem la variable que volem retornar, en aquest cas:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"raw\" data-enlighter-theme=\"droide\">RETURN numT;<\/pre>\n<p>Vegem el codi \u00edntegre de la funci\u00f3:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"raw\" data-enlighter-theme=\"droide\">CREATE FUNCTION numTrans3 (transcritType CHAR(50)) RETURNS INT\u00a0\u00a0\u00a0\r\nBEGIN\r\nDECLARE numT INT;\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\r\nSELECT COUNT(*) INTO numT FROM refGene \r\nWHERE name LIKE transcritType;          \r\nRETURN numT;\r\nEND \/\/<\/pre>\n<p>Canviem el delimitador:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"raw\" data-enlighter-theme=\"droide\">DELIMITER ;<\/pre>\n<p>Invoquem la funci\u00f3 passant-li el par\u00e0metre, en aquest cas els passem el par\u00e0metre NR:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"raw\" data-enlighter-theme=\"droide\">SELECT numTrans3('%NR%');<\/pre>\n<p>Si passem a la funci\u00f3 el par\u00e0metre NM:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"raw\" data-enlighter-theme=\"droide\">SELECT numTrans3('%NM%');<\/pre>\n<p>Si volem veure les funcions emmagatzemades a la base de dades escrivim la sent\u00e8ncia:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"raw\" data-enlighter-theme=\"droide\">SHOW FUNCTION STATUS WHERE db = 'cataleg';<\/pre>\n<p>Si volem eliminar una funci\u00f3 emmagatzemada, escrivim:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"raw\" data-enlighter-theme=\"droide\">DROP FUNCTION IF EXISTS numTrans3;<\/pre>\n<p>\n<\/div>\n<div class=\"featured featured-grey\"><\/p>\n<h3><em>Triggers<\/em><\/h3>\n<p>Un <em>trigger<\/em> \u00e9s un objecte emmagatzemat a la base de dades que est\u00e0 associat amb una taula i que s\u2019activa quan ocorre un esdeveniment sobre la taula.<\/p>\n<p>Els esdeveniments que poden oc\u00f3rrer sobre la taula s\u00f3n:<\/p>\n<ul>\n<li><strong><code>INSERT<\/code><\/strong>. El <em>trigger<\/em> s\u2019activa quan s\u2019insereix una nova fila sobre la taula associada.<\/li>\n<li><strong><code>UPDATE<\/code><\/strong>. El <em>trigger<\/em> s\u2019activa quan s\u2019actualitza una fila sobre la taula associada.<\/li>\n<li><strong><code>DELETE<\/code><\/strong>. El <em>trigger <\/em>s\u2019activa quan s\u2019elimina una fila sobre la taula associada.<\/li>\n<\/ul>\n<p>El <em>trigger<\/em> es pot activar o disparar abans (<strong><code>BEFORE<\/code><\/strong>) de l\u2019esdeveniment o despr\u00e9s (<strong><code>AFTER<\/code><\/strong>) de l\u2019esdeveniment.<\/p>\n<p>Com a exemples vam crear dos <em>triggers <\/em>associats a la taula <em>gens<\/em> de la nostra base de dades:<\/p>\n<p>Un <em>trigger<\/em> amb el nom de <strong>trig_check_gens_before_insert <\/strong>que s\u2019associa a la taula <strong>gens<\/strong>. S\u2019activa abans d\u2019una operaci\u00f3 d\u2019inserci\u00f3. Si el nou valor del camp inici que es vol inserir \u00e9s negatiu, es guarda com a 0. Si el nou valor del camp <strong>final <\/strong>que es vol inserir \u00e9s menor que el valor del camp <strong>inici<\/strong>, es guarda el valor del camp <strong>inici<\/strong>.<\/p>\n<p>Un t<em>rigger<\/em> amb el nom de <strong>trig_check_gens_before_update<\/strong> que s\u2019associa a la taula <strong>gens<\/strong>. S\u2019activa abans d\u2019una operaci\u00f3 de modificaci\u00f3. Si el nou valor del camp <strong>inici <\/strong>que es vol modificar \u00e9s negatiu, es guarda com a 0. Si el valor del camp <strong>final <\/strong>del registre que es vol modificar \u00e9s menor que el nou valor que volem actualitzar del camp <strong>inici<\/strong> es guarda com a 1.<\/p>\n<p>Creem el <em>trigger<\/em><strong> trig_check_gens_before_insert <\/strong><\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"raw\" data-enlighter-theme=\"droide\">DELIMITER \/\/\r\nCREATE TRIGGER trig_check_gens_before_insert\u00a0\u00a0\u00a0\u00a0\u00a0 \r\nBEFORE INSERT\r\nON gens FOR EACH ROW\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\r\nBEGIN IF NEW.inici &lt; 0 THEN SET NEW.inici = 0;\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\r\nELSEIF NEW.inici &gt; NEW.final THEN SET NEW.final = NEW.inici;\u00a0\u00a0\u00a0\u00a0\u00a0 \r\nEND IF;\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0           \u00a0\r\nEND\/\/<\/pre>\n<p>En executar aquest codi de creaci\u00f3 del <em>trigger,<\/em><strong> trig_check_gens_before_insert<\/strong> queda emmagatzemat a la nostra base de dades, i nom\u00e9s actuar\u00e0, s\u2019activar\u00e0 quan l\u2019usuari executi una sent\u00e8ncia d\u2019inserci\u00f3, per exemple:<\/p>\n<p>Canviem el delimitador:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"raw\" data-enlighter-theme=\"droide\">DELIMITER ;<\/pre>\n<p>Realitzem operacions d\u2019inserci\u00f3 a la taula <em>gens<\/em> perqu\u00e8 es dispari el <em>trigger <\/em><strong>trig_check_gens_before_insert<\/strong>:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"raw\" data-enlighter-theme=\"droide\">INSERT INTO gens (nom, cromosoma, cadena, inici, final, proteina, especie) VALUES ('WASH7P', 'chrX', '+', -2527305, 2575270,'NR_033380', 'H. Sapiens');\r\n\r\nINSERT\u00a0INTO\u00a0gens\u00a0(nom,\u00a0cromosoma,\u00a0cadena,\u00a0inici,\u00a0final,\u00a0proteina,\u00a0especie)\u00a0VALUES\u00a0('WASH7P2',\u00a0'chrX',\u00a0'+',\u00a0252730599,\u00a02575270,'NR_033381',\u00a0'H.\u00a0Sapiens');<\/pre>\n<p>La variable composta <strong><code>NEW<\/code><\/strong> que utilitzem en el <em>trigger<\/em> emmagatzema tots els valors que inserim en cada operaci\u00f3 <strong><code>INSERT<\/code><\/strong>. D\u2019aquesta manera podem utilitzar-la en el <em>trigger<\/em> sense con\u00e8ixer <em>a priori<\/em> quins valors s\u2019hi inseriran.<\/p>\n<p>En els nostres exemples la variable<strong> NEW.inici<\/strong> cont\u00e9 en el primer <strong><code>INSERT<\/code><\/strong> el valor -2527305 i en el segon <strong><code>INSERT<\/code><\/strong> la variable <strong>NEW.inici <\/strong>cont\u00e9 el valor 252730599 i la variable <strong>NEW.final<\/strong> cont\u00e9 el valor 2575270<\/p>\n<p>En el primer <strong>INSERT <\/strong>es compleix <code>NEW.inici &lt; 0<\/code>, aquesta condici\u00f3 dispara el <em>trigger<\/em> i en el camp <strong>inici<\/strong> es guarda el valor 0.<\/p>\n<p>En el segon<strong> INSERT<\/strong> es compleix <code>NEW.inici &gt; NEW.final<\/code>, aquesta condici\u00f3 dispara el <em>trigger<\/em> i en el camp <strong>final<\/strong> es guarda el valor <code>252730599<\/code>.<\/p>\n<p>Ara creem el <em>trigger<\/em><strong> trig_check_gens_before_update<\/strong>:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"raw\" data-enlighter-theme=\"droide\">DELIMITER \/\/\r\nCREATE TRIGGER trig_check_gens_before_update \r\nBEFORE UPDATE ON gens \r\nFOR EACH ROW \r\nBEGIN \r\nIF NEW.inici &lt; 0 THEN SET NEW.inici = 0;\r\nELSEIF NEW.inici &gt; OLD.final THEN SET NEW.inici = 1; \r\nEND IF; \r\nEND \/\/<\/pre>\n<p>En executar aquest codi de creaci\u00f3 del <em>trigger<\/em>,<strong> trig_check_gens_before_update <\/strong>queda emmagatzemat a la nostra base de dades, i nom\u00e9s actuar\u00e0, s\u2019activar\u00e0 quan l\u2019usuari executi una sent\u00e8ncia d\u2019actualitzaci\u00f3, per exemple:<\/p>\n<p>Canviem el delimitador:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"raw\" data-enlighter-theme=\"droide\">DELIMITER ;<\/pre>\n<p>Realitzem operacions de modificaci\u00f3 a la taula <em>gens<\/em> perqu\u00e8 es dispari el <em>trigger <\/em><strong>trig_check_gens_before_update<\/strong>:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"raw\" data-enlighter-theme=\"droide\">UPDATE gens SET inici = 228748314 WHERE nom = 'MYC';\r\n\r\nUPDATE gens SET inici = -47643 WHERE nom = 'cbt';<\/pre>\n<p>En aquest cas, la variable composta <strong>NEW<\/strong> que utilitzem en el <em>trigger<\/em> emmagatzema el nou valor que volem actualitzar en la sent\u00e8ncia<strong> UPDATE<\/strong>. En el primer <strong>UPDATE<\/strong> la variable <code>NEW.inici<\/code> cont\u00e9 el valor 228748314 i en el segon<strong> UPDATE<\/strong> la variable <code>NEW.inici<\/code> cont\u00e9 el valor <code>-47643<\/code>.<\/p>\n<p>En canvi, la variable composta<strong> OLD<\/strong> emmagatzema tots els valors vells ja emmagatzemats a la taula del registre que es vol actualitzar. En el primer <strong>UPDATE<\/strong>, la variable <code>OLD.final<\/code> cont\u00e9 el valor emmagatzemat en el camp final del registre amb clau prim\u00e0ria <strong>MYC <\/strong>en la taula <strong>gens<\/strong>, i en el segon <strong>UPDATE<\/strong>, la variable <code>OLD.final<\/code> cont\u00e9 el valor emmagatzemat en el camp final del registre amb clau prim\u00e0ria<strong> cbt<\/strong>.<\/p>\n<p>En el primer <strong>UPDATE<\/strong> es compleix <code>NEW.inici &gt; OLD.final<\/code>, aquesta condici\u00f3 dispara el <em>trigger<\/em> i en el camp inici es guarda el valor 1.<\/p>\n<p>En el segon <strong>UPDATE<\/strong> es compleix <code>NEW.inici &lt; 0<\/code> , aquesta condici\u00f3 dispara el <em>trigger<\/em> i en el camp inici es guarda el valor 0.<\/p>\n<p>En les operacions <strong>DELETE<\/strong> nom\u00e9s s\u2019utilitza la variable composta <strong>OLD,<\/strong> capa\u00e7 d\u2019emmagatzemar tots els valors del registre que es vol eliminar i accedir-hi, amb el format <code>OLD.nom_camp<\/code>.<\/p>\n<p>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>La majoria de bases de dades relacionals ofereixen la possibilitat d\u2019emmagatzemar subprogrames. Es denominen funcions, procediments i triggers o disparadors, i s\u00f3n molt \u00fatils per automatitzar tasques i guardar instruccions SQL que s\u2019han d\u2019utilitzar freq\u00fcentment. S\u00f3n objectes que contenen codi SQL, com breus scripts de codi SQL, que poden acceptar par\u00e0metres i declarar variables. S\u2019assigna [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":[],"acf":[],"_links":{"self":[{"href":"http:\/\/eines-informatiques.recursos.uoc.edu\/gestion-de-datos\/wp-json\/wp\/v2\/pages\/568"}],"collection":[{"href":"http:\/\/eines-informatiques.recursos.uoc.edu\/gestion-de-datos\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"http:\/\/eines-informatiques.recursos.uoc.edu\/gestion-de-datos\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"http:\/\/eines-informatiques.recursos.uoc.edu\/gestion-de-datos\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/eines-informatiques.recursos.uoc.edu\/gestion-de-datos\/wp-json\/wp\/v2\/comments?post=568"}],"version-history":[{"count":11,"href":"http:\/\/eines-informatiques.recursos.uoc.edu\/gestion-de-datos\/wp-json\/wp\/v2\/pages\/568\/revisions"}],"predecessor-version":[{"id":987,"href":"http:\/\/eines-informatiques.recursos.uoc.edu\/gestion-de-datos\/wp-json\/wp\/v2\/pages\/568\/revisions\/987"}],"wp:attachment":[{"href":"http:\/\/eines-informatiques.recursos.uoc.edu\/gestion-de-datos\/wp-json\/wp\/v2\/media?parent=568"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}