# Creando la Base de Datos CREATE DATABASE `mw` DEFAULT CHARACTER SET `latin1` COLLATE `latin1_swedish_ci`; # Creando las Tablas # Creando la tabla entidad Clientes CREATE TABLE `clientes`( `id` INT ( 3 ) NOT NULL AUTO_INCREMENT , `nombre` VARCHAR ( 64 ) NOT NULL , `direccion` MEDIUMTEXT NOT NULL , `telefono` VARCHAR ( 24 ) NOT NULL , PRIMARY KEY ( `id` ) , UNIQUE ( `nombre` ) ) ENGINE = INNODB COMMENT = "Tabla de Clientes"; # Agregando algunos datos INSERT INTO `clientes` (`nombre`, `direccion`, `telefono`) VALUES ('Juan Lopez', 'Ciudad Guatemala', '55522332'); INSERT INTO `clientes` (`nombre`, `direccion`, `telefono`) VALUES ('Comercial Americano', 'Escuintla', '55531512'); INSERT INTO `clientes` (`nombre`, `direccion`, `telefono`) VALUES ('Zapateria El Tacon', 'Ciudad Guatemala', '33221154'); INSERT INTO `clientes` (`nombre`, `direccion`, `telefono`) VALUES ('Ferreteria El Clavo', 'Quetzaltenango', '44454502'); INSERT INTO `clientes` (`nombre`, `direccion`, `telefono`) VALUES ('Cevicheria El Pulpo', 'Escuintla', '54651515'); INSERT INTO `clientes` (`nombre`, `direccion`, `telefono`) VALUES ('Muebler’a El Roperon', 'Ciudad Guatemala', '54615151'); # Creando la tabla entidad Deudores CREATE TABLE `deudores`( `id` INT ( 3 ) NOT NULL AUTO_INCREMENT , `nombre` VARCHAR ( 64 ) NOT NULL , `direccion` MEDIUMTEXT NOT NULL , `telefono` VARCHAR ( 24 ) NOT NULL , PRIMARY KEY ( `id` ) , UNIQUE ( `nombre` ) ) ENGINE = INNODB COMMENT = "Tabla de Deudores"; # Agregando algunos datos INSERT INTO `deudores` (`nombre`, `direccion`, `telefono`) VALUES ('Jervacio Lopez', 'Ciudad Guatemala', '55522333'); INSERT INTO `deudores` (`nombre`, `direccion`, `telefono`) VALUES ('Comercial Tin Tan', 'Escuintla', '55531511'); INSERT INTO `deudores` (`nombre`, `direccion`, `telefono`) VALUES ('Abarroteria 123', 'Ciudad Guatemala', '33221155'); INSERT INTO `deudores` (`nombre`, `direccion`, `telefono`) VALUES ('Panader’a El Pirujo', 'Quetzaltenango', '44454507'); INSERT INTO `deudores` (`id`, `nombre`, `direccion`, `telefono`) VALUES ('6', 'Muebler’a El Roperon', 'Ciudad Guatemala', '54615151'); # Creando la tabla entidad Facturas C x C CREATE TABLE `facturas_cxc`( `numero` INT ( 6 ) NOT NULL AUTO_INCREMENT , `id_cte` INT ( 3 ) NOT NULL , `fecha` DATE NOT NULL , `descripcion` MEDIUMTEXT NOT NULL , `valor` DECIMAL ( 7 , 2 ) NOT NULL , PRIMARY KEY ( `numero` ), CONSTRAINT `FK_CLIENTE` FOREIGN KEY `FK_CLIENTE` ( `id_cte` ) REFERENCES `clientes` ( `id` ) ON DELETE NO ACTION ) ENGINE = INNODB COMMENT = "Tabla de Facturas CxC"; # Agregando algunos datos INSERT INTO `facturas_cxc` (`numero`, `id_cte`, `fecha`, `descripcion`, `valor`) VALUES ('555', '1', '2007-01-15', 'Servicios de Imprenta', ' 2520.25'); INSERT INTO `facturas_cxc` (`numero`, `id_cte`, `fecha`, `descripcion`, `valor`) VALUES ('556', '5', '2007-01-18', 'Por Consumo', '185.30'); INSERT INTO `facturas_cxc` (`numero`, `id_cte`, `fecha`, `descripcion`, `valor`) VALUES ('557', '2', '2007-01-20', 'Accesorios varios', ' 228.85'); INSERT INTO `facturas_cxc` (`numero`, `id_cte`, `fecha`, `descripcion`, `valor`) VALUES ('558', '3', '2007-01-21', 'Materia Prima', '3258.45'); INSERT INTO `facturas_cxc` (`numero`, `id_cte`, `fecha`, `descripcion`, `valor`) VALUES ('559', '4', '2007-01-15', 'Servicios de Imprenta', ' 2520.25'); INSERT INTO `facturas_cxc` (`numero`, `id_cte`, `fecha`, `descripcion`, `valor`) VALUES ('560', '4', '2007-01-25', 'Loza Sanitaria', '1456.40'); INSERT INTO `facturas_cxc` (`numero`, `id_cte`, `fecha`, `descripcion`, `valor`) VALUES ('561', '4', '2007-01-16', 'Material Construcci—n', ' 1455.00'); INSERT INTO `facturas_cxc` (`numero`, `id_cte`, `fecha`, `descripcion`, `valor`) VALUES ('562', '4', '2007-01-15', 'Compras Varias', '3257.50'); INSERT INTO `facturas_cxc` (`numero`, `id_cte`, `fecha`, `descripcion`, `valor`) VALUES ('563', '5', '2007-02-20', 'Compras Varias', ' 84.50'); INSERT INTO `facturas_cxc` (`numero`, `id_cte`, `fecha`, `descripcion`, `valor`) VALUES ('564', '1', '2007-02-21', 'Compras Varias', '984.54'); INSERT INTO `facturas_cxc` (`numero`, `id_cte`, `fecha`, `descripcion`, `valor`) VALUES ('565', '1', '2007-02-22', 'Compras Varias', ' 6987.40'); INSERT INTO `facturas_cxc` (`numero`, `id_cte`, `fecha`, `descripcion`, `valor`) VALUES ('566', '2', '2007-03-08', 'Compras Varias', '6513.80'); INSERT INTO `facturas_cxc` (`numero`, `id_cte`, `fecha`, `descripcion`, `valor`) VALUES ('567', '2', '2007-03-10', 'Compras Varias', ' 6541.00'); INSERT INTO `facturas_cxc` (`numero`, `id_cte`, `fecha`, `descripcion`, `valor`) VALUES ('568', '3', '2007-03-11', 'Compras Varias', '9845.00'); INSERT INTO `facturas_cxc` (`numero`, `id_cte`, `fecha`, `descripcion`, `valor`) VALUES ('569', '3', '2007-03-12', 'Compras Varias', ' 87.50'); INSERT INTO `facturas_cxc` (`numero`, `id_cte`, `fecha`, `descripcion`, `valor`) VALUES ('570', '5', '2007-03-15', 'Compras Varias', '4587.20'); INSERT INTO `facturas_cxc` (`numero`, `id_cte`, `fecha`, `descripcion`, `valor`) VALUES ('571', '5', '2007-03-16', 'Compras Varias', ' 651.50'); INSERT INTO `facturas_cxc` (`numero`, `id_cte`, `fecha`, `descripcion`, `valor`) VALUES ('572', '3', '2007-03-16', 'Compras Varias', '5451.00'); INSERT INTO `facturas_cxc` (`numero`, `id_cte`, `fecha`, `descripcion`, `valor`) VALUES ('573', '5', '2007-03-17', 'Compras Varias', ' 45.68'); INSERT INTO `facturas_cxc` (`numero`, `id_cte`, `fecha`, `descripcion`, `valor`) VALUES ('574', '6', '2007-03-18', 'Compras Varias', '125.30'); INSERT INTO `facturas_cxc` (`numero`, `id_cte`, `fecha`, `descripcion`, `valor`) VALUES ('575', '6', '2007-03-19', 'Compras Varias', ' 9874.80'); # Creando las vistas principales # # Podemos crear vistas generales con el objetivo de dar formato a ciertos valores. En el ejemplo # las dos primeras vistas, son simplemente selecciones globales y parecer’a que no tienen utilidad. # En el tercer ejemplo, estamos dando formato a la fecha. Las vistas principales son importantes # porque permiten agrupar resultados comunes para todas la dem‡s. # # Las vistas vienen a ser como tablas dentro de la base de datos. Las vistas son ejecutadas, de la # misma manera que una consulta de selecci—n normal. Tamb’en pueden ser filtradas. CREATE VIEW `_clientes` AS ( SELECT * FROM `clientes` ); # Ejemplo Vista _clientes SELECT * FROM `_clientes`; CREATE VIEW `_deudores` AS ( SELECT * FROM `deudores` ); # Ejemplo Vista _deudores SELECT * FROM `_deudores`; CREATE VIEW `_facturas_cxc` AS ( SELECT A.*, B.*, DATE_FORMAT(A.`fecha`, '%d-%m-%Y') AS `fecha_formateada` FROM `facturas_cxc` AS A , `clientes` AS B WHERE A.`id_cte` = B.`id` ); # Ejemplo Vista __facturas_cxc SELECT * FROM `_facturas_cxc`; # El siguiente ejemplo, crea una vista que une la tabla clientes y deudores. Este es otro buen # ejemplo de la funcionabilidad de las vistas para unir varias tablas. NOTA: Puede que la # siguiente consulta, no pueda ser creada como una vista. Al intentar guardarla como tal, produce # un error de sint‡xis. # # Por consiguiente, al parecer, en distintas distribuciones de base de datos, existen diversas # limitantes. La soluci—n vendr’a en agrupar bajo el nombre de la vista una consulta equivalente. # # Ahora, podemos darnos cuenta, que en casos como este, la utilizaci—n de vistas es muy importante, # dado que, en vez de cambiar dentro del codigo fuente, todas las referencias a una consulta, cuando # esta se modifica, podemos cambiar la vista, sin que esto afecte a todos los programas. CREATE VIEW `clientes_y_deudores` AS ( (SELECT `id`, `nombre`, `direccion`, `telefono` FROM `clientes`) UNION (SELECT `id`, `nombre`, `direccion`, `telefono` FROM `deudores`) ); # Creando las funciones basicas # # En SQL, se pueden definir funciones. Lo interesante es ver que el mismo SQL viene con el soporte # para muchas sentencias de seleccion y de bucle, incluyendo el FOREACH, dependiendo de la distribuci—n. # # Es recomendable que la funci—n devuelva c—digos de ejecuci—n. Por ejemplo, cada funci—n puede devolver # un codigo para indicar el resultado. Pueden trabajarse codigos de cualquier clase. # # NOTA: Para este ejemplo, la agregaci—n de funciones debe hacerse desde MySQL Query Browser; no sobre # consola o aplicaciones como phpMyAdmin (parece ser que es otra funci—n). # Funciones para clientes DELIMITER $$ CREATE FUNCTION `crear_cliente` (`nombre` VARCHAR ( 64 ) , `direccion` MEDIUMTEXT , `telefono` VARCHAR ( 24 ) ) RETURNS INT ( 4 ) BEGIN INSERT INTO `clientes` (`nombre`, `direccion`, `telefono`) VALUES (`nombre`, `direccion`, `telefono`); RETURN 7892; END $$ DELIMITER ; # Ejemplo de llamado a la funcion crear_cliente SELECT `crear_cliente`('Julio Paz', 'Huehuetenango', '58974613'); DELIMITER $$ CREATE FUNCTION `editar_cliente`(`id` INT ( 3 ) , `nombre` VARCHAR ( 64 ) , `direccion` MEDIUMTEXT , `telefono` VARCHAR ( 24 ) ) RETURNS INT ( 4 ) BEGIN UPDATE `clientes` SET `nombre` = `nombre`, `direccion` = `direccion`, `telefono` = `telefono` WHERE `id` = `id`; RETURN 4562; END $$ DELIMITER ; # Ejemplo de llamado a la funci—n editar_cliente SELECT `editar_cliente`('1', 'Juan Lopez', 'Ciudad Guatemala', '55522333'); DELIMITER $$ CREATE FUNCTION `eliminar_cliente`(`id` INT ( 3 ) ) RETURNS INT ( 4 ) BEGIN # La funci—n verifica si el cliente, tiene facturas pendientes. DECLARE `X745F` INT ( 1 ); SELECT COUNT ( `numero` ) INTO `X745F` FROM `facturas_cxc` WHERE `id_cte` = `id`; IF `X745F` > 0 THEN RETURN 6541; # La funci—n indica que no se puede eliminar el cliente por que tiene facturas pendientes. END IF; DELETE FROM `clientes` WHERE `id` = `id`; RETURN 8520; END $$ DELIMTER ; # Ejemplo de llamado a la funci—n eliminar_cliente SELECT `eliminar_cliente`('7'); # La definici—n de la base de datos, con sus relaciones, incluyendo las vistas y las funciones, forman la definici—n # de datos (es decir, el primer nivel del modelo L5). Dentro del mismo, no interesa, aœn, el tipo de la conexi—n que # va a emplear el lenguaje, ni si se van a emplear uno, dos o m‡s tecnolog’as de scripting. Tampoco, se define el archivo # de configuraci—n y de consultas, que es tarea conjunta del DBA, con el equipo de desarrollo, al terminar de definir # todas las funciones y vistas que se utilizar‡n. Pero, al final del desarrollo de este nivel, todas las tablas, deben # ser accedidas mediante vistas o procedimientos, nunca directamente. # # Este es solo un extracto del ejemplo completo que estar‡ a disposici—n para su descarga, al final de la publicaci—n de la serie. # Se ha dispuesto as’, para que los desarrolladores interesados, puedan ir viendo, las fortalezas y debilidades de la # metodolog’a, y que puedan ir conociendo sobre lo que se propone, poco a poco, para evitar la confusi—n y sobre todo, para # reforzar cada nivel.