Anda di halaman 1dari 33
CTSQL Procedimientos almacenados y triggers BASE100 CTSQ1. Procedimientas almacenados y triggers Indice 1. NOVEDADES ¥ CONSIDERACIONES PREVIAS 1.1 ACTUAUZACION DF BASES DE DATOS GENERADAS CON VERSIONES ANTERIORES.. 1.2 ASPECTOSA TENEREN CUENTA sa 2. INTRODUCCION A LOS PROCEDIMIENTOS ALMACENADOS Y TRIGGERS.. 2.1 PROCEDIMIENTOS ALMACENADOS. 2.1.1 Ventojas de los procedimientos almacenados. 22° Taeaens . 2.2.1 Ventojas de los riggers 22.2 Consideraciones sobre triggers... 223 Tipos de triggers 3. _INSTALACION DEL SERVIDOR DE PROCEDIMIENTOS ALMACENADOS. 3.1 Regulsros paevios 3.2. SERVIDOR DE PROCEDIMIENTOS ALMACENADOS. a 3.3 PUESTAENEIECUCION DEL SERVIDOR DE PROCEDIMIENTOS ALMACENADOS (SP). 33.1 Fichero storedserverlauncher.jni 33.2 Fichero StoredProcServer.properties. 3.3.3 Fichero etsql.ini 4, PROCEDIMIENTOS ALMACENADOS EN CTSQL. 4.1 CaEACION DE PROCEDIMIENTOS ALMACENADOS. 2 4.2 EJECUCION DIRECTA DE PROCEDIMIENTOS ALMACENADOS... . wo 12 4.3, ELIMINACIGN DE UN PROCEDIMIENTO ALMACENADO 2 4.4 ACTUALIZACION OF UN PROCEDIMIENTO ALMACENADO. B 4S Tamasrsprocenun, 3 5. TRIGGERS EN CTSQL 5.1 CREAGONDE TmGaERS.. 5.2 EUMINACION DE TRIGGERS. 5.3 ACTIVAGION / DESACTIVACION DE TRIGGERS.. 54 TaMasvstivacers. 6 CREANDO PROCEDIMIENTOS ALMACENADOS. 6.1 Cuase AssrRacrSoLProceDure. 6.1.1 Métodos de la clase AbstractSqlProcedure 7. EIEMPLOS. 71 Gemmvot 72 Emo? 73 EEMPLOB vrnminnninn —_ sansa -_ 74 Eiemriod 24 7S EiwnoS 2 Pie = b100_nt_procalma-tggers_100620_v1.doe BASE100 esa CTSQ1. Procedimientas almacenados y triggers 1. Novedades y consideraciones previas A partir de la versién 3.4 de MultiBase y de la version 4.2 de Cosmos, el gestor CTSQIL incluye las si ‘auientes novedades: Soporte para tablas de mas de 2 Gbytes para sistemas operativos basados en tecnologia NT. 1 2. Uso de procedimientos almacenados. 3. Uso de triggers. 11 Actu \cién de bases de datos generadas con versiones anteriores, Como consecuencia de los puntos 2 y 3 anteriormente indicados, ha sido necesario crear dos nuevas tablas en el catdlogo de la base de datos: SYSPROCEDUR y SYSTRIGGERS. Esto implica que para poder utilizar estos mecanismas en bases de datos antiguas es necesatia proceder de acuerdo a los siguien- tes pasos: 1. Greacién de las tablas a partir del siguiente script de SQL. create table systriggers (name char (20), tabname char (20), statenent char (10), event char (10), caliproc char(20), status char(10)) set 16; create unique index trignane on eystriggere (mane): create index trigtsnane on systriggers (tabnane) ; create table sysprocedur (name char (20), classnane char (256), parameters char (128), returning char (128)) set 15, create unique index procnane on sysprocedur (mane); 2. Renombrar como se operative en el direct -2 a continuacién los ficheros fisicos “dat” e “idx” desde el sistema de la base de datos systril6.dat systrigger.dat > systril6.idx > — systrigger.ide > eysprolS.dat sysprocedu.dat sysprolS.idx > — sysprocedu.idx 3. Modificar la columna “dirpath” de la tabla SYSTABLES como sigue: update systables set dirpath = "sysprocedu" where tabnane = "sysprocedur"; update systables set dirpath = “systrigger" where tabnane = "systriggers” 1.2. Aspectos a tener en cuenta + Para la creacin y el reemplazo de los procedimiontos almacenados es necesario utilizar el ‘editor clo sontencias SQL (SQL Interactive) proporcionado con la nuova versién. Por ejemplo, b100_nt_procalma-trggers_100620_v1.doe " BASE100 CTSQ1. Procedimientas almacenados y triggers para la versién de Windows™, ejecutando el archivo esqlexe que se encuentra en el direc torio “e:\multiway\bin’. + Esta nueva version de CTSQ). lleva incorporado el "monitor CTSQL”. Para que los clientes puedan conectarse al servidor es necesario que este monitor esté arrancado. + En Cosmos, la llamada a procedimientos almacenados se realizar mediante el método SqlExec de la clase SqlServer o bien a través de la clase SqlStatement. + En MultiBase, la ejecucién de los procedimientos almacenados se realizaré a través de la ins- truccion “tsql” b100_nt_procalma-trggers_100620_v1.doe " BASE100 CTSQ1. Procedimientas almacenados y triggers 2. Introduccién a los procedimientos almacenados y triggers Este apartado tiene por objeto explicar brevemente qué son, cémo se crean y para qué se utilzan los procedimientos almacenados y los triggers contra el motor de base de datos CTSAL. EI motor CTSQL podrs interactuar con un servidor de procedimientos almacenados (SP), el cual pue- de ser instalado en otro servidor distinto al CTSQL y asi “distribuir" la carga de operaciones entre ellos. El servidor SP nos ayudard también a disminuir la carga de las estaciones de trabajo del cliente, haciendo que las tareas con mayor sobrecarga se lleven a cabo en nuestro servidor SP, como pueden ser los trabajos en batch, Por lo tanto, si ejecutamas procesos de la aplicacién mediante procesos almacenados aprovecharemos tados los recursos de hardware disponibles en nuestro servidor. Los procedimientos almacenados faciltan el desarrollo de nuestras aplicaciones y minimizan el limero de modificaciones ante futures cambios. Asi mismo, pueden ser ejecutados como conse: cuencia de una activacién de parte de un triggers. Esto nos permitiré administrar la informacién de la base de datos, manteniéndola consistente, integra y segura. 2.1 Procedimientos almacenados Los procedimientos almacenados son programas que se referencian en la base de datos. En el caso del CTSQL, estos programas estan escritos en Java™. Al ser referenciados en la base de datos, prime- ramente se deben crear en el catdlogo de la base de datos mediante una instruccidn del CTSQL, y posteriormente podrén ser ejecutados desde el programa cliente © como consecuencia de los trig: gers. Los procedimientas almacenados podran recibir pardmetras de entrada. No podran interactuar con cl usuario a través de una interfaz o pantalla, En cambio, no presentan inconvenientes en escribir en ficheros de textos, XML, etc., 0 en tablas de la base de datos o en la generacién y envio de correos electrénicos, por ejemplo. 2.1.1 Ventajas de los procedimientos almacenados + Dise‘io modular y posibilidad de acceder a bases de datos de otros motores mediante la tecnologia JDBC™. + Las aplicaciones que acceden a la misma base de datos pueden compartir los procedimien: to almacenados, eliminando el codigo doble y reduciendo el tamafio de las aplicaciones, + Facil mantenimiento, procedimiento se actualiza, los cambios se reflejan automyiticamente en todas es, sin necesidad de recompilar los programas. Las aplicaciones son compiladas sélo una ver para cada cliente. + Los procedimientos almacenados son ejecutados por el servidor, no por el cliente, lo que reduce el trafico en la red y mejora el rendimiento, especialmente para el acceso del cliente remoto. 1100 _nt_proc alma-trigers_ 100620 vt. doe " BASE100 CTSQ1. Procedimientas almacenados y triggers + Los procedimientos estén almacenados en los servidores y asegurados por las medidas to: madas en la instalacién, lo que impide que los usuarios normales puedan modificarlos, ya ‘que, incluso, desconacen su existencla, Este es un elemento de gran valor en lo que a segu Fidad respecta, 2.2 Triggers Los riggers permiten “disparar" (ejecutar) procedimientos almacenados cada ver que se realice una accién sobre los datos de una tabla, Esta accién puede consistir en la insercién, modificacién o elimi- nacién de un registro. De esta manera, podemos indicar que se ejecuten acciones sobre los datos de la tabla, o de otras tablas, cada ver que se modifican, agregan o eliminan datos de una tabla, 2.2.1 Ventajas de los triggers Algunos usos de los triggers son: Generacién automética de valores derivados de una columna, + Prevencin de transacciones invsldas. + Proporciona auditoras sofisticadas, + Mantener la sincronta en tablas replicadas. Generacion de estadisticas de acceso. + Publicar informacién de los eventos generados por la base de datos, las actividades de los usuarios o de las estructuras SQL que se han ejecutado, + Actualizar totales de la suma de campos de una tabla en otra, El mantenimiento de la aplicacidn se reduce, los cambios a triggers se reflejan automatica ‘mente en todas las aplicaciones que tienen que ver con la tabla sin necesidad de recompilar. 2.2.2 Consideraciones sobre triggers + Los triggers no tienen parimetros de entrada. Los tinicas valores de entrada con los que pueden trabajar son los del registro que han insertado, modificado o eliminado. + Los triggers no devuelven valores como las procedimientos almacenados. Sélo pueden mo: dificar otras tablas 0 los mismos valores del registro agregado 0 modificado (obviemente, el ‘liminado no). + Hay que tener especial cuidado con los triggers recursivos, es decir, aquellos que puedan realizar operaciones que lancen nuevos triggers. 2.2.3 Tipos de triggers Dependiendo de la accién sobre la cual queremos que actien, se pueden crear tres tipos de triggers: Alinsertar un registro. + Almodificar un registro. 7 'b100_nt_proc-alma-triggers_100629_v1.doc ‘ E100 CTSQ1. Procedimientas almacenados y triggers + Aleliminar un registro. Cada uno tipo de estos tipos se puede dividir a su vez en dos subtipos: antes y después de la accién, En consecuencia, podemos disponer de hasta sels tipos distintos de triggers: + BEFORE INSERT. Antes de insortar un registro. + AFTER INSERT. Después de insertar un registro. ‘+ BEFORE UPDATE. Antes de madificar un registro. + AFTER UPDATE, Después de modificar un registro. ‘+ BEFORE DELETE, Antes de eliminar un registro. + AFTER DELETE. Después de eliminar un registro. 7 'b100_nt_proc-alma-triggers_100629_v1.doc ‘ E100 CTSQ1. Procedimientas almacenados y triggers 3. Instalacién del servidor de procedimientos almacenados 3.1. Requisitos previos + Motor CTSQL iniciado. [Para configurar el CTSQL en Windows™ (a partir de la versién NT) consulte el Anexo IV del documento: Particularidades sobre la instalacién del mator de base de datos en modo clien. re-servidor.] + Maquina virtual Java™ 1.3.x. + Arrancar MONITOR CTSAL iniciad. 3.2 Servidor de procedimientos almacenados El ervidor de procedimientos almacenados es un paquete Java™ que se encarga de comunicarse con el servidor CISQL y de gestionar el alta, la baja, la modificacién y la ejecucién de procedimientos al ‘macenados escritas en Java™. Funciona como un servicio que escucha en un puerto determinado y espera a que un servidor CTSQL se conecte con él para realizar operaciones con procedimientos almacenados. Por cada sesién CTSQL que se conecte al servidor, lanzaré un thread, que seré el que se ocupe de la comunicacién con el CTSQL, quedando libre el servidor de procedimientos almacenados para aceptar nuevas conexiones. 3.3. Puesta en ejecucién del servidor de procedimientos almacenados (SP) Existen tres modos de lanzar el servidor de procedimientos almacenados: + Laprimera opcién, y la més recomendable, es mediante la utilidad storedserverconf. + Empleando el programa storedserver.exe, situado en el directorio “bin”. + Directamente desde la linea de comando. A continuacién vamos a ver en detalle cada una de estas posibilidades. 2) Utilidad storedservercont El programa “storedservercont.exe", situado en el directorio bin, permite parar y arrancar el servidor de procedimientos almacenados, comprobar si esta activo 0 inactivo y cambiar parametros de confi _guracién del servidor, tales como la TRANSDIR, el host donde esté ascuchando el servidor de proce- dimientos almacenados, el servicio, el puerto, la JAVA HOME, el CLASSPATH y el fichero de propie- ddades del servidor de procedimientos almacenados. Esta interfaz almacenard dichos valores en el archivo INI indicado en “Current In File”. Esta es la manera mis recomendable para mancjar configurar el servidor de procedimientos alma cenados, ya que internamente utiliza las dos posibilidades que se van a expicar a continuacién, pero emnpleando una interfaz grafca. b100_nt_procalma-trggers_100620_v1.doe " BASE100 CTSQ1. Procedimientas almacenados y triggers woe 679 Las distintas acciones que se pueden ejecutar desde esta interfaz grfica son las siguientes: tos almacenados. &% | Permite arrancar el servidor de procedi Detiene el proceso del servdor de procedimientos almacenados. a BH _ indica el estado del servidor: Arrancado o parado. $3 Actualiza la informacién del servidor. Los parimetros de la configuracién del servidor podran ser modificados, Al presionar ‘este botdn salvaré los valores en el fichero “storedserverlauncher int” del directorio, Sect g Muestra el fichero de “log” del servidlor de procedimientos almacenados (“procserverlis- tener log”) b) Programa storedserver.exe Este programa se encuentra en el directorio “bin. Se le pueden pasar los parimetros start, stop, status y versién para, respectivamente, arrancar, parar, mostrar el estado y mostrar la versién del servidor de procedimientos almacenados. Utiliza el fichero de conexién “storedserverlauncher.ini” (al igual que en la opcién anterior), y se encuentra en el directorio “et steer “Saat> | ctep> | | ¢) Desde la linea de comando JavA.exe com, transtools agi. ProcServeriistener —inssi1e :\MultiWaysP\eto\StoredProcserver properties -port 9999 Esta forma de ejecutar ol servidor de pracedimientos almacenados es la menos recomendada, ya que debe de utilizarse desde la linea de comands. Pi. J, BASEL00 1100_nt_proc-alma-triggers_100629_v1.doe CTSQ1. Procedimientas almacenados y triggers 3.3.1 Fichero storedserverlauncher.ini El contenido del fichero de conexién al servidor de procedimientos almacenados, que se encuentra en el directorio “etc”, es el siguiente: [Public Envizonnent] ‘TRANSDIR=o: \Mul tAWaySP JSPROCHOST=Localhost JSPROCSERVICESjavastoredproc PoRT=9999 JAVA HOMB=C:\3ak1 3.109 INIFILE=o: \MultitaysP\eto\storedProaServer properties CLASSPATH="c: \MultsWaySP\1ib\ Jeqiproc. Jar /o:\sultsWay\ 1ib\1og4j-1.2.7. jax; o:\\cteqiprecedures” La variable JSPROCHOST contione el nombre de la maquina, 0 la IP, donde se encuentra instalado el servidor de procedimientos almacenados. La variable !SPROCSERVICE indica el nombre del servicio asignado al servidor de procedimientos al- rmacenades. Este servicio debe ser dado de alta en el fchera “services” de Windows™ La variable PORT indica el puerto chero “services” de Windows™, EI nombre dol servicio es l valor que tiene la variable JSPROCHOST y el puerto el valor que tenga la variable PORT. ado por el servidor de procedimientos almacenados en el fi La variable JAVA HOME indica dénde esta instalado Java’ La variable INIFILE indica cudl es el fichero de propiedades que utiliza el servidor de procedimientos almacenados. La variable CLASSPATH indica el CLASSPATH que utilizaré el servidor de procedimientos almacenados, Se ineluyen: "jsalproc.jar” y “logdjl.2.7,jar’. EI CLASSPATH debe ir siempre entre comillas 3.3.2 _ Fichero StoredProcServer.properties El servider de procedimientos almacenados ejecuta la clase ProcServerListener, pasindole como parémetros el fichero de propiedades y el puerto por el que escuchard, El contenido del fichero de propiedades StoredProcServer.properties, que se encuentra en el directo- rio “etc”, serd el siguiente: JSTOREDPROCEDURESPATH=c::\\ctsglprocedures LOGGERACTIVE=FALSE La variable ISTOREDPROCEDURESPATH indica el directorio del servidor donde se almacenardn los procedimientos almacenados. b100_nt_procalma-trggers_100620_v1.doe me BASE100 doveas CTSQ1. Procedimientas almacenados y triggers Elinstalador crear por defecto el path indicado en dicha variable. Si se modifica su valor ser nece: sario reiniclar el servidor de procedimientos almacenados para que los cambios tengan efecto. Es importante tener en cuenta que el path debe indicarse con doble cardcter "\", ya que para laval™ ste es un caracter de escape. La variable LOGGERACTIVE indica si se va a generar 0 no un fichero de log. Los valores posibles son TRUE 0 FALSE Si el valor es TRUE se generard el fichero: “c:\tmp| procserverlistener.log", mientras que si su valor es FALSE 0 no se define la variable, no se generard ningin fichero de log. Su valor por defecto es FALSE. 3.3.3 Fichero cteql.ini Fl contenido del ichara de configuracién del CTSA se encuentra en al diractoria “ete” [Peivate Environnent] [TRANSDIR=c: \Mul tAWaySP DOSNAMEAOFF JsPROCHOSTa1ocal host JSPROCSERVICESJavastoredproe JSSUPPORT=oN La variable TRANSDIR indica el direct donde est instalado el CTSQL La variable DOSNAME indica si las bases de datos que se creen con el CTSQL junto con las tablas del catalogo NO tendrén la limitacién de 8 caracteres en su nombre. (DOSNAME = OFF). Mediante las variables JSPROCHOST y JSPROCSERVICE estamos indicando donde encontraré el servi- dor do procedimiontos almacenados. La variable JSSUPPORT habilita y deshabilita la posi rmientos almacenados. lidad do interactuar con el servidor de procedi Para que los triggers y los procedimientos almacenados funcionen, la variable de entorno JSSUP- PORT deberd tener el valor “ON". Pi. b100_pt_proc-alma-triggers_100629_v2.doc )_nt_pe Seaers. 100GZ9.§ dies E100 b100_nt_proe-almatriggers_100629_v1.doe me BAS CTSQ1. Procedimientas almacenados y triggers 4. Procedimientos almacenados en CTSQL Como hemos mencionado anteriormente, es necesario registrar los procedimientos almacenados en la base de datos. Para ello emplearemos las siguientes cuatro instrucciones SQL incorporadas al mo- tor, para crear, eliminar, modificar y ejecutar los procedimientos almacenados que ut 4.1. Creacién de procedimientos almacenados INSERT JAVA PROCEDURE FROM IN Ejemplo; Insert java procedure myprocl from “e:\con\tt\test\nyprocl.class” in com. tt. test myproel” La instruccién enviard un fichero previamente compilado (clase Java™) al servidor de pracedimientos almacenados. Siconsigue enviarlo cotrectamente, lo da de alta en el catdlogo en la tabla SYSPROCEDUR, Si no consigue enviarlo correctamente, devuelve un mensaje de error indicando la causa por la que no se dio de alta, 4.2. Ejecucién directa de procedimientos almacenados CALL JAVA PROCEDURE ({ paranstere] ); Ejempto: call java procedure myproci (); Esta instruccién ejecuta directamente el procedimiento almacenado que se indique. La instruccién comprobard su existencia en el catdlago y comunicaré al servider de procedimientos almacenados la clase Java™ con la que se encuentra asociado, asi come los parmetros con los que se ejecutaré. Sino existe el procedimiento almacenado, devuelve error indicdndole. 43° Eli inacién de un procedimiento almacenado DROP JAVA PROCEDURE . Ejemplo: drop java procedure myprocl La instruccion comprueba la existencia del procedimlento almacenado en el catélogo (tabla SYSPRO- CEDUR). Si existe, comunicar la decisién de eliminarlo al servidor de procedimientos almacenados. Este comprobaré que existe la clase on el path donde se almacenan ls procedimentos almacenados lo eliminara. Si el servidor consigue eliminaro,seré eliminado también del catélogo. Si falla el bo- E100 does CTSQ1. Procedimientas almacenados y triggers rrado fisico (permisos, inexistencia) o la eliminacién del catalogo {inexistencia), devolvers al perti- rente err y-cancelaré la operacién. 4.4 Actui acién de un procedimiento almacenado REPLACE JAVA PROCEDURE FROM IN ; Ejemplo: replace java procedure myprocl from “c:\con\tt\test\myproc?.class” in “com. tt. test. myproc2”; La instruccién enviard un fichero previamente compilado (clase Java™) al servidor de procedimientos almacenados. Si el procedimiento almacenado no existe en el catélogo, 0 si no consigue enviarlo correctamente, devolverd un error indicando la causa por la que no se reemplazé, 4,5 Tabla sysprocedur Esta tabla gestionard los procedimientos almacenados, y se crearé autométicamente al generar la base de datos junta con las demas tablas del catalogo del sistema, SYSPROCEDUR: Name class Parameters | Returning Char(20) char(256) | Char(128)——_Char(128) PRIMARY INDEX: name Este catlogo nos sirve para pader encontrar las clases lava asociadas a los procedimientos alma cenados. b100_nt_procalma-trggers_100620_v1.doe ms BASE100 dasa CTSQ1. Procedimientas almacenados y triggers 5. Triggers en CTSQL Como ya hemos mencionado, en nuestro caso el triqger sera un mecanismo de activacién de proce: dimientos definidos en clases Java™ que residan en la parte servidora, Cuando un trigger invoque a Ln procedimiento almacenado, pasar a éste como parimetro el tipo y el valor de las columnas de la fila en curso, 5.1 Creacién de triggers CREATE TRIGGER BEFORE|AFTER INSERT|DELETE |UPDATE ON ; Ejemplo: create trigger mytriggerl before insert on clientes myprocl: La instruccién erearé un trigger, que ejecutaré la clase Java™ asociada al procedimiento almacenado procname>, antes 0 después de que se ejecute una operacién de modificacién de datos sobre la tabla , Siel procedimiento almacenado no existe en el catdlogo, o sino consigue ejecutarlo correctamente, devolverd un error indicando la causa por la que no se ejecuts. Solamente se pod insertar un trigger por cada accién y tiempo sobre una tabla, es decir, solamente existré un trigger para un AFTER UPDATE TABLA, aunque se declaren con nombres y procedimien- tos dstintos, ya que tendrén caracteristicas similares. 5.2 Eliminacién de triggers DROP TRIGGER Ejemplo: drop trigger mytriggerl; La instruccién eliminard el trigger que se indica. 5.3. Activaci6n / Desactivacién de triggers ALTER TRIGGER ENABLE | DISABLE; Ejemplo: alter trigger mytriggerl diable; La instruceién activaré o desactivard ol trigger que se indica. Si un trigger se encuentra desactivado, ‘no ejecutaré el procedimiento almacenado asociado a él b100_nt_procalma-trggers_100620_v1.doe ied BASE100 saves CTSQ1. Procedimientas almacenados y triggers 5.4 Tabla systriggers Para gestionar los triggers nos valdremos de la tabla “systriggers” de la base de datos, cuya estructura es la siguiente: incorporada en nuestro catalogo Name tabname | Statement | when callproc | status Char(20) | Char(20) | Char(10) | Char(10) | Char(30) | Char(10) b100_nt_procalma-trggers_100620_v1.doe ms BASE100 dsseaa CTSQ1. Procedimientas almacenados y triggers 6. Creando procedimientos almacenados 6.1 Clase AbstractSqlProcedure La clase AbstractSqlProcedure es de la que derivan los procedimientos almacenados y la que se tiene que utilizar como base para la creacién de procedimientos almacenados. Se encuentra declarada en el paquete com.transtools.sql, por lo tanto, debers incluirse este paquete en la realizacién de nues: tros procedimientos almacenados. El paquete “com.transtools.sql" se encuentra incluido en el fichero “jsalorocjar”, que esté presente en el directorio “lib” de la distribucién, Un procedimiento almacenado debe dectarar ol método “run\)’, ya quo éste es exportado por Ia cla se "AbstractSqlProcedure”. Dicho método seré el métado de entrada del procedimiento almacenado. 61a Métodos de Ia clase AbstractSq[Procedure Exporta los siguientes métodos pablicos: public SqlArgument gotArgument(int index) Devuelve el enésimo parémetro pasado al procedimiento almacenado, public SqlArgument getArgument(string colName) Devualve el enésimo parématro pasado al pracedimiento almacenado. public String getArgumentNamefint index) Devuelve el nombre del enésimo parmetro pasado al procedimiento almacenado. public int getArgumentCount() Devuelve el nimero de pardmetros pasados al procedimiento almacenado, Connection getConnection|) Devuelve un objeto de la clase “Connection”, que se corresponde con la conexién que tiene establecida con el servidor CTSQ\L public int istrigger() Devuelve TRUE si el procedimiento almacenado ha sido lanzado desde un trigger. public int istriggerBefore() Devuelve TRUE si el procedimiento almacenado ha sido lanzado desde un trigger declarado como BEFORE. public int isTriggerAfter() Devuelve TRUE si el procedimiento almacenado ha sido lanzado desde un trigger declarado como AFTER, public int ieTriggerInsert() Devuelve TRUE si el procedimiento almacenado ha sido lanzado desde un trigger declarado fen una operacién INSERT. 1100 _nt_proc alma-trigers_ 100620 vt. doe ba BASE100 dessas CTSQ1. Procedimientas almacenados y triggers + public int isTriggerDelete() Devuelve TRUE si el procedimiento almacenado ha sido lanzado desde un trigger declarado fen una operacién DELETE. + public int isTriggerUpdate() Devuclve TRUE si el procedimionto almacenado ha sido lanzado desde un trigger declarado fen una operacién update. Como ya hemos mencionado, cuando un trigger invoque a un procedimiento almacenade, le pasar’ como parémetro el tipo (mediante “isTriggerBefore|)", “isTriggerlnsert()", etc. podremos saber qué tipo de trigger se ha “disparado’) y ol valor de las columnas de la fila en curso, para lo que haremos Uso del método “getArgument(i’, teniendo en cuenta las siguientes consideraciones respecto del tipo de trigger: BEFORE AFTER, Operacion istriggerBefore() isTriggerAfter() INSERT Valores que seran insertados cuando isTriggerinsert() Tesla Jossernnes.2on rl se complete la instruccion, uppate Valores originales dela fla antes de | Nuevos valores que seran escritos, IsTriggerUpdate() __ la actualizacién, ‘cuando se complete la orden DELETE Valores antes del borrado dela fila. Todos los campos son null. isTriggerDelete() 1100 _nt_proc alma-trigers_ 100620 vt. doe ba BASE100 pea CTSQ1. Procedimientas almacenados y triggers 7. Ejemplos Para realizar nuestros primeros ejemplos debeos comprobar que tenemos arrancado el motor CTSQL_y el monitor (si corresponde) y el servidor de procedimientos almacenados. Realizamos una conexién y creamos una nueva base de datos, verificando que en el catdlogo de nuestra base de da tos se encuentren las tablas “sysprocedur” y “systriggers” Trabajaremos, por ejemplo, con el paquete “com.tt.test”, por lo que los procedimientos Java™ que creemos de aqui en adelante lo haremos en al directorio “c:\com\tt\test” Escribiremos nuestro cédigo en un editor de texto 0 en cualquier otro IDE. Seguidamente deberemos compilar los fuentes Java™, verificanda que se generen los ficheros “class” correspondientes, que seran los que utilizar nuestro servidor de procedi sntos almacenados. Recordemos que debemos de inclur el fichero “jsqlproc jar” en ef CLASSPATH para que al compilar encuentre la clase “AbstractSqlProcedure” y no se produzcan errores. Resumiendo: + Arrancar CTSQL y monitor (si es necesario} + Arrancar $P Server (sies necesario).. + Esctibiry realizar la compilacién del procedimiento correspondiente. Para procedimientos almacenados: + Registrar el procedimiento en las tablas del catdlogo “sysprocedur’ + Realizar la llamada al procedimiento desde la aplicacién cliente o desde el CISQL Para triggers: + Rogistrar el procedimiento en las tablas del catdlogo “sysprocedur’, + Activar un trigger para que ejecute un procedimiento almacenado determinado. + Realizar le operacién en la tabla para la cual se ha activado el trigger. 1100_nt_proc-alma-triggers_100629_v1.doe CTSQ1. Procedimientas almacenados y triggers 7.1 Ejemplo 1 En este primer ejemplo realizaremos nuestro primer procedimiento almacenado. Fl eddigo serd el siguiente: package con. tt test; import com.transteols eql.t; //Paquate necesavio para poder utilizar 1a clase Abstractsq1Procedure import java.ie.t; public class myprocl extends AbstractSqlProcedure ( public myprocl() ( , //2ste nétedo es cbligatoric para programar los procediniento alnacenados //Implenenta el nétodo abstzacto de 1a clase AbstractSqlProceduze public int runt) ( try ( FileWriter fichero = new Fileliriter ("'c: /tmp/myprocl. 16: BufferedWriter buffer = new BufferedWriter (fichere) ; PrintWeiter fichLog= new PrintWriter (buffer) ; fichLog-printin ("Mi priner procediniente alnacenado") ; fichLog.printin("Hay "+ getArgumentCount () + " argumentos") ; fichLog.close(); , eaten (Exception @) { e-printstackTrace() ; xeturn (D) > Posteriormente, insertamos el procedimiento almacenado en la tabla “sysprocedur”: procedure myprocl from o:\con\tt\test\nypreel ol: Yt myprecl” ; Aqui comprobaremos que el fichero “myproct.class” se encuentre fisicamente donde lo hayamos definido en la variable de entorno JSTOREDPROCEDURESPATH, b100_nt_procalma-tggers_100620_v1.doe ms BASE100 doses CTSQ1. Procedimientas almacenados y triggers Fjecutamos el procedimiento almacenado: eall java procedure myproel () ; Comprobamos el contenido del fichero de texto “C:\tmp\myproct.log”. 7.2. Ejemplo2 En este ejemplo realizaremos nuestro primer trigger. El cédigo sera el sig nite: package com tt test; import con. transtools.sql.*; import java.io.*; public clase myproe? extends AbstractSglProcedure ( public myproc2() ( ) public int xun() ( try ( Filelriter fichero = new Fil Weiter ("e: /tnp/myproa2. log", true) BufferedNriter buffer = new Bufferediriter(fichero) ; PrintWeiter fichlog= new PrintWriter (buffer) ; fichLog.printin ("Mi primer trigger"); fehLog.printin ("Hay "+ gathygumentCount() +" axgunente: Af Gstrigger() ) ( fichLog println ("Estoy en un trigger"); ) Af (eteiggeratter()) ( Af (astriggerperete()) fichtog.printin ("Es AFTER - DELETE") ; ) else Af (AsTeiggestpdate()) ( fichtog.printin ("Es AFTER - UPDATE"); dares ( 1100_pt_proe-imatiggers_100629_vt.doe m BASE100 bossa CTSQ1. Procedimientas almacenados y triggers fiehtog.printin ("Es AFTER ~ INSERT") ; ) , else ( Af (stetggexderete())( ‘fichLog.printin ("Es BEFORE - DELETE"); ) else Af (istriggertpdate)) ( fichLog-printin ("Es BEFORE - UPDATE"); fichteg.printin ("Es BEFORE - INSERT"); , fichLog.clese() > catch (Exception e) { e.printstackTrace() ; , retuen(1) ; ) , Posteriormente, insertamos el procedimiento almacenado en la tabla “sysprocedur”’ insert java procedure myproc? from "e:\com\tt\test\myproc?.class” in "com. tt. test.myproc2"; ‘Aqui comprobaremes que el fichero “myproc2.class” se encuentre fisicamente donde lo hoyamos definido en la variable de entorno ISTOREDPROCEDURESPATH y que se haya insertado el registro correspondiente en la tabla “sysprocedur’. Posteriormente creamos la tabla provincias: cxeate table provincias ( provincia SMALLINT NOT NULL LABEL "Cod. Provincia", dezortpeion CHAR(20) LABEL "Provincia", prefize SNALLINT LABEL “Frefijo" > PRIMARY KEY (provincia) ; a rg A Fa i BASE100 43 CTSQ1. Procedimientas almacenados y triggers Y agregamos un trigger que se ejecutars después de cada insercién de registros en la “provincias”, indicando que el procedimiento almacenado "myproc2” seré el que se ejecute en este caso: create trigger mytriggerl after insert on provincias myproc?; Para comprobar que esto ha surgido efecto, realizamos la verificacién correspondiente sobre la tabla “systriggers”. Por ditimo, realizamos una insercién en la tabla “provincias", por ejemplo: insert into provineias values (1,"CORDOBA”,32) Comprobamos el contenido del fichero de texto “C:\tmp\myproc2.log” para este caso. 7.3 Ejemplo3 Ahora veremos un ejemplo de céma recoger los valores de la fila en curso después de un INSERT en la table " Name(i)”. rovincias", para mostrar cémo se utilizan los métodos “getArgument(}" y “getArgument. package com.tt.test; Amport con. transtools.eqi.*; import javaie.t; import Sava.eal.*; public class myproc3 extends AbstractSqlProcedure { public myproc3() { , public int run() { tey Ant i= 0; Fileriter fichero = new Fileliriter("e:/tnp/nyproc3. log", true) : ButteredWriter butter = new Buf¢eredWester (tiehexe) ; Printriter fichLog= new PrintWriter (butter) ; fichLog.printin ("Mi segundo trigger") ; fichLog printin("Hay "+ getArgumentCount() + " argunentos" ); while (4 < getAcgumentCount()) { FichLog.printin ("Nombre columna ("+it"): " + gethegumentName (i) ) fichLog-printin ("Valor columna ("4iH"): 7 + getArgunent (i) .getSqlArgunent ()) ; FichLog.printin ("Tipo abe ("#44"): "+ getArgunent (1) .getJabetype()) ; b100_nt_procalma-tggers_100620_v1.doe me BASE100 er CTSQ1. Procedimientas almacenados y triggers fichLog. close) ; ) eatch (Exception e) { e-printstackTrace() ; , return (1); , , Insertamos nuevamente, el procedimiento almacenado en la tabla sysprocedur: insert java procedure myproc3 from "e:\con\tt\test\myproc3.class” in "com. te. test .myproc3"; ‘Aqui comprobaremes que el fichero “myproca.class” se encuentre fisicamente donde lo hoyamos definido en la variable de entorno ISTOREDPROCEDURESPATH y que se haya insertado el registro correspondiente en la tabla “sysprocedur’. Borramas el trigger AFTER INSERT creado anteriormente y creamos uno nuevo asocidndole el proce: dimiento almacenado “myproc3": drop trigger myteiggerl; create trigger mytriggerl after insert on provincias myproc3; Para comprobar que esto ha surgido efecto, realizamos la verificacién correspondiente sobre la tabla “systriggers”. Volveros a realizar un INSERT sobre la tabla: insert into provineias values (2,"MURCIA”,54) ; El contenido del fichero “myproc3 log” seré el siguiente: Mi segundo trigger Hay 5 argunentos po abo (0): 5 Nonbre colunna (0): provincia Valor columna (0): 2 Tipe Jae (2): 1 Nonbre colunna (1); deseripcion Valor columna (1): MURCIA Tipo Jabo (2): 5 Nombre colunna (2): prefijo b100_nt_procalma-tggers_100620_v1.doe hed BASE100 er CTSQ1. Procedimientas almacenados y triggers Vator colunna (2): 54 po Jabe (3): 4 Nombre columna (3): (tabi) Valor columma (3): 150 Tipe Jabe (4): 4 Nombre columna (4): (rowid) Valor columa (4): 3 Como podemos apreciar, la tabla “provincios” tiene 3 compos (que hemos definido mediante el CREATE), pero el trigger le pasa como pardmetro al procedimiento olmacenade, ademds de los co- lumnos de lo fila que proceso, el “tabid” de la tobla y el “rowid” de fila que esté siendo trarada. 7.4 Ejemplo 4 En este ejemplo mostraremos cémo realizar un log sobre las altas, bajas y modificaciones llevadas a cabo sobre la tabla “provincias”, Para ello, crearemos una nueva tabla con la misma estructura que “provincias", agregando 3 campos mas: el rowid, el tabid y ol tipo de instruccién SQL que se ha ejecu- tado. create table log prov ( provincia SMALLINT NOT NULL LABEL "Cod. Provincia", descripeion CHAR(20) «LABEL "Provincia", prefize SMALLIND LABEL "Pretszo", mytabid INTEGER, nyrowia INTEGER, accion CHAR (15) > EI procedimiento contempla todos los posibles tipos de datos del SQL, pudiéndose adaptar muy facilmente a cualquier otra tabla y no solamente a la de “provincias”. package com. tt. test, import con. transteols.ql.*; Amport Java.sal.*; import java.util @regoriancalenday, import java.util.Calendar; public clase myproct extends AbstractSalProcedure ( b100_nt_procalma-trggers_100620_v1.doe me BASE100 oases CTSQ1. Procedimientas almacenados y triggers public myproes() { ) public int run) ( int i= 0; boolean isWull = fais String action="; ProparedStatenent pstmt = null; Af (sTeiggeratter()) ( Af (Astriggerdeiete())( action = new String("APTERDELETE") ; 1d eise Af (LetriggerUpdate()) ( action = new String("AFTERUPDATE") ; } else ( //Setriggerinsert action = new String ("AFTERINSERD") ; ) ease ( Af (Asteiggexdeiete()) ( action = new String("BEFOREDELETE") ; d etze Af UAsTeiggertpaate)) action = new String("BEFOREUPDATE") ; ) else (//ieteiggerInsert action = new String("BEFOREINSERD") ; try petnt = getConnection() preparestatenent("ineert into Log_prov values (?,2,2,2,2,2)" 7 while (4 < getArgunentCount()) { Af (getargument (1) .getsqiArgument () == nul1) pstmt.setMuli (i + 2, getArgunent (i) .getJébetype() 17 else ( switch (getArgument (4) .getJabeotype ()) { 1100_pt_proe-imatiggers_100629_vt.doe bd BASE100 CTSQ1. Procedimientas almacenados y triggers case Types. CHAR patnt (String) getArgunent (1) .getSqlArgunent ()) 7 break; ace Types. INTEGER: pstmt ger) getArgunent (i) .getSqlArgunent ()) -intValue() ); break; ‘Types. SMALLINT: emt i +d String’ i + 1, (ante- patnt.setshort (1 + 1, ((Short) getArgunent (1) .getSqlArgunent ()) .shortValue()) ; break; ease Types. TIME petmt.cetTine(i + 2, convertToine (getArgunent (4) .getSgiArgunent ())) break; case Types. DECIMAL: patmt ble) getArgunent (1) .getSqlArgument ()) .doubleVaiue()) 7 break; J@ Types DATE: eDouble(i + 1, ((Dou- patmt.setDate (1 +1, convertTobate (getArgunent (1) .getSqlargument ())) break; ‘Types TIMESTAMP: petnt.cotTinestanp (itl, convert ToDateTine (gatAzgument (4) .getSalArgument ())) 7 break; default break; , itt ) petmt.setString( i +1 , action); pstmt execute () ; ) catch (SQLEKception e) ) Pi. 'b100_nt_proc alma-triggers_100629_v1.doe ?_nt_pr Seaers. 100GZ9.§ de seaa BASE100 CTSQ1. Procedimientas almacenados y triggers finatiy( Af (pstmt I= nulz) try ( pstmt.close() } catch (SoLException el) { return (1); ) private java sql.Tine convertToTime (Object object) throws SQLException ( Calendar cal = (Calendar) object; Af (object == nut) ( return mull; ) Tine timevalue = new Time(L) return new java.sql-Time (cal .getTime() .getTime()) ; private java.sql.Date convertToDate (Object object) { Calendar cal = (Calendar) object; Date datevalue = new Date (1); Af (object == mutt) ( return mull; ) Af (object instanceof java.util.Date) { eal. setTine ((java-utii.Date) abject) ; ) return new Java.sql.Date(cal.getTine() .getTine()); , private Java. sql. Timestamp convertToDatetime (Object object) throws sQlException ( Calendar cal = (Calendar) object; Af (object == mutt) ( return mull; aon aro a gu 20529 * BASEL00 aa CTSQ1. Procedimientas almacenados y triggers , Timestamp datetinevalue = new Tnestanp (1) ; return new java.sql.Timestanp(cal.getTine() .getTime()) ; ‘Como siempre, insertamos el procedimiento almacenado on la tabla “sysprocedur Ansert java procedure myprocd from "c:\con\tt\test\myproct class” in “com. tt.test.myprocd”; A continuacién creamos los triggers para realizar la aui procedimiento “myproca”: drop trigger mytriggerl; //elinine ya que no puede haber dos triggers sobre after insert provincias en este caso create trigger mytriggerl before update on provincias myproc4; create trigger mytrigger? before delete on provineias mypreed; create trigger mytrigger3 after insert on provincias myproct; create trigger mytrigger4 after update on provincias myproc4; Realizamos una operacién de insercién, una de modificacién y luego otra de modifcar, a fin de pro- bar la ajecucién de los cuatro triggers agrogados antoriormente: Ansert into provincias values(S,"ALAVA",@8) update provincias set descripcion="MADRID" ,prefi3: cian; 10 where provin- delete from provincias where provinciasS; Después de realizar las operaciones SQL anteriores, la tabla “log_prov’ tendrs el siguiente aspecto: S|ALAVA| 8815015 |AFTERINSERT| 5 |ALAVA| 88 | 15015 | BEFOREUPDATE| SIMADRID|110 150] 5 |APTERUPDATE| SIMADRID|110 150] 5 |BEFOREDELETE | Pi. a rg A Fa * BASE100 CTSQ1. Procedimientas almacenados y triggers 7.5 Ejemplo 5 En este ejemplo veremos cémo lanzar un procedimiento almacenado desde una aplicacién Cosmos, con la intencién de mostrar cémo se podrian utilizar los procedimientos almacenados como trabajos en batch, Para ello convertiremas el médula "facturar” dol aplicative de ejemplo “Cosmas Almafac” a un pro- cedimionto almacenado en Java™, package com.tt. test: import con. transtools.eql.*; Amport java.eal.*; import Java.to.*; public clase facturar extends AbetractSqlProcedure ( public facturar() ( , public int run() ( try ( FileWeiter fichexe Weiter ("o:/tmp/tacturar. Log’ BufferedWriter buffer = new Bufferediiviter (fichere) | PrintWeiter fichlog= new PrintWriter (buffer) ; fichLog.printin("Hay " + getArgunentCount() + " argunentos") ; String condicionExtra: fichLog.printin("Argunento:" + getArgu- ment (0) .getSqlArgunent ()) ; String munclis "" + getArgunent (0) .getsqlArgunent () Af (muncli.compareto("0") t= 0) ( condicionExtra= "and clientes cliente =" + numeli; fichLog.printin (condictonzxtra) ; String clientes String prevCliente=""; double totalGeneral double totalCliente=0; 1100_pt_proe-imatiggers_100629_vt.doe me BASE100 og seaa CTSQ1. Procedimientas almacenados y triggers Connection connection = this. getConnection() ; PreparedStatenent pStntUpdateClientes PreparedStatement pStmtUpdateAlbarancs PreparedStatenent pStatCursorClientes String sqlUpdateClientes= ‘update clientes pull; pull; pul; String eqlCursorClientes= -albaran’+ * cantidaa "+ albaranes.cliente"+ dineas. albaran"+ I) Prepare “total_factura = 2 + “where cliente = 2"; update albaranes set "+ “estado = 's! where albaran = 7 “select clientes.cliente, albara~ ", eum(precie * (1 - descuento/100) " from clientes, albaranes, lineas"+ "wnexe estado t= 1s!" + condicionExtes + " and clientes.cliente = " and albaranes.albaran = " group by 1, 2 order by 1, 2"; pStntUpdateClientes = connec- tion. preparestatenent (sglUpdateClientes) ; pStmtUpdateal~ baranessconnection.preparestatenent (sqlUpdateaibaranes) ; pStntCursorClientes connection. preparestatenent (sqiCursorClientes) ; RecultSet roupStntCursorClientes.executeguery () Ant posts Ant poez=2; 1b100_t_proc-alma-triggers_100629_v1.doc o*. BASE100 CTSQ1. Procedimientas almacenados y triggers wnite (rs.next(0) ( Ant elim re.getint(1); clientes rs.getstring(D) ; Ant albaran= xs.getInt (2); double totalAibaran=rs.getDoubie (3) pStntUpdateAlbaranes.setInt (post, albaran) ; pStmtUpdateAlbaranes executeUpdate () Af (cliente. conparemo (prevCliente) == 0) ( totalciiente = totalCliente + totalAlbaran; fichtog.printin("Clientes:" + prevCliente +" =" + cliente +8 "+ new Ja- va. text.DecinalFormat (", #0.00") .fornat (totaiCliente)) ; Af ( preveliente pStntUpdateclien- tes satDouble (posi, totalCiiente) ; pStmtUpdateclien- tes setInt (pos2, Integer valueO# (prevCliente) .intValue()); pStntUpdateClientes.executelpdate () fichLog.printin("Ciientel=:" + prevcliente +" =" 4 cliente + new ja- va. text DecinalFormat ("#, ##0-00") . format (totalCliente))); , totalCliente= totalAlbaran; prevClienteccliente; ) totalGeneral= totaiGeneral + totalAibaran; ) Af ( preveliente t=") ( pStntUpdateClientes. setDouble (post, totalCliente) ; pStntUpdateciien- toe cetint (pos? Integer valueOs (prevCliente) .intValue ()) pStmtUpdateClientes executeUpdate () ; ) fichLog-printin("Total General: § " + new Java. text DecimalFormat ("#,##0.00") . format (totalGeneral) ); 1100_pt_proe-imatiggers_100629_vt.doe ms BASE100 gies CTSQ1. Procedimientas almacenados y triggers #hehteg. closet) ; pStntUpdateCiientes.close() pStntUpdateAlbaranes close () ; pStmtCursorClientes. close () ) atch (Exception @) ( e printStackTrace() ; , return (1); ) Como siempre, insertamos el procedimiento almacenado en la tabla “sysprocedur” insert java procedure facturar from "e:\con\tt\test\facturar.clase" in "com. tt. test. facturar’ Recordamas que en el mecanismo de facturacién del proyecto “almafac” se podia realizar una factu- racién a todos los clientes de la base de datos, asi como también facturar a un cliente en particular. Esto nos sorvira para mostrar como so le pueden pasar paramotros a un procedimiento almacenado; si el pardmetro es nul, se facturaré a todos los clientes, sino, en el parSmetro se indicaré el cédigo de cliente a facturar. La llamada a este procedimiento almacenado desde Cosmos se haré de la siguiente manera: on command Todos begin facturar (mull) end on Conmand UnCliente objects begin cliente as integer end begin Af Sql-SelectWindow total_factura from clientes" b100_nt_procalma-tggers_100620_v1.doe me BASE100 Qpeeaa CTSQ1. Procedimientas almacenados y triggers "Seleccione Clientes" a seliente ) then Af cliente is not null then facturar (cliente) ; ond Private facturar(elienteOpeional as integer default null) begin Sql. SqlExec("call Java procedure facturar(7)", clienteopcional) ; self MessageBox ("Proceso de facturacion lanzado! !","AVISO") ; end ‘También podremos ejecutar este procedimiento como siempre: call java procedure facturar(); En este caso hard una facturacién a todos los clientes de Ia base de datos. call java procedure facturar (58); Meediante esta llamada facturara sélo al cliente 58, por ejemplo, En Ia aplicacion de ejemplo de Multi8ase (almacén}, el procedimiento almacenado que tenemos que generar serd el mismo, y la lamada desde un médulo de MultiBase es la siguiente: databace pruebas main begin SQL "call Java procedure facturar (58) ;" fend main b100_nt_procalma-tggers_100620_v1.doe ms BASE100 gages

Anda mungkin juga menyukai