Page 1

Aromas de Bases de Datos y otras fragancias de Programación

Ing. Núñez Marinovich Néstor Manuel


Aromas de Bases de Datos y otras fragancias de Programación INTRODUCCIÓN La historia de la INFORMÁTICA está llena de progresos, en muchos de los casos sorprendentes, que han influido enormemente en el desarrollo de la ciencia, de manera que estos han pasado por etapas en las que los avances tecnológicos se producían a una vertiginosa velocidad en un corto tiempo. El software está presente hoy día en todos los aspectos de la sociedad: tanto los grandes sistemas (telecomunicaciones, automatización industrial, investigación, sector empresarial, bancario, económico, educativo, agrónomo, salud, etc) como los objetos de la vida cotidiana (teléfonos celulares, tarjetas bancarias, juegos, entretenimiento, etc) funcionan gracias a programas informáticos. La informática realiza un trabajo consistente en ayudarnos a reducir las tareas rutinarias, acceder a grandes volúmenes de información y proveerla en forma oportuna y veraz, aumentar la precisión en nuestros trabajos. Las computadoras han marcado un cambio en la forma de pensar, crear, saber, trabajar, investigar, entretenernos, de manera que ha provocado nuestra “dependencia” de ellos. En realidad es difícil imaginarse nuestra sociedad sin computadoras ya que están presentes en todos los campos del saber humano. De hecho, la informática es actualmente la ciencia que más ha predominado en el progreso de las demás disciplinas científicas, teconológicas, artísticas y humanísticas. La informática ha contribuido a generar más información y la información es sinónimo de poder. Solo para mencionar 2 ejemplos acerca del impacto de la informática, tenemos: •

Cuando la nave Apolo 13 se perdió en el espacio, escasos 90 minutos fueron necesarios para que los ordenadores de la NASA dieran con la forma de recuperarlos. Con papel y lápiz, a un científico le hubiera tomado un millón de años la misma hazaña.

Desde 1970, la informática se ha desarrollado con tal vertiginosidad que si la industria automotriz hubiera avanzado al mismo ritmo, ¡hoy en día se podría comprar un Rolls Royce a tres dólares!...

En conclusión diríamos que la Informática es muy importante en nuestro mundo actual, debido a que nos ayuda a mejorar nuestra calidad de vida, a hacer el trabajo más rápido y buena calidad de presentación; nos permite obtener cualquier tipo de información deseada en la red (Internet), comunicarnos con personas de cualquier parte del mundo, nos permite almacenar y procesar grandes cantidades de información, esta presente también en los juegos y entretenimiento, control de dispositivos electrónicos, control de diversas actividades a nivel empresarial e industrial. También está presente en actividades diarias como: medios de comunicación (dispositivos móviles, celulares, chat, videoconferencias), realizar compra y venta por internet (Comercio electrónico), Ver TV y escuchar radio por Internet, etc. Tambien podríamos mencionar áreas de la informática de actual investigación y auge en la actualidad como Visión Computacional, Inteligencia artificial, Sistemas Expertos, Lógica difusa, Biometría, Redes neuronales, Computación cuántica, etc.

Página 2

Autor: Ing. Núñez Marinovich Néstor Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación PRESENTACION La presente obra es un compendio que abarca la implementación de bases de datos (SQL Server, Oracle, MySQL, PostgreSQL), y sus diferentes conexiones desde distintos lenguajes de programación (VB .NET, C# .NET, Java, PHP). En el capítulo 3 se desarrollo un pequeño sistema de pedidos sobre artículos de cómputo en donde se pone en práctica lo realizado en los capítulos 1 y 2. En el capítulo 4 se desarrollaron temas de Business Intelligence SQL Server 2008: Analysis Services, Data Mining, Integration Services, Reporting Services. Finalmente en el capítulo 5, se desarrolló la Implementación y Consumo de una Web Service en .NET. El objetivo es presentar código que ayuden a la enseñanza y desarrollo de bases de datos con ejemplos concretos desde distintos manejadores de base de datos, interactuando desde diferentes lenguajes (.NET, Java, PHP). Me gustaría hacer hincapié en la importancia del desarrollo de base de datos ya que en la actualidad facilitan el almacenamiento, procesamiento y recuperación de la información, ayudan a la toma de decisiones y están presentes en cualquier tipo de industrias, empresas, organizaciones, bancos, etc. Espero que la presente obra sirva de ayuda en los temas propuestos, y cualquier sugerencia o consulta no duden en escribirme al correo electrónico: manhiuco@hotmail.com. Asimismo les invitamos a visitar nuestra página web http://manhiuco.es.tl/

Página 3

Autor: Ing. Núñez Marinovich Néstor Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación

1. Base de Datos 1.1. SQL Server 1.2. Oracle 1.3. MySQL 1.4. PostgreSQL

2. Conexiones a Base de Datos 2.1. ADO .NET 2.1.1. Conexión ADO.NET a SQL Server 2.1.2. Conexión ADO.NET a Oracle 2.1.3. Conexión ADO.NET a MySQL 2.1.4. Conexión ADO.NET a PostgreSQL 2.2. JDBC 2.2.1. Conexión JDBC a MySQL 2.2.2. Conexión JDBC a Oracle 2.2.3. Conexión JDBC a SQL Server 2.2.4. Conexión JDBC a PostgreSQL 2.2.5. Ejemplos de uso de los Objetos Connection,Statement, PreparedStatement, ResultSet , CallableStatement 2.3. PHP 2.3.1. 2.3.2. 2.3.3. 2.3.4.

Conexión de PHP a MySQL Conexión de PHP a SQLServer Conexión de PHP a Oracle Conexión de PHP a PostgreSQL

3. Proyecto CompuTienda 3.1. Script Base de Datos Computienda en SQL Server 3.2. Script Base de Datos Computienda en MySQL 3.3. Mantenimiento con Visual Basic .NET con SQL Server 3.4. Mantenimiento Java con MySQL 3.5. Mantenimiento PHP con MySQL 4. Business Intelligence SQL Server 2008 4.1. Analysis Services 4.2. Data Mining 4.3. Integration Services 4.4. Reporting Services

5. Web Services en .NET

Página 4

Autor: Ing. Núñez Marinovich Néstor Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación

BASE DE DATOS SQL (Lenguaje de consulta estructurado o Structured Query Language) es un lenguaje declarativo de acceso a bases de datos relacionales que permite especificar diversos tipos de operaciones en éstas. Tipos de sentencias SQL Tipo

Descripción

DDL (Data Definicion Language Lenguaje de definición de datos)

Conjunto de sentencias SQL para la creación, eliminación y borrado de la estructura de una Base de datos (Create, Alter, Drop, Truncate)

DML (Data Manipulation Language Lenguaje de Manipulación de datos)

Conjunto de sentencias que trabaja con el contenido de la BD (Select , Insert, Update, Delete)

DCL (Data Control Language – Lenguaje de Control de datos)

Conjunto de sentencias de asignación de permisos (Grant, Deny, Revoke)

TCL (Transactional Control Language – Lenguaje de Control de Transacciones)

Usado para gestionar las distintas transacciones que ocurren dentro de una base de datos. (Commit, Rollback, Save transaction).

Página 5

Autor: Ing. Núñez Marinovich Néstor Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación

Microsoft SQL Server es un gestor de bases de datos producido por Microsoft basado en el modelo relacional. Sus lenguajes para consultas son T-SQL y ANSI SQL. Contenido: ♦ Crear Base de Datos, Tablas ♦ Inserción de Valores en una Tabla ♦ Modificación de Valores en una Tabla ♦ Eliminación de datos en una Base de Datos ♦ Diferencias entre DELETE y TRUNCATE ♦ Recuperación de datos ♦ Vistas ♦ Procedimientos Almacenados ♦ Funciones ♦ Trigger ♦ Cursores ♦ SQL Dinámico ♦ Pivot Table

Página 6

Autor: Ing. Núñez Marinovich Néstor Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación Diagrama DB Persona

Página 7

Autor: Ing. Núñez Marinovich Néstor Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación Crear una Base de Datos y Tablas Descripción

Sentencia SQL

Crear una BD llamada BDPersonas

CREATE DATABASE BDPersonas

Eliminar dicha BD ‘BDPersonas’

DROP DATABASE BDPersonas

Cambiar de nombre a la Base de datos

ALTER DATABASE BDPersonas MODIFY Name = BDAgenda CREATE TABLE Categoria (idCategoria int not null identity primary key, nombreCategoria varchar(50) unique not null)

Crear la tabla Categoria A la tabla Categoria ya existente, agregar el campo descripcion de tipo varchar(50) En la tabla Categoria, al campo descripcion ya existente, modificar el tipo de dato y cambiarlo por varchar(80) Eliminar el campo descripcion de la tabla Categoria Eliminar la tabla Categoria

ALTERTABLE categoria ADD descripcion varchar(50)

ALTER TABLE categoria ALTER COLUMN descripcion varchar(80) ALTER TABLE categoria DROP COLUMN descripcion DROP TABLE categoria

Ejemplo 1: Crear la Tabla Persona CREATE TABLE Persona ( idPersona int not null identity primary key, nombres varchar(50), apellidos varchar(50), direccion varchar(150), telefono varchar(30), celular varchar(20), email varchar(50), fax varchar(20), fechaNacimiento datetime, lugarNacimiento varchar(50), ocupacion varchar(20), sueldo decimal(10,2), esJubilado bitdefault 0 , nroHijos tinyint, sexo char(1) check (sexo in('M','F')), comentarios varchar(50), idCategoria int foreign key references Categoria(idCategoria), ts timestamp )

Ejemplo 2: CREATE TABLE TablaEjemplo ( idMedicamento char(5) not null primary key check (idMedicamento like'[A-Z][A-Z][0-9][0-9][0-9]'), fechaMatricula datetime DEFAULT (convert(char(10),getdate(), 112)), tipoVentaM char (1)check (tipoVentaM IN('K','L')), idTipoMedicamento int DEFAULT 1 references TipoMed(idTM) ) Funciones de conversión de datos CAST: Print CAST(getdate()as varchar (25))+' es la hora y fecha actual' CONVERT: Print 'Fecha actual ' + CONVERT(char (10), orderDate, 112)

Página 8

Autor: Ing. Núñez Marinovich Néstor Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación Inserción de Valores en una Tabla Descripción

Sentencia SQL insert into Categoria values (‘Universidad’)

Insertar en la Tabla Categoria

insert into persona(nombres, apellidos, direccion, telefono, celular, email, fax, fechaNacimiento, lugarNacimiento, ocupacion, sueldo, esJubilado, nroHijos, sexo, comentarios, idCategoria)

Insertar en la Tabla Persona

values ('Pamela','Chu','Av. Incas 250', '253299', '949383634', 'pchu@gmail.com', '', '12/20/1990', 'Columbine', 'Carnicera', '2500', '1',3,'F','',1) insert into persona (nombres, apellidos, direccion, telefono, celular, email, fax, fechaNacimiento, lugarNacimiento, ocupacion, sueldo, esJubilado, nroHijos, sexo, comentarios, idCategoria) Duplicar el contenido de la tabla persona en la misma tabla. Inserción de más de una fila

SELECT nombres, apellidos, direccion, telefono, celular, email, fax, fechaNacimiento, lugarNacimiento, ocupacion, sueldo, esJubilado, nroHijos, sexo, comentarios, idCategoria from persona

Modificación de Valores en una Tabla Descripción

Sentencia SQL

Modificar el nombre de la categoria del idCategoria 1

Update Categoria set nombreCategoria='UNT' where idCategoria=1

Update Persona set fax=''

Actualizar el campo FAX de la tabla Persona a dato en blanco. Aumentar el un 30% al sueldo de todas las personas cuyo lugar de nacimiento sea Inglaterra

Update Persona set sueldo=sueldo*1.3 where lugarNacimiento='Inglaterra'

Eliminación de datos en una Base de Datos Descripción

Sentencia SQL

Eliminar todo el contenido de la tabla Categoria

Delete from Categoria delete Categoria truncate table Categoria

Eliminar el registro de categoria que tenga idCategoria 5

delete Categoria where idCategoria=5

Eliminar las personas que tengan sueldo mayor a un numero X

declare @sueldo as float set @sueldo=500000 delete persona where sueldo>@sueldo

Página 9

Autor: Ing. Núñez Marinovich Néstor Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación Diferencias entre DELETE y TRUNCATE -

-

Ambas eliminan los datos, no la estructura. Solo DELETE permite la eliminación condicional de los registros. DELETE es una operación registrada en el log de transacciones, basada en registrar cada eliminación individual. TRUNCATE es una operación registrada en el log de transacciones, pero como un todo, en conjunto, no por eliminación individual. TRUNCATE se registra como una liberación de las páginas de datos en las cuales existen los datos. TRUNCATE es más rápida que DELETE. Ambas se pueden deshacer con un ROLLBACK. TRUNCATE reiniciará el contador para una tabla que contenga una columna IDENTITY. DELETE mantendrá el contador de la tabla para una columna IDENTITY. TRUNCATE es un comando DDL(lenguaje de definición de datos) mientras que DELETE es un DML(lenguaje de manipulación de datos). TRUNCATE no desencadena un TRIGGER, DELETE sí

Declaración de variables en SQL Server declare @n1 int set @n1=10 print 2*@n1 declare @n2 as int set @n2=5 print power(@n2,2)

Página 10

Autor: Ing. Núñez Marinovich Néstor Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación Tipo de Datos

Binary binary varbinary image Character char varchar text Date time datetime smalldatetime Decimal decimal numeric Floating point float real Integer bigint int smallint tinyint Monetary money smallmoney Special bit cursor timestamp uniqueidentifier SQL_variant table

Unicode nchar nvarchar ntext

Almacena cadenas de bits. El dato consiste de números hexadecimales. Por ejemplo, el número decimal 245 vale en hexadecimal F5. Los datos deben tener la misma longitud fija (hasta 8 KB) Los datos pueden variar en el número de dígitos hexadecimales (hasta 8 KB) Los datos pueden ser de longitud variable y exceder los 8 KB Los datos Character consisten de cualquier combinación de letras, símbolos, y caracteres numéricos. Por ejemplo, datos character válidos:"John928" "(0*&(%B99nh jkJ" Los datos deben tener la misma longitud fija (hasta 8 KB) Los datos pueden variar en el número de caracteres (hasta 8 KB) Los datos pueden ser cadena de caracteres ASCII que excedan los 8 KB Los datos Date time consisten de combinaciones de fechas o horas válidas. No existe tipos de datos separados para fechas y horas para almacenar solo fechas o solo horas Los datos fecha están comprendidos entre en el 1 de Enero de 1753 hasta el 31 de diciembre de 9999 (requiere 8 bytes por dato). Los datos fecha están comprendidos entre en el 1 de Enero de 1900 hasta el 31 de diciembre de 2079 (requiere 4 bytes por dato). Los datos Decimal consisten de datos numéricos que son almacenados al menor dígito significativo Los datos pueden tener un máximo de 30 dígitos, que pueden estar todos a la derecha de la coma decimal. El tipo de dato almacena una representación exacta del número. En SQL Server, el tipo de datos numeric es equivalente al tipo de datos decimal. Datos numéricos aproximados que consisten de datos con una aproximación tanto como el sistema de numeración binaria pueda ofrecer Desde –1.79E + 308 a 1.79E + 308. Desde –3.40E + 38 a 3.40E + 38 Los datos Integer consisten de números enteros positivos y negativos tales como: –15, 0, 5, y 2.509 Desde –2^63 (–9223372036854775808) a 2^63–1 (9223372036854775807). Tamaño 8 bytes Desde –2.147.483.648 a 2.147.483.647 (requiere de 4 bytes por valor) Desde –32,768 a 32.767 (requiere de 2 bytes por valor) Desde cero a 255 (requiere de 1 bytes por valor) Monetary representa montos de dinero positivos o negativos Desde –922.337.203.685.477,5808 a +922.337.203.685.477,5807 Tamaño 8 bytes. Desde –214.748,3648 a 214.748,3647 Tamaño 4 bytes Special se utiliza para datos que caben en ninguna de las categorías anteriores. Consisten en un 1 o un 0. Se usan para representar valores lógicos VERDADERO o FALSO, SI o NO Este tipo de dato es usado para variables o prámetros OUTPUT en procedimientos almacenados que contenga una referencia a un cursor. Cualquier variable creada con el tipo de datos cursor puede tomar valor nulo Este tipo de datos es usado para indicar la secuencia de la actividad del SQL Server sobre una fila y es representado por un número incremental en formato binario. Consiste de números hexadecimales de 16 byte, indicando un identificador único global (GUID). Los GUID son usados cuando una columna deba ser única frente a cualquier otra columna. Este tipo de datos soporta a cualquier otro tipo de datos soportado por SQL Server excepto text, ntext, timestamp, image, y sql_variant. Es utilizado para almacenar un conjunto de resultados para su posterior procesamiento. El tipo de datos Table puede ser usado únicamente para para definir variable locales de tipo table o para retornar valores de una función definida por el usuario. Al usar tipo de datos Unicode, una columna puede almacenar cualquier cualquier caracter definido por el estándar Unicode. Lo cual incluye a todos los caracteres definidos en los distintos conjuntos de caracteres. Los tipos de datos Unicode toman el doble de espacio de almacenamiento que los tipos no-Unicode. Los datos deben tener la misma longitud fija (hasta 4000 caracteres Unicode) Los datos pueden variar en el número de caracteres (hasta 4000 caracteres Unicode) Los datos pueden exceder los 4000 caracteres Unicode.

Página 11

Autor: Ing. Núñez Marinovich Néstor Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación

Recuperación de datos

Contenido:  Diagrama Relacional BD Northwind  Sentencias Básicas  Ordenaciones  Búsquedas  Operador LIKE  Operador between, IN, AND, OR  Funciones MAX, MIN, SUM, AVG, STDEV  Agrupaciones (Group by)  Composición interna  Composición externa  Unión, Intersección  Diferencia  Subconsultas  Sentencias IF  Sentencias Case When  Sentencias While Diagrama BD Northwind Orders

Employees

Customers

EmployeeID

OrderID

LastName

CustomerID

FirstName

EmployeeID

Title

OrderDate

TitleOfCourtesy

RequiredDate

BirthDate

ShippedDate

HireDate

ShipVia

Address

Freight

City

ShipName

Region

ShipAddress

PostalCode

ShipCity

Country

ShipRegion

HomePhone

ShipPostalCode

Extension

ShipCountry

CustomerID CompanyName ContactName ContactTitle Address

CustomerCustomerDemo

City Region PostalCode

CustomerID CustomerTypeID

Country Phone Fax

CustomerDemographics CustomerTypeID

Photo

CustomerDesc

Notes ReportsTo PhotoPath

Categories CategoryID

Shippers

CategoryName

ShipperID

Description

CompanyName

Picture

Phone

EmployeeTerritories EmployeeID TerritoryID

Suppliers Order Details Territories TerritoryID TerritoryDescription RegionID

Region

Products

SupplierID

OrderID

ProductID

CompanyName

ProductID

ProductName

ContactName

UnitPrice

SupplierID

ContactTitle

Quantity

CategoryID

Address

Discount

QuantityPerUnit

City

UnitPrice

Region

UnitsInStock

PostalCode

UnitsOnOrder

Country

ReorderLevel

Phone

Discontinued

Fax HomePage

RegionID RegionDescription

Página 12

Autor: Ing. Núñez Marinovich Néstor Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación Sintaxis: SELECT [ALL | DISTINCT ] <nombre_campo> [{,<nombre_campo>}] FROM <nombre_tabla>|<nombre_vista> [{,<nombre_tabla>|<nombre_vista>}] [WHERE <condicion> [{ AND|OR <condicion>}]] [GROUP BY <nombre_campo> [{,<nombre_campo >}]] [HAVING <condicion>[{ AND|OR <condicion>}]] [ORDER BY <nombre_campo>|<indice_campo> [ASC | DESC] [{,<nombre_campo>|<indice_campo> [ASC | DESC ]}]] Ejemplo1 Descripción Mostrar el usuario logueo

Sentencia SQL SELECT suser_sname()

Mostrar la fecha

SELECT getdate()

Mostrar el nombre de la estación de trabajo.

SELECT host_name()

Mostrar el nombre de aplicación de la sesión actual.

SELECT app_name()

Mostrar las Bases de Datos

SELECT * FROM master.dbo.sysdatabases SELECT NAME FROM master.dbo.sysdatabases

Mostrar las Tablas de una BD

SELECT * FROM INFORMATION_SCHEMA.TABLES

Ejemplo2 Descripción

Sentencia SQL SELECT sin(pi()/2), 2+2*3-6/3,power(5,3),

Realizar cálculos matemáticos

5%3 as Residuo

Mostrar la tabla Empleados

SELECT * from employees

Mostrar nombres y apellidos de la tabla empleados

SELECT firstName, lastName as Empleado from employees SELECT firstName+' '+ lastName as Empleado from employees SELECT firstName+' '+ lastName as Empleado, birthdate,datediff(year, birthdate,getdate())As Edad from employees

Mostrar nombres y apellidos , fecha de nacimiento y edad de los empleados Mostrar las ciudades de los empleados

SELECT

distinct city from employees

Mostrar el total de empleados

SELECT

count(*)from employees

Mostrar el total de ciudades de los empleados

SELECT

count(distinct city)from employees

Mostrar los 3 primeros empleados de la tabla

SELECT SELECT

top 3 * from employees top(3) * from employees

Mostrar los primeros 40% empleados del total

SELECT

top 40 percent * from employees

Página 13

Autor: Ing. Núñez Marinovich Néstor Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación Sentencias SQL - Ordenaciones

Los campos nombrados en la clausula ORDER BY no necesita estar en la lista de SELECT. Cuando se usa ORDER BY, los valores nulos son listados primeros. Descripción Sentencia SQL SELECT * from employees order by lastname Mostrar la tabla empleados ordenados SELECT * from employees order by lastname ASC por apellido Mostrar la tabla empleados ordenados SELECT * from employees order by lastname DESC por apellido descendentemente Mostrar la tabla empleados mostrando SELECT * from employees order by newid() aleatoriamente los registros. SELECT top 1 * from employees Mostrar el mayor en edad de los order by birthdate empleados SELECT top 1 * from employees Mostrar el menor en edad de los order by birthdate DESC empleados

Sentencias SQL – Busquedas Ejemplo1 Descripción Mostrar la dirección, ciudad, región y código postal del empleado ‘King’

Sentencia SQL

Mostrar los empleados cuya fecha de contrato (hiredate) haya sido en el año 1993

SELECT * from employees where year(hiredate)=1993

Mostrar los empleados cuya fecha de contrato (hiredate) sea diferente al año 1993

SELECT * from employees where year(hiredate) <>1993

Mostrar los empleados cuya fecha de nacimiento sea mayor al 22 de Mayo 1960 Mostrar los empleados cuya fecha de nacimiento este entre 22 de Mayo 1955 y 22 de Mayo 1962

SELECT address, city, region, postalCode from employees where lastName='King'

SELECT * from employees where birthdate>'1960/05/22' SELECT * from employees where convert(datetime,birthdate,103)>'05/22/1960' SELECT * from employees where birthdate>'1955/05/22' AND birthdate<'1962/05/22'

Ejemplo2 – Operador LIKE Descripción Mostrar los empleados cuyo apellido comienza con la letra ‘D’ Mostrar los empleados cuyo apellido termina con la letra ‘N’ Mostrar los empleados cuyos nombres tengan como segunda letra la ‘A’ Mostrar los empleados cuyos nombres tengan como tercera letra la ‘N’ Mostrar los empleados cuyo nombre contenga la palabra ‘AN’ Mostrar los empleados cuyos nombres comiencen con la letra A, M o S. Mostrar los empleados cuyos nombres estén entre las letras L y R. Mostrar los empleados cuyos nombres no estén entre las letras L y R.

Página 14

Sentencia SQL SELECT * from employees where lastName like 'D%' SELECT * from employees where lastName like '%N' SELECT * from employees where firstName like '_a%' SELECT * from employees where firstName like '__N%' SELECT * from employees where firstName like '%an%’ SELECT * from employees where firstName like '[A,M,S]%’ SELECT * from employees where firstName like '[L-R]%' SELECT * from employees where firstName not like '[L-R]%' SELECT * from employees where firstName like '[^L-R]%'

Autor: Ing. Núñez Marinovich Néstor Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación Ejemplo3 – Operador Between, IN, AND, OR Descripción Mostrar los productos que cuesten entre 10 y 20 Mostrar los clientes (customers) que sean del país de México o Francia o Canadá

Sentencia SQL SELECT * from products where unitprice between 10 AND 20 SELECT * from products where unitprice>=10 AND unitprice<=20 SELECT * from customers where country IN('Mexico', 'France','Germany')

Mostrar el total de productos

SELECT * from customers where country='Mexico' OR country='France' OR country='Germany' SELECT count(*) from products

Mostrar el máximo, mínimo, suma, promedio y desviación estándar de los precios de los productos

SELECT max(unitPrice) Maximo, min(unitPrice) Minimo, sum(unitPrice) as Suma, avg(unitPrice) as Promedio, stdev(unitPrice) as [Desviacion Estandar] from products

Sentencias SQL – Agrupaciones -

Las funciones de agregados ignoran los valores nulos (excepto count(*)) SUM, AVG, STDEV trabajan con valores numéricos.

Descripción Mostrar el total de clientes agrupados por países Mostrar el total de clientes agrupados por países y ordenados por dicho total Mostrar el país en donde hay menos clientes Mostrar el país en donde hay más clientes Mostrar los países en donde hay más de 10 clientes

Sentencia SQL SELECT country, count(*) as Total from customers group by country SELECT country, count(*) as Total from customers group by country order by Total SELECT top 1 country, count(*) as Total from customers group by country order by Total SELECT top 1 country, count(*) as Total from customers group by country order by Total DESC SELECT country, count(*) as Total from customers group by country having count(*)>10

Sentencias SQL - Juntura interna Descripción Mostrar el nombre de la categoría y el nombre del producto Mostrar el nombre del proveedor y el nombre del producto. Mostrar el nombre del proveedor, el nombre de la categoría y el nombre del producto.

SELECT categoryName, productname from categories inner join products on categories.categoryid=products.categoryid SELECT companyName as Proveedor, productname as Producto from suppliers s inner join products p on s.supplierid=p.supplierid SELECT companyName as Proveedor, categoryName as Categoria, productname as Producto from suppliers s inner join products p on s.supplierid=p.supplierid inner join categories c on c.categoryid=p.categoryid

Mostrar el nombre del cliente, el nombre de laempleado y la fecha de orden.

Página 15

Sentencia SQL

SELECT c.companyname as Cliente, e.lastName +' '+ e.firstname as Empleado, orderdate as Fecha from employees e inner join orders o on e.employeeid=o.employeeid inner join customers c on o.customerid=c.customerid

Autor: Ing. Núñez Marinovich Néstor Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación Sentencias SQL – Composición externa Descripción Mostrar los clientes que aun no han efectuado compra alguna (usar left join) Mostrar los clientes que aun no han efectuado compra alguna (usar right join) Producto Cartesiano

Sentencia SQL SELECT c.companyName, o.customerId from customers c left join orders o on c.customerid=o.customerid where o.customerid is null SELECT c.companyName, o.customerId from orders o right join customers c on c.customerid=o.customerid where o.customerid is null SELECT C.CategoryName, P.ProductName FROM Categories C CROSS JOIN Products P

Sentencias SQL – Unión, Intersección, Diferencia Descripción Mostrar la unión de las regiones de los empleados, clientes y proveedores

Mostrar la intersección de las regiones (regiones en común) de los clientes y proveedores

Sentencia SQL SELECT region from employees union SELECT region from customers union SELECT region from suppliers order by region SELECT region from customers intersect SELECT region from suppliers order by region ----- Este otro no saca NULL SELECT distinct c.region from customers c where exists(SELECT 1 from suppliers s where c.region=s.region)

Mostrar las regiones de los empleados, pero q no sean las regiones de los proveedores.

SELECT region from customers except SELECT region from suppliers order by region ----- Otra forma SELECT distinct c.region from customers c Where not exists(SELECT 1 from suppliers s where c.region=s.region)

Sentencias SQL – Subconsultas Descripción Clientes que no han efectuado compra Obtener el nombre del producto mas vendido Obtener el nombre del cliente más fidelizado

Obtener el empleado que mas ordenes ha realizado

Página 16

Sentencia SQL SELECT customerId, companyName from customers where not customerId in (SELECT customerid from orders) SELECT productname from products where productid= (SELECT top 1 productid from [order details] group by productid order by sum(quantity) desc) SELECT companyName from customers where customerid= (SELECT top 1 customerid from orders group by customerid order by count(customerid) desc) SELECT lastname from employees where employeeid= (SELECT top 1 employeeid from orders group by employeeid order by count(employeeid) desc)

Autor: Ing. Núñez Marinovich Néstor Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación Sentencias SQL – Sentencia IF Descripción

Sentencia SQL

Evaluar un número y mostrar un mensaje solo si es cero.

Determinar si un número es par o impar

Obtener los productos almacenados cuando estos superen las 10 unidades, y el numero de ellos cuando no lo superen.

Declare @n int set @n = 0 if @n = 0 print 'El numero es cero' Declare @n int set @n = 290 if @n % 2 = 0 begin print ‘El número es par' end else begin print 'El número es impar' end if (SELECT count(*) from products) >10 begin SELECT productName from products end else begin SELECT count (*) from products end

Sentencias SQL – Case When Descripción Mostrar los títulos (titleofcourtesy) de los empleados, cambiando los titulos por su correspondiente significado en español. Listar los nombres de los empleados indicando el nombre del mes en que nacieron

Mostrar el nombre de cada cliente con un código que esté constituido por: Tipo1 si customerID comienza con A, Tipo2 si customerID comienza con las lentras entre la B y L, Tipo3: si customerID comienza con M,R,S o T, y tipo4 para el resto de letras.

Página 17

Sentencia SQL SELECT Titulo=case titleofcourtesy when 'Dr.' then 'Doctor' when 'Mr.' then 'Señor' when 'Ms.' then 'Señorita' when 'Mrs.' then 'Señora' Else titleofcourtesy end from employees SELECT lastName + ' ' + firstName + ' nació en ' + case month(birthdate) when 1 then 'Enero' when 2 then 'Febrero' when 3 then 'Marzo' when 4 then 'Abril' when 5 then 'Mayo' when 6 then 'Junio' when 7 then 'Julio' when 8 then 'Agosto' when 9 then 'Setiembre' when 10 then 'Octubre' when 11 then 'Noviembre' when 12 then 'Diciembre' End As Empleados from employees SELECT CompanyName as Cliente, Tipo= case when customerid like 'A%'then 'Tipo 1' when customerid like '[B-L]%'then 'Tipo 2' when customerid like '[M,R,S,T]%'then 'Tipo 3' else 'Tipo 4' End from Customers

Autor: Ing. Núñez Marinovich Néstor Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación Sentencias SQL – While Descripción

Sentencia SQL

Mostrar los códigos de los clientes pero de manera que dicho código se le anteponga una enumeración que sea sucesiva de registro en registro

declare @CustId nchar(5) declare @RowNum int,@Limite int SELECT top 1 @CustId=CustomerID from Northwind.dbo.Customers SELECT @Limite=count(CustomerID) from Northwind.dbo.Customers set @RowNum = 0 WHILE @RowNum < @Limite BEGIN set @RowNum = @RowNum + 1 print cast(@RowNum as char(3)) + ' ' + @CustId SELECT top 1 @CustId=CustomerID from Northwind.dbo.Customers where CustomerId > @CustID END

Uso del Continue y Break

Imprime números del 1 al 100 con sus raíces cuadradas.

Página 18

declare @balance int set @balance=0 WHILE @balance<1000 BEGIN set @balance =@balance +1 print @balance IF @balance < 10 CONTINUE Print @balance IF @balance > 99 BREAK end DECLARE @myvalue float SET @myvalue = 1.00 print'Nro'+space(7)+'SQRT' WHILE @myvalue <= 100 BEGIN Print cast(@myvalue as char(10))+cast(SQRT(@myvalue)as char(10)) --SELECT @myvalue N, SQRT(@myvalue) RAIZ set @myvalue = @myvalue + 1 END GO

Autor: Ing. Núñez Marinovich Néstor Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación Sentencia COMPUTE

Genera totales que aparecen como columnas de resumen adicionales al final del conjunto de resultados. Sintaxis básica: SELECT CAMPOS from TABLA compute FUNCION(CAMPO) El campo que se coloque en la cláusula "compute" debe estar incluida en la lista de campos del “SELECT ”

Ejemplo: SELECT * from products compute sum(unitsinstock) ; Produce la misma salida que las siguientes 2 sentencias SELECT SELECT

* from products ; sum (unitsinstock) from products ;

Ejemplos: • •

SELECT * from products compute sum(unitsinstock),avg(unitsinstock) SELECT productid, orderid,quantity FROM [Order Details] ORDER BY productid, orderid COMPUTE SUM(quantity)

Sentencia COMPUTE BY "Compute by" genera cortes de control y subtotales. Se generan filas de detalle y varios valores de resumen cuando cambian los valores del campo. Con "compute by" se DEBE usar también la cláusula "order by" y los campos que se incluyan luego de "by" deben estar en el "order by". Listando varios campos luego del "by" corta un grupo en subgrupos y aplica la función de agregado en cada nivel de agrupamiento: Ejemplo1: Descripción

Sentencia SQL

Mostrar cada producto y su cantidad en los detalles de orden. Por cada producto generar el total de cantidad

SELECT productName, quantity from products p inner join [Order Details] o on p.productid=o.productid order by productName compute sum (quantity) by productName

Los campos que aparecen luego de la cláusula "compute by" DEBEN ser idénticos a un subconjunto de los campos que aparecen después de "order by" y estar en el mismo orden. Ejemplos 2: Descripción Mostrar cada producto y su cantidad en los detalles de orden. Por cada producto generar el total de cantidad Muestra cada cliente y su OrderId. Por cada Cliente cuenta el número de órdenes.

Página 19

Sentencia SQL SELECT productName, quantity from products p inner join [Order Details] o on p.productid=o.productid order by productName compute sum (quantity) by productName USE NORTHWIND SELECT Customers.CompanyName, Orders.OrderID FROM Customers, Orders WHERE Customers.CustomerID=Orders.CustomerID ORDER BY Customers.CustomerID COMPUTE COUNT(Orders.OrderID) BY Customers.CustomerID

Autor: Ing. Núñez Marinovich Néstor Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación Ejemplo 3:

La primera clausula COMPUTER

USE NORTHWIND BY, agrupa el total por total de SELECT CompanyName, Orders.OrderID OrderID, ProductName, factura (detalle de orden). UnitPrice=ROUND([Order [Order Details].UnitPrice, Details] 2), Quantity, Discount=CONVERT(int nt, Discount * 100), La segunda clausula ExtendedPrice=ROUND( CONVERT(money, COMPUTER BY, agrupa el total Quantity * (1 - Discount) * [Order Details].UnitPrice), Details] 2) por cliente. FROM Products, [Order Details], Details] Customers, Orders WHERE [Order Details].ProductID ProductID = Products.ProductID And [Order Details].OrderID = Orders.OrderID And Orders.CustomerID = Customers.CustomerID Customers ORDER BY Customers.CustomerID, , Orders.OrderID COMPUTE SUM(ROUND(CONVERT(money money, Quantity * (1 - Discount) * [Order Details].UnitPrice), 2)) BY Customers.CustomerID, Orders.OrderID Orders COMPUTE SUM(ROUND(CONVERT(money money, Quantity * (1 - Discount) * [Order Details].UnitPrice), 2)) BY Customers.CustomerID

Resultado:

Página 20

Autor: Ing. In Núñez Marinovich Néstor Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: mail: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación Sentencia ROLLUP-CUBE • CUBE: genera un conjunto de resultados que muestra agregados para todas las combinaciones de valores de las columnas seleccionadas. • ROLLUP: genera un conjunto de resultados que muestra agregados para una jerarquía de valores de las columnas seleccionadas. Grouping es una función de agregado que genera una columna adicional en el resultado con el valor de 1 si la fila se agrega mediante el operador CUBE o ROLLUP ó 0 cuando la fila no es el resultado de CUBE o ROLLUP. Ejemplo 1: Muestra el id del producto y sus cantidades vendidas. Muestra al inicio la suma de todas las cantidades. SELECT productid, cantidad=sum(quantity) from [order details] od group by productid with rollup order by productid

Ejemplo 2: Muestra el id del producto, una columna que determina si es el resultado de una función rollup o cube y sus cantidades vendidas. Muestra al inicio la suma de todas las cantidades. Darse cuenta que en la suma de los totales tiene 1 en el resultado de la función grouping y el resto su resultado es 0. SELECT productid, ver=grouping(od.productid), cantidad=sum(quantity) from [order details] od group by productid with rollup order by productid

Ejemplo3: Muestra el id del producto, una columna que determina si es el resultado de una función rollup o cube y sus cantidades vendidas. Muestra al inicio la suma de todas las cantidades. Darse cuenta que en la suma de los totales mostramos la palabra ‘Total’ caso contrario mostramos su id del producto. SELECT productid, ver = case when grouping(od.productid)=1 then 'Total' else str(productid,10) end, cantidad=sum(quantity) from [order details] od group by productid with rollup order by productid

Página 21

Autor: Ing. Núñez Marinovich Néstor Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación Ejemplo 4: Realizar una consulta asi como se muestra en el gráfico. Columna “Ver” mostrará “Total General” si es el nivel máximo de agrupamiento. En un Segundo nivel, mostrará el nombre de la categoria. En un tercer nivel, mostrará el nombre del producto. Columnas “categoryid” y “productid” mostrará los ids de categoria y producto respectivamente. Columnas “cate” y “prod” mostrarán el resultado de la función grouping de los ids de categoria y product. Columna precio y cantidad, mostrará el precio y la cantidad de los productos en las ventas realizadas (Tabla order details). Si la cantidad y el precio corresponden a una fila en la que se muestre la categoria, deberá mostrar la suma de los productos que le corresponden. Si la fila corresponde al total general, deberá mostrar la suma de todos los productos.

SELECT ver=case when grouping(p.categoryid)=1 and grouping(od.productid)=1 then 'Total General' else case when grouping(p.categoryid)=0 and grouping(od.productid)=1 then space(4) + max(c.categoryname) else space(7) + max(p.productname) end end, p.categoryid,od.productid, cate=grouping(p.categoryid), prod=grouping(od.productid), precio=sum(od.unitprice),cantidad=sum(od.quantity) from [order details] od inner join products p on od.productid=p.productid inner join categories c on c.categoryid=p.categoryid group by p.categoryid,od.productid with rollup order by p.categoryid,od.productid

Página 22

Autor: Ing. Núñez Marinovich Néstor Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación Ejercicio 5: Columna “Descripcion” mostrará “Total” si es el nivel máximo de agrupamiento. En un Segundo nivel, mostrará la fecha de la orden de venta. En un tercer nivel, mostrará el nombre del empleado que atendio dicha ordeny por ultimo en un cuarto nivel, mostrará el nombre del producto. Columna precio y cantidad, mostrará el precio y la cantidad de los productos en las ventas realizadas (Tabla order details). Si la cantidad y el precio corresponden a una fila en la que se muestre el empleado o fecha, deberá mostrar la suma de los productos que le corresponden. Si la fila corresponde al total, deberá mostrar la suma de todos los productos. Columna OrderDate muestra la fecha de la orden. Columnas “employeeid” y “productid” mostrará los ids de empleado y producto respectivamente.

SELECT Descripcion = case grouping(o.OrderDate) + grouping(e.EmployeeId) + grouping(p.ProductId) when 3 then 'TOTAL' when 2 then space(5) + 'Fecha: '+convert(char(12),o.OrderDate,103) when 1 then space(10) + 'Empleado: '+MAX( e.LastName ) when 0 then space (15)+ MAX( p.ProductName) end, Precio = SUM ( d.UnitPrice ), cantidad = sum( d.Quantity ), o.OrderDate, e.EmployeeId, p.ProductId --,MAX( e.LastName ), MAX( p.ProductName) FROM Orders o INNER JOIN [ORDER DETAILS] d ON o.OrderId = d.OrderId INNER JOIN Employees e ON e.EmployeeId = o.EmployeeId INNER JOIN Products p ON p.ProductId = d.ProductId group by o.OrderDate, e.EmployeeId, p.ProductId with rollup order by o.OrderDate, e.EmployeeId, p.ProductId

Página 23

Autor: Ing. Núñez Marinovich Néstor Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación

La siguiente consulta produce un resultado semejante al anterior. La diferencia solo esta en el SELECT . SELECT Descripcion = case when grouping(o.OrderDate) = 1 and grouping(e.EmployeeId) = 1 and grouping(p.ProductId) = 1 then 'TOTAL' else case when grouping(o.OrderDate) = 0 and grouping(e.EmployeeId) = 1 and grouping(p.ProductId) = 1 then space(5) +'Fecha: '+convert(char(10),o.OrderDate,103) else case when grouping(o.OrderDate) = 0 and grouping(e.EmployeeId) = 0 and grouping(p.ProductId) = 1 then space(10) +'Empleado: '+MAX( e.LastName ) else space(15) +MAX( p.ProductName) end end end, Precio = SUM ( d.UnitPrice ), cantidad = sum( d.Quantity ), o.OrderDate, e.EmployeeId, p.ProductId, MAX( e.LastName ), MAX( p.ProductName) FROM Orders o INNER JOIN [ORDER DETAILS] d ON o.OrderId = d.OrderId INNER JOIN Employees e ON e.EmployeeId = o.EmployeeId INNER JOIN Products p ON p.ProductId = d.ProductId group by o.OrderDate, e.EmployeeId, p.ProductId with rollup order by o.OrderDate, e.EmployeeId, p.ProductId

Página 24

Autor: Ing. Núñez Marinovich Néstor Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación Ejercicio 6: Mostrar un reporte que se muetre el total de los totales, el total por cada Fecha, Producto y Empleado. Los totales que debe de mostrar son totales de suma de precios, suma de cantidades de unidades vendidas. SELECT Descripcion = case when grouping(o.OrderDate) = 1 and grouping(e.EmployeeId) = 1 and grouping(p.ProductId) = 1 then 'TOTAL' else case when (grouping(o.OrderDate) = 0 and grouping(e.EmployeeId) = 1 and grouping(p.ProductId) = 1) then ' Fecha: '+convert(char(10),o.OrderDate,103) else case when (grouping(o.OrderDate) = 1 and grouping(e.EmployeeId) = 1 and grouping(p.ProductId) = 0) then ' PRODUCTO: ' + MAX( p.ProductName) else -- Encontrar la venta de todos los productos case when grouping(o.OrderDate) = 1 and grouping(e.EmployeeId) = 0 and grouping(p.ProductId) = 1 then ' Empleados: ' +MAX( e.LastName) end end end end, Precio = SUM ( d.UnitPrice ), cantidad = sum( d.Quantity ), o.OrderDate, e.EmployeeId, p.ProductId, MAX( e.LastName ), MAX( p.ProductName) FROM Orders o INNER JOIN [ORDER DETAILS] d ON o.OrderId = d.OrderId INNER JOIN Employees e ON e.EmployeeId = o.EmployeeId INNER JOIN Products p ON p.ProductId = d.ProductId group by o.OrderDate, e.EmployeeId, p.ProductId with cube HAVING (grouping(o.OrderDate) = 1 and grouping(e.EmployeeId) = 1 and grouping(p.ProductId) = 1) or (grouping(o.OrderDate) = 1 and grouping(e.EmployeeId) = 0 and grouping(p.ProductId) = 1) or -- empleado ( grouping(o.OrderDate) = 1 and grouping(e.EmployeeId) = 1 and grouping(p.ProductId) = 0) or -- producto ( grouping(o.OrderDate) = 0 and grouping(e.EmployeeId) = 1 and grouping(p.ProductId) = 1) -- fecha order by o.OrderDate, e.EmployeeId, p.ProductId

Página 25

Autor: Ing. Núñez Marinovich Néstor Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación Resultado:

Página 26

Autor: Ing. In Núñez Marinovich Néstor Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: mail: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación Ejemplo: Diferencia entre ROLLUP y CUBE CREATE INSERT INSERT INSERT INSERT

TABLE Sales Sales Sales Sales

Sales (EmpId INT, , Yr INT, Sales MONEY) VALUES(1, 2005, 12000) 12000 INSERT Sales VALUES(1, 2006, 18000) 18000 VALUES(1, 2007, 25000) 25000 INSERT Sales VALUES(2, 2005, 15000) 15000 VALUES(2, 2006, 6000) 6000 INSERT Sales VALUES(3, 2006, 20000) 20000 VALUES(3, 2007, 24000) 24000

Ejemplo con ROLLUP --Obtener el totales de e las ventas agrupadas por empleado y año con ROLLUP SELECT EmpId, Yr, SUM(Sales) AS Sales FROM Sales GROUP BY EmpId, Yr WITH ROLLUP

Ejemplo con CUBE --Obtener Obtener el totales de las ventas agrupadas por empleado y año con CUBE SELECT EmpId, Yr, SUM(Sales) SUM AS Sales FROM Sales GROUP BY EmpId, Yr WITH CUBE order by Yr

--Obtener Obtener una tabla de referencia cruzada cuyos años sean las columnas con CUBE select *, AÑO_2005+AÑO_2006+AÑO_2007 as Total from (select isnull(cast(EmpId as CHAR(5)),'Total') CHAR EMP, sum(case when Yr=2005 then Sales else 0 end) AÑO_2005, sum(case when Yr=2006 then Sales else 0 end) AÑO_2006, sum(case when Yr=2007 then Sales else 0 end) AÑO_2007 from (SELECT EmpId, Yr, , SUM(Sales) AS Sales FROM Sales GROUP BY EmpId, Yr WITH CUBE) T1 group by T1.EmpId) T2 order by EMP

Página 27

Autor: Ing. In Núñez Marinovich Néstor Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: mail: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación EJERCICIOS RESUELTOS 1. Mostrar los empleados que no tienen jefes SELECT employeeid,lastName from employees where reportsTo is NULL 2. Mostrar los empleados cuyos jefes no tienen jefes SELECT employeeid,lastName from employees where reportsTo IN (SELECT employeeid from employees where reportsTo is NULL) 3. Mostrar los empleados junto con sus jefes SELECT e1.lastName as Empleado, e2.lastName as Jefe from employees e1 left join employees e2 on e1.reportsTo= e2.employeeid 4. Obtener el número de países en los que hay clientes SELECT count(distinct country)from customers 5. Mediante sub consulta obtener el producto más caro SELECT productName, unitprice from products where unitprice=(SELECT max(unitprice)from products) 6. Obtener el flete cobrado por el envío de productos SELECT sum(freight)as Flete from orders 7. Mostrar el flete cobrado por cada compañía de envío SELECT companyName,sum(freight)as Flete from Shippers s join orders o on (s.shipperid=o.shipvia)group by CompanyName ORDER BY Flete desc 8. Obtener el número de pedidos agrupados por Cliente SELECT companyName as Cliente,count(*)as Total from customers c inner join orders oon c.customerid=o.customerid GROUP BY companyName ORDER BY Total desc 9. Obtener el número de productos agrupados por el proveedor y categoría SELECT CategoryName as Categoria, CompanyName Proveedor,count(*)as Total from Categories c inner join Products p on c.categoryid=p.categoryid inner join Suppliers s on s.supplierid=p.supplierid GROUP BY CategoryName, CompanyName ORDER BY Total desc 10. Obtener el nombre del producto más vendido SELECT top 1 productName,sum(quantity)as Total from products p inner join [order details] od on p.productid=od.productid GROUP BY productName ORDER BY Total desc 11. Obtener el nombre del producto más rentable SELECT top 1 productName,sum(od.quantity*od.unitprice*(1-od.discount))as Total from products p inner join [order details] od on p.productid=od.productid GROUP BY productName ORDER BY Total desc 12. Obtener el nombre completo del empleado que más pedidos atendió SELECT top 1 lastName +' '+firstName as Empleado,count(*)as Total from employees e inner join orders o on e.employeeid=o.employeeid GROUP BY lastName,firstName ORDER BY total desc 13. Obtener el nombre del cliente más fidelizado SELECT top 1 companyName as Cliente,count(*)as Total from customers c inner join orders o on c.customerid=o.customerid GROUP BY companyName ORDER BY Total desc

Página 28

Autor: Ing. Núñez Marinovich Néstor Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación 14. Obtener los 3 productos con stock más bajo SELECT top 3 productName, unitsinstock from products ORDER BY unitsinstock Puede darse el caso, de que el cuarto stock devuelto por la consulta tenga un valor igual al tercero. El uso de TOP 3 discriminaría el cuarto registro. Para evitar este comportamiento, y que la consulta devuelva también al cuarto utilizamos la clausula WITH TIES. SELECT top 3 with ties productName, unitsinstock from products ORDER BY unitsinstock

15. Mostrar las categorías que tengan más de 10 productos SELECT c.categoryName,count(*)as Total from products p inner join categories c on p.categoryid=c.categoryid GROUP BY categoryName havingcount(*)>10 --Otra forma: SELECT c.categoryName from categories c where c.categoryid in (SELECT p.categoryid from products p GROUP BY p.categoryid havingcount(*)>10)

16. Obtener cada proveedor con el producto más caro que vende SELECT companyName, productname, unitPrice as Precio from products p inner join suppliers s on p.supplierid=s.supplierid where unitPrice in(SELECT max(unitprice)from products p2 GROUP BY p2.supplierid having p2.supplierid =p.supplierid ) ORDER BY companyName

17. Obtener una tabla de referencia cruzada del total de ordenes por año y por cada Trimestre SELECT anio, sum(case when trim=1 then 1 else 0 end) Trimestre1, sum(case when trim=2 then 1 else 0 end) Trimestre2, sum(case when trim=3 then 1 else 0 end) Trimestre3, sum(case when trim=4 then 1 else 0 end) Trimestre4 from ( SELECT year(orderdate)as anio,datepart(quarter,orderdate) as trim, orderid from orders) T group by anio

18. Obtener una tabla de referencia cruzada del total del flete cobrado por año y trimestre SELECT *, Trimestre1+Trimestre2+Trimestre3+Trimestre4 as Total from(SELECT anio, sum(case when trim=1 then monto else 0 end) Trimestre1, sum(case when trim=2 then monto else 0 end) Trimestre2, sum(case when trim=3 then monto else 0 end) Trimestre3, sum(case when trim=4 then monto else 0 end) Trimestre4 from (SELECT year(orderdate)as Anio,datepart(quarter,orderdate)as trim, freight as monto from orders) TB group by anio)as T;

Página 29

Autor: Ing. Núñez Marinovich Néstor Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación 19. Obtener btener una tabla de referencia cruzada del total de las ventas por año y trimestre SELECT *, Trimestre1+Trimestre2 Trimestre2+Trimestre3+Trimestre4 as Total from(SELECT anio as Año, sum(case when trim=1 then monto else 0 end) Trimestre1, sum(case when trim=2 then monto else 0 end) Trimestre2, sum(case when trim=3 then monto else 0 end) Trimestre3, sum(case when trim=4 then monto else 0 end) Trimestre4 from( SELECT year(o.orderdate orderdate)as anio, datepart(quarter,o. .orderdate)as trim, sum(od.quantity*od. .unitprice*(1-od.discount)) monto from orders as o join [order details] as od on o.orderid = od.orderid orderid group by o.orderdate orderdate )tempo group by anio)as t;

20. Mostrar las unidades vendidas de cada producto por cada mes select P.ProductName as Producto, Producto sum(CASE WHEN month(O.OrderDate OrderDate) sum(CASE WHEN month(O.OrderDate OrderDate) sum(CASE WHEN month(O.OrderDate OrderDate) sum(CASE WHEN month(O.OrderDate OrderDate) sum(CASE WHEN month(O.OrderDate OrderDate) sum(CASE WHEN month(O.OrderDate OrderDate) sum(CASE WHEN month(O.OrderDate erDate) sum(CASE WHEN month(O.OrderDate OrderDate) sum(CASE WHEN month(O.OrderDate OrderDate) sum(CASE WHEN month(O.OrderDate OrderDate) sum(CASE WHEN month(O.OrderDate OrderDate) sum(CASE WHEN month(O.OrderDate OrderDate) from [Order Details] D inner join inner join group by P.ProductName order by 1

Página 30

= 1 THEN D.Quantity ELSE 0 END) AS Enero, = 2 THEN D.Quantity ELSE 0 END) AS Febrero, = 3 THEN D.Quantity ELSE 0 END) AS Marzo, = 4 THEN D.Quantity ELSE 0 END) AS Abril, = 5 THEN D.Quantity ELSE 0 END) AS Mayo, = 6 THEN D.Quantity ELSE 0 END) AS Junio, = 7 THEN D.Quantity ELSE 0 END) AS Julio, = 8 THEN D.Quantity ELSE 0 END) AS Agosto, = 9 THEN D.Quantity ELSE 0 END) AS Septiembre, = 10 THEN D.Quantity ELSE 0 END) ) AS Octubre, = 11 THEN D.Quantity ELSE 0 END) ) AS Noviembre, = 12 THEN D.Quantity ELSE 0 END) ) AS Diciembre Orders O on D.OrderID = O.OrderID rID Products P on D.ProductID = P.ProductID ProductID

Autor: Ing. In Núñez Marinovich Néstor Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: mail: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación 21. Mostrar las unidades vendidas de cada año por cada mes select year(O.OrderDate) as Año, sum(CASE WHEN month(O.OrderDate) sum(CASE WHEN month(O.OrderDate) sum(CASE WHEN month(O.OrderDate) sum(CASE WHEN month(O.OrderDate) sum(CASE WHEN month(O.OrderDate) sum(CASE WHEN month(O.OrderDate) sum(CASE WHEN month(O.OrderDate) sum(CASE WHEN month(O.OrderDate) sum(CASE WHEN month(O.OrderDate) sum(CASE WHEN month(O.OrderDate) sum(CASE WHEN month(O.OrderDate) sum(CASE WHEN month(O.OrderDate) from [Order Details] D inner join group by year(O.OrderDate) order

= 1 THEN D.Quantity ELSE 0 END) AS Enero, = 2 THEN D.Quantity ELSE 0 END) AS Febrero, = 3 THEN D.Quantity ELSE 0 END) AS Marzo, = 4 THEN D.Quantity ELSE 0 END) AS Abril, = 5 THEN D.Quantity ELSE 0 END) AS Mayo, = 6 THEN D.Quantity ELSE 0 END) AS Junio, = 7 THEN D.Quantity ELSE 0 END) AS Julio, = 8 THEN D.Quantity ELSE 0 END) AS Agosto, = 9 THEN D.Quantity ELSE 0 END) AS Septiembre, = 10 THEN D.Quantity ELSE 0 END) AS Octubre, = 11 THEN D.Quantity ELSE 0 END) AS Noviembre, = 12 THEN D.Quantity ELSE 0 END) AS Diciembre Orders O on D.OrderID = O.OrderID by 1

Funciones del sistema Devuelve el número de filas afectadas por la última instrucción. Si el número de @@ROWCOUNT filas es mayor de 2 mil millones, use ROWCOUNT_BIG. @@IDENTITY Devuelve el último valor de identidad insertado @@ERROR Devuelve el número de error de la última instrucción Transact-SQL ejecutada. Devuelve el número de instrucciones BEGIN TRANSACTION que se han producido en la conexión actual. La instrucción BEGIN TRANSACTION incrementa @@TRANCOUNT en 1. ROLLBACK @@TRANCOUNT

TRANSACTION disminuye @ @ TRANCOUNT en 0, salvo para ROLLBACK TRANSACTION savepoint_name, que no afecta a @ @ TRANCOUNT. Cada instrucción COMMIT TRANSACTION o COMMIT WORK disminuye @@TRANCOUNT en uno.

Página 31

Autor: Ing. Núñez Marinovich Néstor Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación Vistas (View) Una vista es como una tabla virtual que almacena una consulta. Los datos accesibles a través de la vista no están almacenados en la base de datos como un objeto. Las vistas permiten: - Ocultar información: permitiendo el acceso a algunos datos y manteniendo oculto el resto de la información que no se incluye en la vista. El usuario opera con los datos de una vista como si se tratara de una tabla, pudiendo modificar tales datos. - Simplificar la administración de los permisos de usuario: se pueden dar al usuario permisos para que solamente pueda acceder a los datos a través de vistas, en lugar de concederle permisos para acceder a ciertos campos, así se protegen las tablas base de cambios en su estructura. - Mejorar el rendimiento: se puede evitar tipear instrucciones repetidamente almacenando en una vista el resultado de una consulta compleja que incluya información de varias tablas. Podemos crear vistas con: un subconjunto de registros y campos de una tabla; una unión de varias tablas; una combinación de varias tablas; un resumen estadístico de una tabla; un subconjunto de otra vista, combinación de vistas y tablas. Una vista se define usando un "SELECT". Descripción

Crear una Vista que muestre el proveedor categoría de los productos, además de su precio y stock

Vista Create view Producto_Categoria_Proveedor as SELECT dbo.Suppliers.CompanyName as Proveedor, dbo.Categories.CategoryName as Categoria, dbo.Products.ProductName as Producto, dbo.Products.UnitPrice as Precio, dbo.Products.UnitsInStock as Stock FROM dbo.Categories INNER JOIN dbo.Products ON dbo.Categories.CategoryID = dbo.Products.CategoryID INNER JOIN dbo.Suppliers ON dbo.Products.SupplierID = dbo.Suppliers.SupplierID --Ver los datos de la vista: SELECT * from Producto_Categoria_Proveedor

Mostrar los objetos que dependen y depende la vista. Eliminar la vista.

sp_depends Producto_Categoria_Proveedor drop view Producto_Categoria_Proveedor

Mostrar el texto que define la vista

sp_helptext Producto_Categoria_Proveedor

“with encryption” codifica las sentencias que definen la vista.

Alter view Producto_Categoria_Proveedor withencryption as . . .

Página 32

Autor: Ing. Núñez Marinovich Néstor Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación Stored Procedures (Procedimientos almacenados) Un procedimiento almacenado es una colección guardada de instrucciones de Transact-SQL o una referencia a un método de Common Language Runtime (CLR) de Microsoft .NET Framework que puede aceptar y devolver los parámetros proporcionados por el usuario. Sintaxis: Create Procedure nombreProcedimiento @parametro tipoDato [=predeterminado][OUTPUT] WITH RECOMPILE ENCRYPTION RECOMPILE, ENCRYPTION AS instruccionesSQL

Para ejecutar el SP: EXECUTE nombreSP ó EXEC nombreSP

RECOMPILE: El procedimiento se vuelve a compilar cada vez que se ejecuta. ENCRYPTION: Codifica la instrucción SQL que contiene el SP . SP – Insertar, modificar, eliminar Categoría Descripción

Procedimiento Almacenado

Ejecución del SP

SP para mostrar las Categorías

CREATE PROCEDURE mostrarCategoria AS SELECT nombreCategoria from Categoria CREATE PROCEDURE insertarCategoria @nombreCategoria varchar(50) AS If Not exists(SELECT idCategoria from Categoria where nombreCategoria=@nombreCategoria) INSERT INTO Categoria values (@nombreCategoria) ALTER PROCEDURE modificarCategoria @nombreCategoria varchar(50),@idCategoria int As Update Categoria set nombreCategoria=@nombreCategoria where idCategoria=@idCategoria GO CREATE PROCEDURE eliminarCategoria @idCategoria int as delete from Categoria where idCategoria=@idCategoria

EXEC mostrarCategoria

Procedimiento almacenado para insertar una Categoría

Procedimiento almacenado para modificar una Categoría. Se usa ALTER PROCEDURE para actualizar el SP si es que existe. Procedimiento almacenado para eliminar una Categoría

Página 33

Autor: Ing. Núñez Marinovich Néstor Manuel Ingeniero Informático

EXEC insertarCategoria 'UNT' SELECT * from categoria

EXEC modificarCategoria 'B', 3 SELECT * from categoria

EXEC eliminarCategoria 3 SELECT * from categoria

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación SP – Insertar Personas CREATE PROCEDURE insertarPersona @nombres as varchar(50), @apellidos as varchar(50), @direccion as varchar(150), @telefono as varchar(30), @celular as varchar(20), @email as varchar(50), @fax as varchar(20), @fechaNacimiento as datetime, @lugarNacimiento as varchar(50), @ocupacion as varchar(20), @sueldo as decimal(10,2), @esJubilado as bit=0 , @nroHijos as tinyint, @sexo as char(1), @comentarios as varchar(50), @nombreCategoria as varchar(50) AS declare @idCategoria int -- insertamos en la Tabla Categoria exec insertarCategoria@nombreCategoria -- Devolvemos en el idCategoria SELECT @idCategoria=idCategoria from categoria where nombreCategoria=@nombreCategoria --Insertamos en la Tabla Persona INSERT INTO persona(nombres, apellidos, direccion, telefono, celular, email, fax, fechaNacimiento, lugarNacimiento, ocupacion, sueldo, esJubilado, nroHijos, sexo, comentarios, idCategoria) values(@nombres,@apellidos, @direccion, @telefono, @celular, @email, @fax, @fechaNacimiento, @lugarNacimiento, @ocupacion, @sueldo, @esJubilado, @nroHijos, @sexo, @comentarios, @idCategoria) go

Ejecutar SP insertarPersona: Exec insertarPersona'Pamela','Chu','Av. Incas 250','253299','995566778','pchu@gmail.com', '','12/20/1990','Columbine','Carnicera','2500','1',3,'F','','B' SELECT *from persona

SP-Ejemplos Descripción SP que muestra las ordenes entre 2 fechas ingresadas.

SP con parámetros de salida (output)

SP que devuelve la raíz enésima, ingresando una base y el índice radical.

Página 34

Procedimiento Almacenado

Ejecución del SP

CREATE PROCEDURE OrdersByDate @StartDate datetime, @EndDate datetime AS SELECT * FROM Orders WHERE OrderDate BETWEEN @StartDate AND @EndDate CREATE PROCEDURE CountOrdersByDate @StartDate datetime, @EndDate datetime, @CountOrders intOUTPUT AS SELECT @CountOrders =COUNT(OrderID)FROM Orders WHERE OrderDate BETWEEN @StartDate AND @EndDate

DECLARE @date1 datetime DECLARE @date2 datetime SET @date1=’1/1/1997’ SET @date2=’3/31/1997’ EXECUTE OrdersByDate @date1, @date2

ALTER PROCEDURE raizN @base real, @indiceRadical real as declare @resultado real set @resultado =power(@base,(1/@indiceRadical)) return (@resultado)

DECLARE @date1 datetime DECLARE @date2 datetime SET @date1='1/1/1997' SET @date2='3/31/1997' DECLARE @orderCount int EXECUTE CountOrdersByDate@date1, @date2, @orderCount OUTPUT PRINT'Existen '+CONVERT(varchar(5), @orderCount)+' ordenes.' declare @a real, @b real, @c real set @a=1000;set @b=3 exec @c= raizN@a,@b print @c

Autor: Ing. Núñez Marinovich Néstor Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación EJERCICIOS 1. Stored procedure con transacciones. Modifica el precio de 2 productos de la tabla products. ALTER PROCEDURE usp_ModificarPrecio2Productos @precio1 money, @precio2 money AS --transacción que modifica el precio de dos productos de la base de datos. DECLARE @Error int --Declaramos una variable que utilizaremos para almacenar un posible código de error BEGIN TRAN --Iniciamos la transacción UPDATE Products SET UnitPrice=@precio1 WHERE ProductName ='Chai' --Ejecutamos la primera sentencia SET @Error=@@ERROR --Si ocurre un error almacenamos su código en @Error --y saltamos al trozo de código que deshara la transacción. Si, eso de ahí es un --GOTO, el demonio de los programadores, pero no pasa nada por usarlo --cuando es necesario IF (@Error<>0)GOTO TratarError --Si la primera sentencia se ejecuta con éxito, pasamos a la segunda UPDATE Products SET UnitPrice=@precio2 WHERE ProductName='Chang' SET @Error=@@ERROR --Y si hay un error hacemos como antes IF (@Error<>0)GOTO TratarError --Si llegamos hasta aquí es que los dos UPDATE se han completado con --éxito y podemos "guardar" la transacción en la base de datos COMMIT TRAN TratarError: --Si ha ocurrido algún error llegamos hasta aquí If @@Error<>0 BEGIN PRINT'Ha ecorrido un error. Abortamos la transacción' --Se lo comunicamos al usuario y deshacemos la transacción --todo volverá a estar como si nada hubiera ocurrido ROLLBACK TRAN END --Probar el procedimiento --exec usp_ModificarPrecio2Productos19,20 --SELECT *from Products

2. Stored procedure con transacciones anidadas. CREATE PROCEDURE ups_TransaccionesAnidadas1 AS IF EXISTS(SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE='BASE TABLE' and TABLE_CATALOG='Northwind' AND TABLE_NAME='Test') DROP TABLE TEST CREATE TABLE Test(Columna int) BEGIN TRAN TranExterna -- @@TRANCOUNT ahora es 1 SELECT 'El nivel de anidamiento es',@@TRANCOUNT INSERT INTO Test VALUES (1) BEGIN TRAN TranInterna1 -- @@TRANCOUNT ahora es 2.

Página 35

Autor: Ing. Núñez Marinovich Néstor Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación SELECT 'El nivel de anidamiento es',@@TRANCOUNT INSERT INTO Test VALUES (2) BEGIN TRAN TranInterna2 -- @@TRANCOUNT ahora es 3. SELECT 'El nivel de anidamiento es',@@TRANCOUNT INSERT INTO Test VALUES (3) COMMIT TRAN TranInterna2 -- Reduce @@TRANCOUNT a 2. -- Pero no se guarda nada en la base de datos. SELECT 'El nivel de anidamiento es',@@TRANCOUNT COMMIT TRAN TranInterna1 -- Reduce @@TRANCOUNT a 1. -- Pero no se guarda nada en la base de datos. SELECT 'El nivel de anidamiento es',@@TRANCOUNT COMMIT TRAN TranExterna -- Reduce @@TRANCOUNT a 0. -- Se lleva a cabo la transacción externa y todo lo que conlleva. SELECT 'El nivel de anidamiento es',@@TRANCOUNT SELECT * FROM Test 3. Uso de Save Transaction (Save Tran crea un punto de almacenamiento dentro de una transacción) CREATE PROCEDURE ups_EjemploSaveTran AS IF EXISTS(SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE='BASE TABLE' and TABLE_CATALOG='Northwind' AND TABLE_NAME='Test') DROP TABLE TEST CREATE TABLE Test(Columna int) BEGIN TRAN TranExterna -- @@TRANCOUNT ahora es 1 SELECT 'El nivel de anidamiento es',@@TRANCOUNT INSERT INTO Test VALUES (1) BEGIN TRAN TranInterna1 -- @@TRANCOUNT ahora es 2. SELECT 'El nivel de anidamiento es',@@TRANCOUNT INSERT INTO Test VALUES (2) SAVE TRAN Guadada BEGIN TRAN TranInterna2 -- @@TRANCOUNT ahora es 3. SELECT 'El nivel de anidamiento es',@@TRANCOUNT INSERT INTO Test VALUES (3) ROLLBACK TRAN Guadada -- se deshace lo hecho el punto guardado. SELECT 'El nivel de anidamiento es',@@TRANCOUNT --Ahora podemos decidir si la transacción se lleva a cabo --o se deshace completamente --Para deshacerla un ROLLBACK bastará como hemos visto --Pero para guardar la transacción hace falta reducir @@TRANCOUNT a 0 COMMIT TRAN TranInterna1 -- Reduce @@TRANCOUNT a 2. SELECT 'El nivel de anidamiento es',@@TRANCOUNT COMMIT TRAN TranInterna1 -- Reduce @@TRANCOUNT a 1. -- Pero no se guarda nada en la base de datos. SELECT 'El nivel de anidamiento es',@@TRANCOUNT COMMIT TRAN TranExterna -- Reduce @@TRANCOUNT a 0. -- Se lleva a cabo la transacción externa y todo lo que conlleva. SELECT 'El nivel de anidamiento es',@@TRANCOUNT SELECT *FROM Test

Página 36

Autor: Ing. Núñez Marinovich Néstor Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación 4. Stored Procedure para insertar un producto con su respectiva categoría. Uso de Try catch y controlados por una transacción.

CREATE PROCEDURE ups_insertarProducto( @ProductName VARCHAR(40), @SupplierId int, @CategoryName VARCHAR(40), @QuantityPerUnit VARCHAR(20), @UnitPrice money, @UnitsInStock smallint, @UnitsOnOrder smallint, @ReorderLevel smallint, @Discontinued bit ) AS declare @idCategoria int declare @ErrMsg varchar(1000),@ErrSeverity int begin try BEGIN TRAN saction --Insertamos la categoria si no existe If Not exists(SELECT CategoryName from Categories where CategoryName=@CategoryName) INSERT INTO Categories(CategoryName) VALUES(@CategoryName); -- 1.2 Devolvemos en el id SELECT @idCategoria=categoryID from Categories where CategoryName=@CategoryName /*2. Insertamos en la tabla Producto*/ INSERT INTO Products(ProductName,SupplierID, CategoryID, QuantityPerUnit,UnitPrice,UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued) VALUES(@ProductName,@SupplierID, @idCategoria, @QuantityPerUnit,@UnitPrice,@UnitsInStock, @UnitsOnOrder, @ReorderLevel, @Discontinued) commit transaction End Try begin catch rollback transaction SELECT @ErrMsg =ERROR_MESSAGE(), @ErrSeverity =ERROR_SEVERITY(); PRINT'Error:'+ERROR_MESSAGE() raiserror(@ErrMsg,@ErrSeverity,1) end catch

Probar SP: exec ups_insertarProducto'P1', 1,'CAT1','1Litro x botella',50,100,60, 15, 0; SELECT * from Products

Functions

I. Funciones Escalares: Devuelven un tipo de los datos (int, money, varchar, real, etc.) Pueden ser utilizadas en cualquier lugar incluso incorporado dentro de sentencias SQL. CREATE FUNCTION [owner_name.] function_name ( [{ @parameter_name scalar_parameter_type [ = default]} [,..n]]) RETURNS scalar_return_type [WITH <function_option>>::={SCHEMABINDING | ENCRYPTION] [AS] BEGIN function_body RETURN scalar_expression END

Página 37

Autor: Ing. Núñez Marinovich Néstor Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación Ejemplos Descripción

Crear una función que devuelva la potencia y raíz enésima dado una base y un exponente

Crear una función recursiva que devuelva el factorial de un número.

Funciones Escalares CREATE FUNCTION potencia(@base float, @exponente float) RETURNS float AS BEGIN RETURN(power(@base,@exponente)) END Create FUNCTION raiz(@base float, @indiceRadical float) RETURNS float AS BEGIN RETURN power(@base,(1/@indiceRadical)) END --Prueba SELECT dbo.potencia(2,3), dbo.potencia(2.3,3.5), dbo.raiz(8,3) CREATE FUNCTION dbo.factorial(@n int) Returns int as begin declare @res int if @n<=1 set @res=1 else set @res=dbo.factorial(@n-1)*@n return @res end --Prueba SELECT dbo.factorial(5)

II. Funciones de tabla en línea: Devuelven la salida de una simple declaración SELECT. La salida se

puede utilizar adentro de joins o querys como si fuera un tabla de estándar. CREATE FUNCTION [owner_name.] function_name ( [{ @parameter_name scalar_parameter_type [ = default]} [,..n]]) RETURNS TABLE [WITH <function_option>::={SCHEMABINDING | ENCRYPTION}] RETURN [(] SELECT _statement [)]

Descripción Crear una función que devuelva los productos de un determinado CategoryID

Página 38

Funciones Tabla en Linea CREATE FUNCTION dbo.Productos_Categoria(@idCategoria char(2)) RETURNS TABLE AS RETURN (SELECT * FROM products WHERE categoryID= @idCategoria) --Prueba SELECT * FROM dbo.Productos_Categoria(2)

Autor: Ing. Núñez Marinovich Néstor Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación III. Funciones de tabla de multi sentencias Son similares a los procedimientos almacenados excepto que devuelven un tabla. Este tipo de función se usa en situaciones donde se requiere más lógica y proseso. CREATE FUNCTION [owner_name.] function_name ( [{ @parameter_name scalar_parameter_type [ = default]} [,..n]]) RETURNS TABLE [WITH <function_option>>::={SCHEMABINDING | ENCRYPTION] [AS] BEGIN function_body RETURN END Ejemplo1: CREATE FUNCTION dbo.multi_test(@FirstLetter char(1)) RETURNS @Result TABLE ( fname varchar(20), hire_date datetime, on_probation char(1) ) AS BEGIN INSERT INTO @Result (fname, hire_date) SELECT firstName, hireDate FROM employees WHERELEFT(firstName, 1)= @FirstLetter UPDATE @Result SET on_probation ='N' UPDATE @Result SET on_probation ='Y' WHERE hire_date <'01/01/1991' RETURN END --Pruebas: SELECT *FROM dbo.multi_test('A') SELECT e.LastName, f.fname FROM employees e INNER JOIN

dbo.multi_test('A') f ON e.firstname = f.fname

Ejemplo2: CREATE FUNCTION dbo.customersbycountry( @Country varchar(15)) RETURNS @CustomersbyCountryTab table ( [CustomerID] [nchar](5), [CompanyName] [nvarchar](40), [ContactName] [nvarchar](30), [ContactTitle] [nvarchar](30), [Address] [nvarchar](60), [City] [nvarchar](15), [PostalCode] [nvarchar](10), [Country] [nvarchar](15), [Phone] [nvarchar](24), [Fax] [nvarchar](24) ) AS BEGIN INSERT INTO @CustomersByCountryTab SELECT [CustomerID],

Página 39

Autor: Ing. Núñez Marinovich Néstor Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación [CompanyName], [ContactName], [ContactTitle], [Address], [City], [PostalCode], [Country], [Phone], [Fax] FROM [Northwind].[dbo].[Customers] WHERE country = @Country DECLARE @cnt INT SELECT @cnt =COUNT(*)FROM @customersbyCountryTab IF @cnt = 0 INSERT INTO @CustomersByCountryTab( [CustomerID], [CompanyName], [ContactName], [ContactTitle], [Address], [City], [PostalCode], [Country], [Phone], [Fax] ) VALUES ('','No Companies Found','','','','','','','','') RETURN END GO --Pruebas SELECT *FROM dbo.customersbycountry('USA') SELECT *FROM dbo.customersbycountry('CANADA') SELECT *FROM dbo.customersbycountry('ADF')

Ejemplo3: Analizar una lista delimitada y convertirlo en un conjunto de filas. Delimitador por defecto es una coma CREATE FUNCTION dbo.parse_comma_delimited_integer( @list VARCHAR(8000), @delimiter VARCHAR(10)=',') -- table variable that will contain values RETURNS @tablevalues TABLE ( item INT) AS BEGIN DECLARE @item VARCHAR(255) /* Loop over the commadelimited list */ WHILE (DATALENGTH(@list)> 0) BEGIN IF CHARINDEX(@delimiter,@list)> 0 BEGIN SELECT @item = SUBSTRING(@list,1,(CHARINDEX(@delimiter, @list)-1)) SELECT @list = SUBSTRING(@list,(CHARINDEX(@delimiter, @list)+ DATALENGTH(@delimiter)),DATALENGTH(@list)) END

Página 40

Autor: Ing. Núñez Marinovich Néstor Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación ELSE BEGIN SELECT SELECT END

@item = @list @list =NULL

-- Insert each item into temp table INSERT @tablevalues( item) SELECT item =CONVERT(INT, @item) END RETURN END --Prueba: SELECT

* FROM dbo.parse_comma_delimited_integer('3, 9, 24, 36, 24, 22, 345',',')

Ejemplo4: Muestra los clientes que hayan pasado un número determinado de ventas en un año determinado CREATE FUNCTION dbo.udf_top_customers_and_reps( @year INT, @amount INT) RETURNS @temp TABLE( ProductName VARCHAR(200), CategoryName VARCHAR(200), CustomerID CHAR(5), CompanyName VARCHAR(200), TotalSales INT, EmployeeNames VARCHAR(2000)) AS BEGIN /* Rellena la tabla temp con la tabla customer que han comprado algun producto con ventas totales superiores a la cantidad especificada, en el año dado */ INSERT @temp( ProductName , CategoryName , CompanyName , CustomerID , TotalSales ) SELECT ProductName, CategoryName, CompanyName, b.CustomerID, SUM(a.UnitPrice * quantity)AS total_sales FROM [order details] a INNER JOIN orders b ON a.orderid = b.orderid INNER JOIN products c ON c.productid = a.productid INNER JOIN customers d ON d.customerid = b.customerid INNER JOIN categories e ON e.CategoryID = c.CategoryID WHERE DATEPART(YEAR, OrderDate)= @year

Página 41

Autor: Ing. Núñez Marinovich Néstor Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación GROUP BY c.ProductName, e.CategoryName, b.CustomerID, d.CompanyName,DATEPART(YEAR, OrderDate) HAVING SUM(a.UnitPrice * quantity)> @amount ORDER BY ProductName /* Ahora obtenemos todos los empleados con sus clientes que han participado en un año dado y retorna una lista separada por comas. */ DECLARE @CustomerID CHAR(5), @EmployeeName VARCHAR(200) DECLARE @Employees TABLE ( EmployeeName VARCHAR(80)) DECLARE CustomerCursor CURSOR FOR SELECT CustomerID FROM @temp a OPEN CustomerCursor FETCH NEXT FROM CustomerCursor INTO @CustomerID WHILE @@FETCH_STATUS= 0 BEGIN INSERT @employees SELECT DISTINCT FirstName +' '+ LastName FROM Employees a INNER JOIN Orders b ON a.EmployeeID = b.EmployeeID AND DATEPART(YEAR,OrderDate)= @year WHERE b.CustomerID = @CustomerID /* crea la lista de empleados con el delimitador coma */ SELECT @EmployeeName ='' SELECT @EmployeeName = @EmployeeName +', '+ EmployeeName FROM @Employees SELECT

@EmployeeName =SUBSTRING(@EmployeeName, 3,LEN(@EmployeeName)-2)

UPDATE @temp SET EmployeeNames = @EmployeeName WHERE CustomerID = @CustomerID DELETE @Employees FETCH NEXT FROM CustomerCursor INTO @CustomerID END CLOSE CustomerCursor DEALLOCATE CustomerCursor RETURN END --Prueba SELECT *FROM dbo.udf_top_customers_and_reps(1997, 10000)

Página 42

Autor: Ing. Núñez Marinovich Néstor Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación

Columnas computadas: Las funciones escalares se pueden utilizar para crear columnas calculadas en una definicion de tabla. Los argumentos de las funciones calculadas, columnas de tabla, constantes, o funciones incorporadas. Este ejemplo muestra una tabla que utilice una función del volumen para calcular el volumen de un envase. CREATE FUNCTION dbo.Volume( @dHeight decimal(5,2), @dLength decimal(5,2), @dWidth decimal(5,2)) RETURNS decimal (15,4) AS BEGIN RETURN (@dHeight * @dLength * @dWidth ) END CREATE TABLE dbo.Container ( ContainerID int NOT NULL PRIMARY KEY, MaterialID int NOT NULL REFERENCES Material(MaterialID), ManufacturerID int NOT NULL REFERENCES Manufacturer(ManufacturerID), Height decimal(5,2)NOT NULL, Length decimal(5,2)NOT NULL, Width decimal(5,2)NOT NULL, Volume AS ( dbo.Volume( Height,Length, Width ) ) )

Triggers ( trigger - disparador - desencadenador )

Es una clase especial de procedimiento almacenado que se ejecuta automáticamente cuando se produce un evento en el servidor de bases de datos. SQL Server proporciona los siguientes tipos de triggers Se ejecutan cuando un usuario intenta modificar datos mediante un evento de lenguaje de Trigger DML manipulación de datos (DML). Los eventos DML son instrucciones INSERT, UPDATE o DELETE de una tabla o vista. Se ejecutan en respuesta a una variedad de eventos de lenguaje de definición de datos (DDL). Estos eventos corresponden principalmente a instrucciones CREATE, ALTER y Trigger DDL DROP de Transact-SQL, y a determinados procedimientos almacenados del sistema que ejecutan operaciones de tipo DDL. Trigger DML. CREATE TRIGGER <Trigger_Name, sysname, Trigger_Name> ON <Table_Name, sysname, Table_Name> AFTER <Data_Modification_Statements, , INSERT,DELETE,UPDATE> AS BEGIN -- SET NOCOUNT ON added to prevent extra result sets from -- interfering with SELECT statements. SET NOCOUNT ON; -- Insert statements for trigger here END

Página 43

Autor: Ing. Núñez Marinovich Néstor Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación Las instrucciones de triggers DML utilizan dos tablas especiales

Tabla

Descripción

inserted

deleted

Solo está disponible en las operaciones INSERT y UPDATE y en ella están los valores resultantes despues de la inserción o actualización. Es decir, los datos insertados. Inserted estará vacia en una operación DELETE. Disponible en las operaciones UPDATE y DELETE, están los valores anteriores a la ejecución de la actualización o borrado. Es decir, los datos que serán borrados. Deleted estará vacia en una operacion INSERT.

¿No existe una tabla UPDATED? No, hacer una actualización es lo mismo que borrar (deleted) e insertar los nuevos (inserted). La sentencia UPDATE es la única en la que inserted y deleted tienen datos simultaneamente.

Ejemplo: Crear un Trigger en la Tabla Categories tal q al actualizar, actualizar o elimianr algún dato, se muestre la tabla inserted y deleted Create TRIGGER TR_Categories ON Categories AFTER INSERT,UPDATE,DELETE AS BEGIN -- SET NOCOUNT ON impide que se generen mensajes de texto -- con cada instrucción SET NOCOUNT ON; SELECT categoryID, categoryName FROM INSERTED SELECT categoryID, categoryName FROM DELETED END --Prueba: update categories set categoryName='Nueva categoria'where categoryID=9 insert categories(categoryName)values('Categoria N') delete categories where categoryID=9 SELECT *from categories

Descripción Desactiva el trigger Activa el trigger Desactiva todos los trigger de la tabla Categories Activa todos los trigger de la tabla Categories

Trigguer DISABLE TRIGGER TR_Categories ENABLE TRIGGER TR_Categories ALTER TABLE Categories DISABLE TRIGGER ALL ALTER TABLE Categories ENABLE TRIGGER ALL

Trigger DDL CREATE TRIGGER <trigger_name, sysname, table_alter_drop_safety> ON DATABASE FOR <data_definition_statements, , DROP_TABLE, ALTER_TABLE> AS BEGIN ... END La siguiente instrucción impide que se ejecuten sentencias drop table y alter table en la base de datos. CREATE TRIGGER TR_SEGURIDAD ON DATABASE FOR DROP_TABLE, ALTER_TABLE AS BEGIN RAISERROR ('No está permitido borrar ni modificar estructura de las tablas !!!', 16, 1) ROLLBACK TRANSACTION END --Prueba Drop table [order details]

Página 44

Autor: Ing. Núñez Marinovich Néstor Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación Cursores Un cursor es una variable que nos permite recorrer con un conjunto de resultados obtenido a través de una sentencia SELECT fila a fila. Pasos paratrabajar con cursores Instrucción Acción DECLARE OPEN FETCH ... INTO CLOSE DEALLOCATE

Declara el cursor Abre el cursor Lee los datos del cursor Cierra el cursor Libera el cursor

@@FETCH_STATUS: Devuelve el estado de la última instrucción FETCH de cursor emitida para cualquier cursor abierto en ese momento por la conexión.

Valor devuelto Descripción 0

La instrucción FETCH se ejecutó correctamente.

-1

La instrucción FETCH no se ejecutó correctamente o la fila estaba más allá del conjunto de resultados.

-2

Falta la fila capturada.

Ejemplo: -- Declaracion de variables para el cursor DECLARE @Id int, @Nombre varchar(80), @Apellido varchar(80), @FechaNacimiento datetime -- Declaración del cursor DECLARE cClientes CURSORFOR SELECT EmployeeID, FirstName, LastName, Birthdate FROM employees OPEN cClientes -- Apertura del cursor -- Lectura de la primera fila del cursor FETCH cClientes INTO @id, @Nombre, @Apellido, @FechaNacimiento WHILE (@@FETCH_STATUS= 0 ) BEGIN PRINT @Nombre +' '+ @Apellido +space(5)+cast(@FechaNacimiento as char(12)) -- Lectura de la siguiente fila del cursor FETCH cClientes INTO @id, @Nombre, @Apellido, @FechaNacimiento END CLOSE cClientes -- Cierre del cursor DEALLOCATE cClientes -- Liberar los recursos

Ejemplo 2: Crear backup de todas las bases de datos DECLARE DECLARE DECLARE DECLARE

@name VARCHAR(50)-- database name @path VARCHAR(256)-- path for backup files @fileName VARCHAR(256)-- filename for backup @fileDate VARCHAR(20)-- used for file name

SET @path ='D:\Backup\'--Debe de existir la ruta, crearla manualmente si no existe

Página 45

Autor: Ing. Núñez Marinovich Néstor Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación SELECT

@fileDate =CONVERT(VARCHAR(20),GETDATE(),112)

DECLARE db_cursor CURSORFOR SELECT name FROM master.dbo.sysdatabases WHERE name NOTIN('master','model','msdb','tempdb') OPEN db_cursor FETCH NEXT FROM db_cursor INTO @name WHILE @@FETCH_STATUS= 0 BEGIN SET @fileName = @path + @name +'_'+ @fileDate +'.BAK' BACKUP DATABASE @name TODISK= @fileName FETCH NEXT FROM db_cursor INTO @name END CLOSE db_cursor DEALLOCATE db_cursor Apertura del Cursor: DECLARE<nombre_cursor>CURSOR [ LOCAL | GLOBAL ] [ FORWARD_ONLY | SCROLL ] [ STATIC | KEYSET | DYNAMIC | FAST_FORWARD ] [ READ_ONLY | SCROLL_LOCKS | OPTIMISTIC ] [ TYPE_WARNING ] FOR<sentencia_sql>

Apertura del Cursor Especifica que el ámbito del cursor es local para el proceso por lotes, procedimiento almacenado o desencadenador en que se creó el cursor. Especifica que el ámbito del cursor es global para la conexión. Puede hacerse GLOBAL referencia al nombre del cursor en cualquier procedimiento almacenado o proceso por lotes que se ejecute en la conexión. Especifica que el cursor sólo se puede desplazar de la primera a la última fila. FORWARD_ONLY FETCH NEXT es la única opción de recuperación admitida. Especifica que están disponibles todas las opciones de recuperación (FIRST, LAST, PRIOR, NEXT, RELATIVE, ABSOLUTE). Si no se especifica SCROLL en una instrucción DECLARE CURSOR la única opción de recuperación que se admite es NEXT. No es posible especificar SCROLL si se incluye también FAST_FORWARD. SCROLL LOCAL

STATIC

KEYSET

DYNAMIC

Página 46

Si se incluye la opción SCROLL, la forma en la realizamos la lectura del cursor varia, debiendo utilizar la siguiente sintaxis: FETCH [ NEXT | PRIOR | FIRST | LAST | RELATIVE | ABSOLUTE ] FROM < INTO Define un cursor que hace una copia temporal de los datos que va a utilizar. Todas las solicitudes que se realizan al cursor se responden desde esta tabla temporal de tempdb; por tanto, las modificaciones realizadas en las tablas base no se reflejan en los datos devueltos por las operaciones de recuperación realizadas en el cursor y además este cursor no admite modificaciones. Especifica que la pertenencia y el orden de las filas del cursor se fijan cuando se abre el cursor. El conjunto de claves que identifica las filas de forma única está integrado en la tabla denominada keyset de tempdb. Define un cursor que, al desplazarse por él, refleja en su conjunto de resultados todos los cambios realizados en los datos de las filas. Los valores de los datos, el orden y la pertenencia de las filas pueden cambiar en cada operación de recuperación. La opción de recuperación ABSOLUTE no se puede utilizar en los cursores dinámicos Autor: Ing. Núñez Marinovich Néstor Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación FAST_FORWARD

READ_ONLY

SCROLL_LOCKS

OPTIMISTIC

TYPE_WARNING

Especifica un cursor FORWARD_ONLY, READ_ONLY con las optimizaciones de rendimiento habilitadas. No se puede especificar FAST_FORWARD si se especifica también SCROLL o FOR_UPDATE. Evita que se efectúen actualizaciones a través de este cursor. No es posible hacer referencia al cursor en una cláusula WHERE CURRENT OF de una instrucción UPDATE o DELETE. Esta opción reemplaza la capacidad de actualizar el cursor. Especifica que se garantiza que las actualizaciones o eliminaciones posicionadas realizadas a través del cursor serán correctas. Microsoft SQL Server bloquea las filas cuando se leen en el cursor para garantizar que estarán disponibles para futuras modificaciones. No es posible especificar SCROLL_LOCKS si se especifica también FAST_FORWARD o STATIC. Especifica que las actualizaciones o eliminaciones posicionadas realizadas a través del cursor no se realizarán correctamente si la fila se ha actualizado después de ser leída en el cursor. SQL Server no bloquea las filas al leerlas en el cursor. En su lugar, utiliza comparaciones de valores de columna timestamp o un valor de suma de comprobación si la tabla no tiene columnas timestamp, para determinar si la fila se ha modificado después de leerla en el cursor. Si la fila se ha modificado, el intento de actualización o eliminación posicionada genera un error. No es posible especificar OPTIMISTIC si se especifica también FAST_FORWARD. Especifica que se envía un mensaje de advertencia al cliente si el cursor se convierte implícitamente del tipo solicitado a otro

Ejemplo: DECLARE @Id int, @Nombre varchar(80), @Apellido varchar(80), @FechaNacimiento datetime -- Declaración del cursor DECLARE cClientes CURSOR SCROLL FOR SELECT EmployeeID, FirstName, LastName, Birthdate FROM employees OPEN cClientes -- Apertura del cursor -- Lectura de la primera fila del cursor FETCH NEXT FROM cClientes INTO @id, @Nombre, @Apellido, @FechaNacimiento WHILE (@@FETCH_STATUS= 0 ) BEGIN PRINT @Nombre +' '+ @Apellido +space(5)+cast(@FechaNacimiento as char(12)) -- Lectura de la siguiente fila del cursor FETCH cClientes INTO @id, @Nombre, @Apellido, @FechaNacimiento END -- Lectura de la fila anterior FETCH PRIOR FROM cClientes INTO @id, @Nombre, @Apellido, @FechaNacimiento PRINT'Anterior: '+ @Nombre +' '+ @Apellido +space(5)+cast(@FechaNacimiento char(12))

as

-- Lectura de la primera fila FETCH FIRST FROM cClientes INTO @id, @Nombre, @Apellido, @FechaNacimiento PRINT'Primera fila: '+ @Nombre +' '+ @Apellido +space(5)+cast(@FechaNacimiento char(12)) -- Lectura de la ultima fila FETCH LAST FROM cClientes INTO @id, @Nombre, @Apellido, @FechaNacimiento PRINT'Ultima fila: '+ @Nombre +' '+ @Apellido +space(5)+cast(@FechaNacimiento char(12))

Página 47

Autor: Ing. Núñez Marinovich Néstor Manuel Ingeniero Informático

as

as

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación -- Lectura de la fila anterior FETCH PRIOR FROM cClientes INTO @id, @Nombre, @Apellido, @FechaNacimiento PRINT'Anterior: '+ @Nombre +' '+ @Apellido +space(5)+cast(@FechaNacimiento char(12))

as

--Lectura de fila 5 FETCH ABSOLUTE 5 FROM cClientes INTO @id, @Nombre, @Apellido, @FechaNacimiento PRINT'Fila 5: '+ @Nombre +' '+ @Apellido +space(5)+cast(@FechaNacimiento as char(12)) --Lectura de 2 filas antes a la posicion actual FETCH RELATIVE-2 FROM cClientes INTO @id, @Nombre, @Apellido, @FechaNacimiento PRINT'Fila 2 anteriores: '+ @Nombre +' '+ @Apellido +space(5)+cast(@FechaNacimiento char(12))

as

CLOSE cClientes -- Cierre del cursor DEALLOCATE cClientes -- Liberar los recursos

SQL Dinámico La instrucción EXECUTE (EXEC):Permite ejecutar una cadena de caracteres que representa una sentencia SQL. El principal incoveniente de trabajar con la instrucción EXEC es que no permite el uso de parametros abriendo la puerta a potenciales ataques de Sql Injections DECLARE @sql nvarchar(1000) SET @sql='CREATE TABLE TEMPORAL ( ID int IDENTITY, DATO varchar(100))' EXEC (@sql) SET @sql ='SELECT EXEC (@sql)

* FROM TEMPORAL'

El procedimiento almacenado sp_executesql:Para ejecutar sql dinámico, se recomienda utilizar el procedimiento almacenado sp_executesql, en lugar de una instrucción EXECUTE. • sp_executesql admite la sustitución de parámetros, • sp_executesql es más seguro y versátil que EXECUTE • sp_executesql genera planes de ejecución con más probabilidades de que SQL Server los vuelva a utilizar, es más eficaz que EXECUTE.

Ejemplo1: DECLARE @sql nvarchar(1000) SET @sql ='SELECT * from employees' EXEC sp_executesql@sql

Ejemplo2 con parametros: DECLARE @sql nvarchar(1000), @paramDefinition nvarchar(255), @paramValue char(3) SET @paramDefinition ='@codPais char(3)' SET @paramValue ='USA' SET @sql ='SELECT * from employees WHERE Country = @codPais' EXEC sp_executesql@sql, @paramDefinition, @paramValue

Página 48

Autor: Ing. Núñez Marinovich Néstor Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación

Pivot Table PIVOT es un nuevo operador incluído en SQL Server 2005 que podemos usar en la cláusula FROM para rotar filas en columnas y conseguir informes de tabla cruzada. Al usar el comando PIVOT, pueda que nos alga el siguiente error:

Incorrect syntax near 'PIVOT'. You may need to set the compatibility level of the current database to a higher value to enable this feature. See help for the SET COMPATIBILITY_LEVEL option of ALTER DATABASE.

Debemos de cambiar el nivel de compatibilidad de la base de datos. El COMPATIBILITY_LEVEL está en 80, debemos de cambiarla manualmente ejecutando: SQL 2005

SQL 2008

EXEC sp_dbcmptlevel 'myDatabaseName', 90

EXEC sp_dbcmptlevel 'myDatabaseName', 100

Sintaxis: SELECT <columna no dinamizada>, [primera columna dinamizada] AS <nombre de columna>, [segunda columna dinamizada] AS <nombre de columna> ... [última columna dinamizada] AS <nombre de columna> FROM (<la consulta SELECT que genera los datos>) AS <alias de la consulta de origen> PIVOT (<función de agregación>(<columna que se agrega>) FOR [<columna que contiene los valores que se convertirán en encabezados de columna>] IN ([primera columna dinamizada], [segunda columna dinamizada] ... [última columna dinamizada]) ) AS <alias de la tabla dinamizada> <cláusula ORDER BY opcional>;

Pivot Estático: --Nro de ventas x Años y Trimestres select * from (SELECT year(orderdate)as Año, datepart(quarter,orderdate) as Trimestre, orderid from orders) T pivot (count(orderid) FOR Trimestre in ([1],[2],[3],[4])) as Pv

--Nro de ventas x Años y Trimestres con cabeceras de columna personalizados select Año,[1] as Trimestre1,[2] as Trimestre2,[3] as Trimestre3,[4] as Trimestre4 from (SELECT year(orderdate)as Año, datepart(quarter,orderdate) as Trimestre, orderid from orders) T pivot (count(orderid) FOR Trimestre in ([1],[2],[3],[4])) as Pv

Página 49

Autor: Ing. Núñez Marinovich Néstor Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación --Monto de las ventas por Año y Trimestres. Agregar una columna al final que muestre montos totales por cada año select Año,isnull([1],0) as Trimestre1,isnull([2],0) as Trimestre2,isnull([3],0) as Trimestre3,isnull([4],0) as Trimestre4, isnull([1],0)+isnull([2],0)+isnull([3],0)+isnull([4],0) as Total from (SELECT year(o.orderdate)as Año, datepart(quarter,o.orderdate)as Trimestre, sum(od.quantity*od.unitprice*(1-od.discount)) monto from orders as o join [order details] as od on o.orderid = od.orderid group by o.orderdate ) T PIVOT (sum(monto) FOR Trimestre in ([1],[2],[3],[4])) as Pv

--Mostrar el valor total vendido por cada empleado para los siguientes productos: --'Alice Mutton','Filo Mix','Flotemysost','Geitost', 'Konbu','Maxilaku','Pavlova','Tofu','Vegie-spread'. SELECT Empleado, [Alice Mutton],[Filo Mix],[Flotemysost], [Geitost],[Konbu], [Maxilaku],[Pavlova],[Tofu],[Vegie-spread] FROM ( select E.lastname+ ' ' + E.firstname as Empleado, P.Productname as Producto , sum (OD.Unitprice*OD.Quantity) as Total FROM Employees E INNER JOIN Orders O ON E.EmployeeID = O.EmployeeID INNER JOIN [Order Details] OD ON O.OrderID = OD.OrderID INNER JOIN Products P ON OD.ProductID = P.ProductID WHERE P.Productname IN('Alice Mutton','Filo Mix','Flotemysost','Geitost', 'Konbu','Maxilaku','Pavlova','Tofu','Vegie-spread') group by E.lastname+ ' ' + E.firstname ,Productname ) as T PIVOT(SUM(Total) FOR [Producto] IN ([Alice Mutton],[Filo Mix],[Flotemysost], [Geitost],[Konbu],[Maxilaku],[Pavlova],[Tofu],[Vegie-spread])) AS PV

Página 50

Autor: Ing. Núñez Marinovich Néstor Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación Pivot Dinámico: Ejemplo1:

Nota: Cuando se trabaja con las constantes de cadena Unicode en SQL Server debe preceder a todas las cadenas Unicode con una letra mayúscula N. El prefijo "N" significa el idioma nacional en el estándar SQL-92 92 y debe ser mayúscula.

/*Muestra el monto de cada producto Con sus correspondientes categorias.*/ DECLARE @idCategoria INT DECLARE @listaCategorias AS NVARCHAR(MAX), NVARCHAR @nombreCategoria AS varchar(50) varchar --seleccionamos seleccionamos el menor idcategoria SET @idCategoria=(SELECT MIN(CategoryID CategoryID) FROM Categories) --seleccionamos seleccionamos el nombre de la categoria de dicho idcategoria SET @nombreCategoria = ( SELECT CategoryName FROM Categories WHERE CategoryID = @idCategoria) SET @listaCategorias = N'' WHILE @nombreCategoria IS NOT NULL BEGIN --armamos armamos la lista de las categorias SET @listaCategorias = @listaCategorias + N',['+ @nombreCategoria +N']' --seleccionamos seleccionamos la siguiente categoria SET @nombreCategoria = (SELECT SELECT TOP(1) CategoryName FROM Categories WHERE CategoryID > @idCategoria ORDER BY CategoryID ASC) --seleccionamos seleccionamos el id de dicha categoria SET @idCategoria=(SELECT MIN(CategoryID) MIN FROM Categories Where Categoryname=@nombreCategoria) ) END SUBSTRING 2, LEN(@listaCategorias @listaCategorias)) SET @listaCategorias = SUBSTRING(@listaCategorias, print @listaCategorias DECLARE @sql AS nvarchar(MAX) SET @sql = N'SELECT * FROM (SELECT P.ProductName, ProductName, C.CategoryName, (OD.UnitPrice * OD.Quantity) AS Monto FROM Products P INNER JOIN dbo.[Order Details] OD ON P.ProductID=OD.ProductID INNER JOIN Categories C ON C.CategoryID=P.CategoryID ) T PIVOT (SUM(Monto) FOR CategoryName IN ('+ (' @listaCategorias + ')) AS PV' EXEC sp_executesql @sql

Página 51

Autor: Ing. In Núñez Marinovich Néstor Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: mail: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación Ejemplo1: Crearemos un procedimiento para generar un pivot dinámico create procedure dynamic_pivot ( @select varchar(2000), @PivotCol varchar(100), @Summaries varchar(100) ) as declare @pivot varchar(max), @sql varchar(max) select @select =replace(@select @select,'select ','select '+@PivotCol+' ' as pivot_col,') pivot_col,' create table #pivot_columns (pivot_column pivot_column varchar(100)) Select @sql='select distinct pivot_col from ('+@select+') (' as t' insert into #pivot_columns exec(@sql) select @pivot=coalesce(@pivot+ +',','')+'['+pivot_column+']'from #pivot_columns select @sql= 'select * from ('+@select+' ' ) as t pivot ( '+@Summaries+' ' for pivot_col in ('+@pivot+') (' ) as p' exec(@sql) --luego ejecutar: EXEC dynamic_pivot 'SELECT e.lastname as Empleado, o.OrderDate FROM northwind..Employees as e INNER JOIN northwind..Orders as o ON (e.EmployeeID=o.EmployeeID) ', ' 'Year(OrderDate)', 'Count(OrderDate)'

--luego ejecutar: EXEC dynamic_pivot 'SELECT s.companyname as Proveedor,coalesce(od.unitprice*od.quantity ,0) as total_cost FROM northwind..products as p inner join northwind..[order details] as od on p.productid=od.productid inner join northwind..suppliers as s on p.supplierid=s.supplierid', p.supplierid=s.supplierid' 'productname', 'sum(total_cost)'

Página 52

Autor: Ing. In Núñez Marinovich Néstor Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: mail: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación

Oracle es un sistema de gestión de base de datos objeto-relacional (o ORDBMS por el acrónimo en inglés de Object-Relational Data Base Management System), desarrollado por Oracle Corporation. Se considera a Oracle como uno de los sistemas de bases de datos más completos, destacando: soporte de transacciones, estabilidad, escalabilidad y Soporte multiplataforma. Fuente: iSIL Tech - Curso de Oracle Database 11g – SQL and PL/SQL Fundamentals

Descripción

Sentencia SQL

Crear usuario MarketPERU.

CREATE USER MarketPERU IDENTIFIED BY mercado;

Conceda al usuario MarketPERU los privilegios CONNECT y RESOURCE

GRANT connect, resource TO MarketPERU;

Conceder todos los privilegios

GRANT ALL PRIVILEGES TO MarketPERU;

Desbloquear cuenta con system.

ALTER USER MarketPERU identified by mercado ACCOUNT UNLOCK;

Ejecutar script de crear esquema y carga de datosde MarketPeru Conectarse a MarketPeru. Luego pide contraseña (mercado).

@D:\CreaEsquemaMarketPERU.sql @D:\CargaDatosMarketPERU.sql

Mostra los objetos de un esquema

select * from cat;

Mostrar la descripción de una tabla

DESCRIBE proveedor;

CONNECT MarketPERU;

Diagrama de MarketPeru

Página 53

Autor: Ing. Núñez Marinovich Néstor Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación Script Esquema MarketPeru create table CATEGORIA( IdCategoria number(2) primary key, Categoria varchar2(20) not null, Descripcion varchar2(40) null ); create table PROVEEDOR( IdProveedor number(3) not null, Nombre varchar2(40) not null, Representante varchar2(30) null, Direccion varchar2(60) null, Ciudad varchar2(15) null, Departamento varchar2(15) null, CodigoPostal varchar2(15) null, Telefono varchar2(15) null, Fax varchar2(15) null ); alter table PROVEEDOR add primary key(IdProveedor); create table PRODUCTO( IdProducto number(5) primary key, IdCategoria number(2) not null, IdProveedor number(3) not null, Nombre varchar2(40) not null, UnidadMedida varchar2(30) null, PrecioUnitario number(8,2) null, StockActual number(6) null, StockMinimo number(6) null, Descontinuado number(1) not null);

create table ORDEN_DETALLE( IdOrden number(6) not null, IdProducto number(5) not null, PrecioCompra number(8,2) not null, CantidadSolicitada number(6) not null, CantidadRecibida number(6) not null, Estado varchar2(10) null ); alter table ORDEN_DETALLE add primary key(IdOrden, IdProducto); alter table ORDEN_DETALLE add foreign key(IdOrden) references ORDEN; alter table ORDEN_DETALLE add foreign key(IdProducto) references PRODUCTO; create table GUIA ( IdGuia number(6) primary key, IdLocal number(2) not null, FechaSalida date not null, Transportista varchar2(30) not null ); alter table GUIA add foreign key(IdLocal) references LOCAL; create table GUIA_DETALLE( IdGuia number(6) not null, IdProducto number(5) not null, PrecioVenta number(8,2) not null, Cantidad number(6) not null );

alter table PRODUCTO add foreign key (IdProveedor) references PROVEEDOR; alter table PRODUCTO add foreign key (IdCategoria) references CATEGORIA;

alter table GUIA_DETALLE add primary key(IdGuia, IdProducto);

create table LOCAL( IdLocal number(2) primary key, Direccion varchar2(60) null, Distrito varchar2(20) null, Telefono varchar2(15) null, Fax varchar2(15) null ); create table ORDEN( IdOrden number(6) primary key, FechaOrden date not null, FechaEntrada date not null );

alter table GUIA_DETALLE add foreign key(IdProducto) references PRODUCTO; alter table GUIA_DETALLE add foreign key(IdGuia) references GUIA; alter table PRODUCTO add unique(Nombre, UnidadMedida); alter table CATEGORIA add unique(Categoria);

Página 54

Autor: Ing. Núñez Marinovich Néstor Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación Funciones Matematicas SELECT abs(-5755) FROM dual; -- Retorna 5755 SELECT acos(-1) FROM dual; -- Retorna 3.14159265 SELECT asin(1) FROM dual; -- Retorna 1.57079633 SELECT atan(0) FROM dual; -- Retorna 0 SELECT atan2(1, 0) FROM dual; -- Retorna 1.57079633 SELECT ceil(27.157) FROM dual; -- Retorna 28 SELECT cos(3.14159265) FROM dual; -- Retorna -1 SELECT cosh(0) FROM dual; -- Retorna 1 SELECT exp(1) FROM dual; -- Retorna 2.71828183 SELECT floor(27.857) FROM dual; -- Retorna 27 SELECT ln(2.71828183) FROM dual; -- Retorna 1 SELECT log(10, 1000) FROM dual; -- Retorna 3 SELECT mod(11, 3) FROM dual; -- Retorna 2 SELECT power(4, 5) FROM dual; -- Retorna 1024 SELECT round(748.5845, 0) FROM dual; -- 749.0000 SELECT round(748.5845, 1) FROM dual; -- 748.6000 SELECT round(748.5845, 2) FROM dual; -- 748.5800 SELECT sign(-180) FROM dual; -- Retorna -1 SELECT sin(3.14159265/2) FROM dual; -- Retorna 1 SELECT sinh(1) FROM dual; -- Retorna 1.17520119 SELECT sqrt(225) FROM dual; -- Retorna 15 SELECT tan(3.14159265/4) FROM dual; -- Retorna 1 SELECT tanh(0.5) FROM dual; -- Retorna .462117157 SELECT trunc(123.6789, 2) FROM dual; -- 123.67 SELECT trunc(123.6789) FROM dual; -- 123 SELECT trunc(123.6789, -1) FROM dual; -- 120

Funciones de Cadena SELECT SELECT SELECT SELECT

ASCII('Marinovich') FROM dual; -- Retorna 77 chr(77) FROM dual; -- Retorna 'M' concat('Hola ', 'Mundo') FROM dual; -- Retorna ''Hola Mundo' initcap('Oracle es mI PASION') FROM dual; -- Retorna 'Oracle Es Mi Pasion'

--Instr(cadena1, cadena2 [ , n1 [ , n2 ] ] ) --Busca la ocurrencia n2 de cadena2 en cadena1. La búsqueda empieza a partir del caracter en la posición n1 en expresiónCadena1. SELECT instr('el murcielago del pielago', 'el', 3, 2) FROM dual; -- Retorna 16 SELECT SELECT SELECT SELECT SELECT SELECT SELECT SELECT SELECT SELECT

length('Nuñez Marinovich') FROM dual; -- Retorna 16 lower('Hola MUNDO') FROM dual; -- Retorna 'hola mundo' upper('Hola mundo') FROM dual; -- Retorna 'HOLA MUNDO' lpad('Oracle', 11, '*+') FROM dual;--Retorna: '*+*+*Oracle' ltrim(' Oracle Enterprise') FROM dual; -- Retorna 'Oracle Enterprise' ltrim('Oracle Enterprise', 'Oracle') FROM dual; -- Retorna ' Enterprise' replace('la triste noche del triste día', 'triste', 'alegre') FROM dual; -- Retorna la alegre noche del alegre día rpad('Oracle', 11, '*+') FROM dual;--Retorna: 'Oracle*+*+*' rtrim('Oracle Enterprise ') FROM dual; -- Retorna 'Oracle Enterprise' rtrim('Oracle Enterprise', 'Enterprise') FROM dual; -- Retorna ' Oracle'

--Soundex( expresiónCadena ) Retorna un código de cuatro caracteres que establece la fonética de expresiónCadena. Se utiliza para comparar si dos cadenas son fonéticamente similares. SELECT soundex('MACRO'), soundex('MICRO') FROM dual; -- Retorna M260, M260 --retorna una subcadena de n caracteres de longitud generada a partir de la posición inicio. SELECT substr('Oracle es mi pasion', 4, 3) FROM dual; -- Retorna 'cle' SELECT SELECT SELECT SELECT

translate('jejeje', 'e', 'o') FROM dual; -- Retorna 'jojojo' trim(LEADING '1' FROM '1231') FROM dual; -- Retorna '231' trim(TRAILING '1' FROM '1231') FROM dual; -- Retorna '123' trim('1' FROM '1231') FROM dual; -- Retorna '23'

Página 55

Autor: Ing. Núñez Marinovich Néstor Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación Funciones Fecha Devuelve la fecha actual Sumar y restar una fecha Agregar 5 meses a la fecha actual Establece el formato de salida de la sesión para los datos fecha-hora. Establece que la zona horaria actual (zona horaria de la sesión) es –5 horas respecto a la del Meridiano de Greenwich (UTC). Muestra la zona horaria de la sesión, y la fecha actual para esa zona horaria. Mostrar fecha actual (current_date), current_timestamp, y localtimestamp. Entrega el valor de la zona horaria de la base de datos.

Sentencia SQL select sysdate from dual; SELECT sysdate, sysdate - 10, sysdate + 10 FROM dual; SELECT add_months(sysdate, 5) FROM dual; ALTER SESSION SET nls_date_format = 'DD-MON-YYYY HH24:MI:SS'; ALTER SESSION SET time_zone = '-5:0'; SELECT sessiontimezone, current_date FROM dual SELECT current_date, current_timestamp, localtimestamp FROM dual; SELECT dbtimezone FROM dual;

Devuelve la parte de uan fecha. Extract( parteFecha from expresiónFecha ). parteFecha: Year, Month, Day, Hour, Minute, Second, Timezone_hour, Timezone_minute, Timezone_region, Timezone_abbr.

select extract(year from current_timestamp) from dual; select extract(month from sysdate) from dual; select extract(day from current_timestamp) from dual;

Entrega la fecha del último día del mes especificado

SELECT last_day(sysdate) FROM dual;

Entrega la diferencia en meses

SELECT months_between(sysdate, to_date('02/03/2010', 'DD/MM/YYYY')) FROM dual;

Entrega la fecha posterior más cercana a una fecha dada y que cae en el día de semana especificado.

SELECT next_day(sysdate, 'MARTES') FROM dual;

Ejemplos de formato y lenguaje especifiados.

SELECT to_char(sysdate, 'Day DD Mon, YYYY', 'NLS_DATE_LANGUAGE = English') FROM dual; SELECT to_char(sysdate, 'Day DD Mon, YYYY', 'NLS_DATE_LANGUAGE = Spanish') FROM dual;

Funciones de conversion de tipo de datos SELECT cast('03-DIC-2010' AS TIMESTAMP WITH LOCAL TIME ZONE) FROM dual;

--Retorna 03/12/20 10:00:00,000000 +00:00

Otras funciones Sentencia SQL Entregan el ID y el nombre del usuario en la sesión SELECT user, uid FROM dual; actual. Devolver los detalles de las ordenes y ademas una columna que compare al cantidad solicitada con la cantidad recibida. Si son iguales escribir ‘Conforme’, sino ‘No conforme’. Decode( expresión, valor1, resultado1 [, valor2, resultado2 , ...] [, otroResultado ] )

SELECT idOrden, idProducto, cantidadSolicitada, cantidadRecibida, decode(cantidadSolicitada, cantidadRecibida, 'Conforme', 'No Conforme') AS Conformidad FROM Orden_detalle;

Coalesce( listaExpresiones ) Retorna el primer valor NOT NULL de listaExpresiones Nullif( expresión1, expresión2 ) Compara expresión1 con expresión2. Si son iguales, la función retorna el valor NULL; en caso contrario, retorna expresión1.

SELECT coalesce(null, null, null, 10, null, 20, null) FROM dual; -- Retorna 10

Nvl( expresión1, expresión2 ) Si expresión1 es NULL, la función retorna expresión2.

SELECT idProveedor, nombre, ciudad, departamento, nvl(telefono, 'Dato no ingresado') AS telefono FROM Proveedor;

Nvl2( expresión1, expresión2, expresión3 ) Si expresión1 no es NULL, retorna expresión2; si expresión1 es NULL, retorna expresión3.

SELECT idGuia, fechaSalida, nvl2(transportista, 'Asignado', 'No asignado') AS transportista FROM Guia;

Página 56

SELECT cantidadSolicitada, cantidadRecibida, nullif(cantidadSolicitada, cantidadRecibida) AS Incompleto FROM Orden_detalle;

Autor: Ing. Núñez Marinovich Néstor Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación Regexp_instr( expCadena, patrónBúsqueda [, inicio [, ocurrencia [, opciónRetorno [, comportamiento ] ] ] ] ) Esta función amplía la funcionalidad de la función instr permitiendo la búsqueda de una cadena en base a un patrón de búsqueda. La función devuelve la posición de la ocurrencia según el valor del argumento opciónRetorno.

SELECT regexp_instr('Oracle es mi pasion', '[^ ]+', 1, 3) FROM dual;

-- Retorna 11, que es la posición del caracter inicial -- en la 3ra palabra ('mi') de la cadena.

Consultas tablas: create table Editorial( idEditorial int, nombreEditorial varchar2(100), primary key(idEditorial) );

create table Libro( idLibro int, idEditorial int, titulo varchar2(100), autor varchar2(80) default 'Anonimo', precio decimal(5,2), cantidad smallint default 0, primary key(idLibro), foreign key (idEditorial) references Editorial(idEditorial));

Consultas sencillas: -- Generar la lista de precios. Mostrar: código del producto, descripción, presentación, precio unitario, precio con IGV. SELECT idProducto "Código", nombre "Descripción", unidadMedida "Presentación", precioUnitario "Precio Unitario", precioUnitario * 1.18 "Precio con IGV" FROM Producto;

-- Mostrar el nombre del proveedor y una columna que muestre la ciudad concatenada con el departamento SELECT nombre, ciudad || ' - ' || departamento AS Ubicación FROM Proveedor;

-- Genere una lista de productos que son de la categoría 2 SELECT * FROM Producto WHERE idCategoria = 2;

-- Genere una lista de productos pertenecientes a las categorías 2, 6 y 3 SELECT * FROM Producto WHERE idCategoria IN ( 2, 6, 3 );

-- Genere una lista de productos cuya descripción contenga la cadena 'gloria' SELECT * FROM Producto WHERE nombre = 'gloria'; -- nombre debe contener exactamente la cadena 'gloria' SELECT * FROM Producto WHERE nombre LIKE 'gloria'; -- nombre debe contener exactamente la cadena 'gloria' SELECT * FROM Producto WHERE nombre LIKE 'gloria%'; -- nombre debe empezar con la cadena 'gloria' SELECT * FROM Producto WHERE nombre LIKE '%gloria';-- nombre debe terminar con la cadena 'gloria' SELECT * FROM Producto WHERE nombre LIKE '%gloria%';-- nombre debe contener la cadena 'gloria' -- las búsquedas basadas en cadenas son case sensitive. SELECT * FROM Producto WHERE lower(nombre) LIKE '%gloria%'; SELECT * FROM Producto WHERE upper(nombre) LIKE '%GLORIA%';

--Mostrar el codigo del producto y su nombre, pero cuyo nombre del producto debe tener la cadena 'BLANC' antes del último carácter. El último caracter puede ser cualquiera. SELECT idProducto, nombre FROM Producto WHERE UPPER(nombre) LIKE '%BLANC_';

Página 57

Autor: Ing. Núñez Marinovich Néstor Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación Busquedas basadas en fechas: --Definir el formato de fecha a utilizar por la sesión cliente ALTER SESSION SET NLS_DATE_FORMAT = 'DD/MM/YYYY';

-- Generar un listado de las guías emitidas el 20 de Agosto del 2011 SELECT * FROM Guia WHERE TO_CHAR(fechaSalida, 'DD/MM/YYYY') = '28/08/2011';

--Igual al anterior pero con otro formato SELECT * FROM Guia WHERE TO_CHAR(fechaSalida, 'MM-DD-YY') = '08-28-11';

-- Generar una lista de las guías emitidas desde el 20 Setiembre 2011 al 27 Febrero 2012 SELECT * FROM Guia WHERE fechaSalida BETWEEN '20/09/2011' AND '27/02/2012';

-- Formato de fechas en la salida SELECT idGuia, TO_CHAR(fechaSalida, 'DD Month YYYY') fecha FROM Guia; SELECT idGuia, TO_CHAR(fechaSalida, 'fmDD Month YYYY') fecha FROM Guia;

Crear table Empleado: CREATE TABLE Empleado( IdEmpleado int PRIMARY KEY, Apellido varchar2(30) not null, HaberBasico decimal(8,2) not null, PorcentajeComision decimal(3,1) null);

INSERT INSERT INSERT INSERT INSERT

INTO INTO INTO INTO INTO

Empleado Empleado Empleado Empleado Empleado

VALUES(1, VALUES(2, VALUES(3, VALUES(4, VALUES(5,

'CASTRO ARENAS', 1200, 5); 'LUNA ESPEJO', 1000, 10); 'SOTO BUENO', 1400, NULL); 'MARQUEZ ARIZAGA', 1500, NULL); 'DAVILA SANCHEZ', 1200, 7.5);

--Mostrar los empleados cuyo porcentaje de comision no sea nulo SELECT idEmpleado, apellido, haberBasico, porcentajeComision FROM Empleado WHERE porcentajeComision IS NOT NULL;

--Listar los empleados mostrando el monto total a abonarle a cada uno por su remuneración del mes. COnsiderar: monto =shaberBasico + 10000 * porcentajeComision / 100 SELECT idEmpleado, apellido, haberBasico, porcentajeComision, haberBasico + 10000 * porcentajeComision / 100 AS monto FROM Empleado;--Incorrecto SELECT idEmpleado, apellido, haberBasico, porcentajeComision, haberBasico + 10000*NVL(porcentajeComision,0)/100 AS monto FROM Empleado; -- Correcto

--Ordenar la tabla empleados por porcentajecomision, listando los NULLs primero SELECT * FROM Empleado order by porcentajecomision NULLS FIRST;

--Ordenar la tabla empleados por porcentajecomision, listando los NULLs al final SELECT * FROM Empleado order by porcentajecomision NULLS LAST;

--Mostrar la tabla categoria mostrando aleatoriamente los registros. SELECT * FROM categoria ORDER BY dbms_random.value; --Mostrar 1 registro aleatoriamente de la tabla categoria SELECT * FROM (SELECT * FROM categoria ORDER BY dbms_random.value) WHERE rownum = 1; --Mostrar las 5 primeras filas de la tabla producto select rownum, idProducto, nombre from (select * from producto order by idProducto) where rownum<=5;

--Mostrar los registros entre las filas 5 y 10 de la tabla producto SELECT idProducto, nombre FROM (SELECT idProducto, nombre, ROWNUM r FROM producto order by idProducto) WHERE r BETWEEN 5 AND 10;

Página 58

Autor: Ing. Núñez Marinovich Néstor Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación Secuencia: Es un objeto de base de datos que genera números secuenciales y se utiliza para asignar valores a campos numéricos enteros en los que se requiere que la generación de su contenido sea automático y secuencial.

Sintáxis CREATE SEQUENCE nombre_secuencia [ START WITH valor_inicial ] [ INCREMENT BY incremento ] [ MAXVALUE valor_máximo | NOMAXVALUE ] [ MINVALUE valor_mínimo | NOMINVALUE ] [ CYCLE | NOCYCLE ]

--Creamos la secuencia CREATE SEQUENCE sqCodigo MAXVALUE 99999 start with 7; select sqCodigo.currval from dual; --obtener el valor actual de la secuencia select sqCodigo.nextval from dual; --obtener el siguienet valor de la secuencia

--Ejemplo insertar caracteres especiales como: ',%,_ insert into categoria (idcategoria, categoria, descripcion) values (sqCodigo.nextval, 'Toxicus''s', 'Alto % de _toxicidad'); commit;

--CARACTERES DE ESCAPE: ----Realizar consultas con los caracteres especiales como: ',%,_ select * from categoria where categoria LIKE '%' || '''' || '%';--Muestre las categorias que tienen el caracter ' select * from categoria where descripcion LIKE '%\%%' ESCAPE '\';--Buscar descripcion que contenga el caracter: % select * from categoria where descripcion LIKE '%\_%' ESCAPE '\';--Buscar descripcion que contenga el caracter: _

Agregación y agrupamiento: --Obtener el promedio de los precios unitarios de los productos: SELECT AVG(precioUnitario) FROM Producto;

--Cuenta de los productos despachados a los diferentes locales de la empresa. SELECT COUNT(DISTINCT idProducto) FROM Guia_detalle;

--Precio más alto y más bajo de los productos registrados en la tabla Producto. SELECT MAX(precioUnitario), MIN(precioUnitario) FROM Producto;

--Monto total de los productos salidos del almacén del producto10. SELECT SUM(precioVenta * cantidad) FROM Guia_detalle where idproducto=10;

--Cantidad de productos por proveedor para las categorías 2 y 4 SELECT idCategoria, idProveedor,COUNT(idProducto) AS Productos FROM Producto WHERE idCategoria IN (2, 4) GROUP BY idCategoria, idProveedor ORDER BY idCategoria;

--Productos cuyo monto total despachado es mayor a 20,000. SELECT idProducto, SUM(precioVenta * cantidad) AS "Monto total" FROM Guia_detalle GROUP BY idProducto HAVING SUM(precioVenta * cantidad) > 20000;

-- ¿Puedo usar alias para la expresión agregada? NO --lo siguiente da error SELECT idCategoria, count(descontinuado) cuenta_productos FROM Producto GROUP BY idCategoria HAVING cuenta_productos > 20 ORDER BY 1;

--lo siguiente es correcto SELECT idCategoria, count(descontinuado) cuenta_productos FROM Producto GROUP BY idCategoria HAVING count(descontinuado) > 20 ORDER BY 1;

Página 59

Autor: Ing. Núñez Marinovich Néstor Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación

-- ¿Puedo usar alias para la expresión agregada en el ORDER BY? SI SELECT idCategoria, count(descontinuado descontinuado) cuenta_productos FROM Producto GROUP BY idCategoria HAVING count(descontinuado) > 20 ORDER BY cuenta_productos;

/* GROUP BY agrupa las filas ilas de la tabla Producto en base a la combinación de los valores de las columnas idCategoria e idProveedor, y para cada una de las combinaciones obtenidas calcula la suma de columna precioUnitario. */ SELECT idCategoria, idProveedor, sum(precioUnitario precioUnitario) AS "Precio Suma" FROM Producto GROUP BY CUBE(idCategoria, idProveedor) idProveedor ORDER BY idCategoria, idProveedor;

El resultado se muestra a continuación: n:

Página 60

Autor: Ing. In Núñez Marinovich Néstor Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: mail: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación

/* Ahora lo agrupamos con ROLLUP */ SELECT idCategoria, idProveedor, sum(precioUnitario precioUnitario) AS "Precio Suma" FROM Producto GROUP BY ROLLUP (idCategoria, idProveedor) idProveedor ORDER BY idCategoria, idProveedor;

El resultado se muestra a continuación: n:

Página 61

Autor: Ing. In Núñez Marinovich Néstor Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: mail: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación /* El operador GROUPING SETS permite que en una sola consulta GROUP BY se presenten grupos grupo formados por distintas combinaciones de atributos. Este ejemplo muestra la suma acumulada del stockActual para tres combinaciones de atributos: (idCategoria, idProveedor, precioUnitario) (idCategoria, precioUnitario) (idProveedor, precioUnitario) */ SELECT idCategoria, idProveedor, precioUnitario, precioUnitario SUM(stockActual) AS "Stock total" FROM Producto GROUP BY GROUPING SETS( (idCategoria, idProveedor, precioUnitario), precioUnitario (idCategoria, precioUnitario), (idProveedor, precioUnitario) ) ORDER BY idCategoria, idProveedor, precioUnitario; precioUnitario

El resultado se muestra a continuación: n:

Página 62

Autor: Ing. In Núñez Marinovich Néstor Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: mail: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación Consultas multitabla: Un join, combinación ó consulta correlacionada es la consulta que selecciona columnas de dos tablas ó conjuntos de filas, y las entrega en un único conjunto de resultados. Tpos: 1. inner join 2. outer join 2.1. left outer join 2.2. right outer join 2.3. full outer join 3. cross join Inner join: es la consulta correlacionada que combina todas las filas que están relacionadas de las dos tablas ó conjuntos de filas. --Obtener un listado de idCategoria, nombre de la categoría, idProducto, nombre producto, unidad y precio --Relación entre Categoria y Producto:c (Categoria.idCategoria = Producto.idCategoria) --Las siguientes consultas devuelven el mismo resultado: SELECT Categoria.idCategoria, Categoria.categoria, Producto.idProducto, Producto.nombre, Producto.unidadMedida, Producto.precioUnitario FROM Categoria, Producto WHERE Categoria.idCategoria = Producto.idCategoria ORDER BY 2,4; SELECT Categoria.idCategoria, Categoria.categoria, Producto.idProducto, Producto.nombre, Producto.unidadMedida, Producto.precioUnitario FROM Categoria INNER JOIN Producto ON Categoria.idCategoria = Producto.idCategoria ORDER BY 2,4; SELECT Categoria.idCategoria, categoria, idProducto, nombre, unidadMedida, precioUnitario FROM Categoria INNER JOIN Producto ON Categoria.idCategoria = Producto.idCategoria ORDER BY 2,4; SELECT C.idCategoria, C.categoria, P.idProducto, P.nombre, P.unidadMedida, P.precioUnitario FROM Categoria C INNER JOIN Producto P ON C.idCategoria = P.idCategoria ORDER BY 2,4;

-- Monto total despachado a cada local en Marzo del 2011 SELECT Local.idLocal, Local.direccion || ' - ' || Local.distrito dirección, SUM(Guia_Detalle.precioVenta * Guia_Detalle.cantidad) monto FROM Local INNER JOIN Guia ON Local.idLocal = Guia.idLocal INNER JOIN Guia_Detalle ON Guia.idGuia = Guia_Detalle.idGuia WHERE EXTRACT(YEAR FROM Guia.fechaSalida) = 2011 AND EXTRACT(MONTH FROM Guia.fechaSalida) =3 GROUP BY Local.idLocal, Local.direccion || ' - ' || Local.distrito;

--Unidades mensuales despachadas por cada producto SELECT Producto.idProducto, Producto.nombre, EXTRACT(YEAR FROM Guia.fechaSalida) AS Año, EXTRACT(MONTH FROM Guia.fechaSalida) AS Mes,SUM(Guia_detalle.cantidad) As Unidades FROM Guia INNER JOIN Guia_detalle ON Guia.idGuia = Guia_detalle.idGuia INNER JOIN Producto ON Guia_detalle.idProducto = Producto.idProducto GROUP BY Producto.idProducto, Producto.nombre, EXTRACT(YEAR FROM Guia.fechaSalida), EXTRACT(MONTH FROM Guia.fechaSalida) ORDER BY Producto.idProducto, Año, Mes;

Página 63

Autor: Ing. Núñez Marinovich Néstor Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación Outer join: es la consulta correlacionada que entrega todas las filas que están relacionadas, y además: - las filas no relacionadas de la tabla izquierda (LEFT OUTER JOIN), ó - las filas no relacionadas de la tabla derecha (RIGHT OUTER JOIN), ó - las filas no relacionadas de ambas tablas (FULL OUTER JOIN) Se considera como la tabla izquierda, a aquella que se menciona primero en la cláusula FROM --Muestra solo los productos que NO registran salida del almacén. SELECT Producto.idProducto, Producto.nombre FROM Producto LEFT OUTER JOIN Guia_detalle ON Producto.idProducto = Guia_detalle.idProducto WHERE Guia_detalle.cantidad IS NULL ORDER BY Producto.idProducto;

--Reporte unidades despachadas a cada producto SELECT Producto.idProducto, Producto.nombre,NVL(SUM(Guia_detalle.cantidad), 0) AS Unidades FROM Producto LEFT OUTER JOIN Guia_detalle ON Producto.idProducto = Guia_detalle.idProducto GROUP BY Producto.idProducto, Producto.nombre ORDER BY Producto.idProducto;

-- Generar un listado que muestre el total de unidades entrantes, y el total de unidades salientes, para cada producto. --La siguiente consulta es un ERROR, la data aparece "inflada" SELECT Producto.idProducto, Producto.nombre, SUM(Orden_Detalle.cantidadRecibida) entradas, SUM(Guia_Detalle.cantidad) salidas FROM Producto INNER JOIN Orden_Detalle ON Producto.idProducto = Orden_Detalle.idProducto INNER JOIN Guia_Detalle ON Producto.idProducto = Guia_Detalle.idProducto GROUP BY Producto.idProducto, Producto.nombre ORDER BY 1;

SOLUCIONES: --Solucion 1: Usando Vistas --Antes de crear las vistas se deberá otorgar permisos para crear vistas desde system grant create any view to MarketPeru;

-- Creación de la vista con las entradas CREATE VIEW vEntradas AS SELECT Producto.idProducto, Producto.nombre, NVL(SUM(Orden_Detalle.cantidadRecibida), 0) AS entradas FROM Producto LEFT OUTER JOIN Orden_Detalle ON Producto.idProducto = Orden_Detalle.idProducto GROUP BY Producto.idProducto, Producto.nombre ORDER BY Producto.idProducto;

-- Creación de la vista con las salidas CREATE VIEW vSalidas AS SELECT Producto.idProducto, Producto.nombre, NVL(SUM(Guia_Detalle.cantidad), 0) AS salidas FROM Producto LEFT OUTER JOIN Guia_Detalle ON Producto.idProducto = Guia_Detalle.idProducto GROUP BY Producto.idProducto, Producto.nombre ORDER BY Producto.idProducto;

-- Ejecución de vistas SELECT * FROM vEntradas; SELECT * FROM vSalidas;

-- Obtención del balance SELECT vEntradas.idProducto, vEntradas.nombre, vEntradas.entradas, vSalidas.salidas FROM vEntradas INNER JOIN vSalidas ON vEntradas.idProducto = vSalidas.idProducto;

Página 64

Autor: Ing. Núñez Marinovich Néstor Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación --Solucion 2 SELECT T_Entradas.idProducto, T_Entradas.nombre, T_Entradas T_Entradas.entradas, T_Salidas.salidas salidas FROM (SELECT Producto.idProducto, Producto.nombre, Pr NVL(SUM(Orden_Detalle.cantidadRecibida cantidadRecibida), 0) AS entradas FROM Producto LEFT OUTER JOIN Orden_Detalle ON Producto.idProducto = Orden_Detalle.idProducto Orden_Detalle GROUP BY Producto.idProducto, Producto.nombre ORDER BY Producto.idProducto) T_Entradas INNER JOIN (SELECT Producto.idProducto, Producto.nombre, Producto NVL(SUM(Guia_Detalle.cantidad cantidad), 0) AS salidas FROM Producto LEFT OUTER JOIN Guia_Detalle ON Producto.idProducto = Guia_Detalle.idProducto Guia_Detalle GROUP BY Producto.idProducto, Producto.nombre ORDER BY Producto.idProducto) T_Salidas ON T_Entradas.idProducto =T_Salidas.idProducto idProducto;

En cualquiera lquiera de las 2 soluciones se mostrará mostrar el resultado:

Cross join: Ess la consulta correlacionada que combina cada una de las filas de una de las tablas con cada una de las filas de la otra tabla. /* CROSS JOIN o Producto Cartesiano: Es un join ejecutado sin restricciones */ SELECT Producto.idProducto, Producto.nombre nombre, Categoria.categoria FROM Producto CROSS JOIN Categoria;

Natural join: Se e comparan todas las columnas que tengan el mismo nombre en ambas tablas. La tabla resultante contiene sólo una columna por cada par de columnas con el mismo nombre. SELECT idProducto, nombre, categoria FROM Producto NATURAL JOIN Categoria; Categoria

Página 65

Autor: Ing. In Núñez Marinovich Néstor Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: mail: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación Auto join: Es una consulta correlacionada en la que una tabla se combina consigo misma para generar un nuevo conjunto de resultados. /* AUTOJOIN: Es un join ejecutado en un solo conjunto. El conjunto tiene una autorelación */ -- Cambiar al esquema HR SELECT employee_id, last_name, job_id, manager_id FROM Employees ORDER BY employee_id;

-- Generar un reporte que para cada empleado muestre el apellido de su jefe SELECT E1.employee_id, E1.last_name, E1.job_id, E2.last_name FROM Employees E1 LEFT OUTER JOIN Employees E2 ON E1.manager_id = E2.employee_id ORDER BY 1;

Ejemplo AutoJoin: -- Consulta autojoin, creación de la tabla con autorelación CREATE TABLE Trabajador( idTrabajador int PRIMARY KEY, Apellidos varchar(30) not null, Jefe int null ); ALTER TABLE Trabajador ADD CONSTRAINT fk_Trabajador_Trabajador FOREIGN KEY(Jefe) REFERENCES Trabajador; INSERT INTO INSERT INTO INSERT INTO INSERT INTO INSERT INTO INSERT INTO INSERT INTO commit;

Trabajador Trabajador Trabajador Trabajador Trabajador Trabajador Trabajador

VALUES(102, VALUES(101, VALUES(105, VALUES(103, VALUES(104, VALUES(107, VALUES(106,

'Ardiles Soto', NULL); 'Camacho Saravia', 102); 'Vilchez Santos', 102); 'Sánchez Aliaga', 101); 'Castro Avila', 101); 'Urrunaga Tapia', 101); 'Juárez Pinto', 105);

--Consulta que muestre una lista de trabajadores. La lista debe mostrar los apellidos del jefe de cada trabajador. SELECT T1.idTrabajador, T1.apellidos, T2.apellidos AS Jefe FROM Trabajador T1 LEFT OUTER JOIN Trabajador T2 ON T1.jefe = T2.idTrabajador;

Otra manera de escribir join: -- los productos que no registran salida tienen el valor NULL en CANTIDAD. --Las 2 consultas siguientes muestran resultados iguales: SELECT Producto.idProducto, Producto.nombre FROM Producto LEFT OUTER JOIN Guia_Detalle ON Producto.idProducto = Guia_Detalle.idProducto WHERE Guia_Detalle.cantidad IS NULL ORDER BY Producto.idProducto; SELECT Producto.idProducto, Producto.nombre FROM Producto, Guia_Detalle WHERE Producto.idProducto = Guia_Detalle.idProducto (+) AND Guia_Detalle.cantidad IS NULL ORDER BY Producto.idProducto;

-- el operador (+) va en el lado donde se buscan los nulos

Página 66

Autor: Ing. Núñez Marinovich Néstor Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación Operadores Union, Intersect, Union All, Minus: Se requiere que las consultas a las tablas referenciadas tengan el mismo número de columnas, los mismos tipos de datos, y que las columnas se encuentren en el mismo orden en la lista de cada uno de los SELECT. Se elimina las filas duplicadas en el resultado. Sin embargo, si usa la opción ALL, todas las filas (incluso las duplicadas) son incluidas en el resultado. Debe especificar los nombres de las columnas en la primera instrucción SELECT. Por consiguiente, si quiere definir los nuevos títulos de las columnas para el resultado, debe crear los seudónimos de las columnas en la primera instrucción SELECT. Si quiere que el resultado completo sea devuelto en un orden específico, debe especificar el orden e incluir la cláusula ORDER BY dentro de la sentencia UNION.

--Mostrar todos los documentos registrados (órdenes de compra y guías de remisión) SELECT fechaOrden AS "Fecha emisión", idOrden AS "Número documento", 'Orden de Compra' AS "Tipo documento" FROM Orden UNION SELECT fechaSalida, idGuia, 'Guía de Remisión' FROM Guia ORDER BY "Fecha emisión";

--Ejemplo con Union All, Intersect, Minus -- Crearemos la table Operario y Supervisores CREATE TABLE Operarios(idOperario varchar2(4),nombre varchar2(15) ); INSERT INTO Operarios VALUES( '0967', 'Antonio' ); INSERT INTO Operarios VALUES( '0245', 'Nancy' ); INSERT INTO Operarios VALUES( '0376', 'Carlos' ); INSERT INTO Operarios VALUES( '0879', 'Rosa' ); INSERT INTO Operarios VALUES( '0147', 'Marcos' ); commit; CREATE TABLE Supervisores(idSupervisor varchar2(4), nombre varchar2(15) ); INSERT INTO Supervisores VALUES( '0376', 'Carlos' ); INSERT INTO Supervisores VALUES( '0713', 'Gumercindo' ); commit;

--Devuelve la union de las 2 tablas sin duplicar los datos SELECT idSupervisor AS Empleado, nombre FROM Supervisores UNION SELECT idOperario, nombre FROM Operarios;

--Devuelve la union de las 2 tablas incluso las duplicadas SELECT idSupervisor AS Empleado, nombre FROM Supervisores UNION ALL SELECT idOperario, nombre FROM Operarios;

--INTERSECT entrega las filas que son comunes a las dos consultas. SELECT idSupervisor AS Empleado, nombre FROM Supervisores INTERSECT SELECT idOperario, nombre FROM Operarios;

--MINUS muestra las filas que aparecen en el primer conjunto, pero que no aparecen en el segundo conjunto. SELECT idOperario AS Empleado, nombre FROM Operarios MINUS SELECT idSupervisor, nombre FROM Supervisores;

Página 67

Autor: Ing. Núñez Marinovich Néstor Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación Subconsultas: Un subconsulta es una declaración SELECT anidada dentro una sentencia SELECT, INSERT, UPDATE o DELETE o dentro de otra subconsulta. Pueden entregar 1 valor o un conjunto de valores. --Lista de precios de todos los productos, y una columna adicional que muestra la diferencia entre el precio de cada -producto y el precio promedio de todos los productos. SELECT idProducto, nombre, precioUnitario, precioUnitario - (SELECT AVG(precioUnitario) FROM Producto) AS Diferencia FROM Producto;

-- Obtener una lista de los productos de la categoría 1 cuyo precio unitario es mayor al precio promedio de los -- productos de la categoría 6 SELECT idProducto, nombre, precioUnitario FROM Producto WHERE idCategoria = 1 AND precioUnitario > (SELECT avg(precioUnitario) FROM Producto WHERE idCategoria = 6);

-- Obtener una lista de los productos que no registran salida del almacén SELECT idProducto, nombre FROM Producto WHERE idProducto NOT IN (SELECT idProducto FROM Guia_Detalle);

--consulta que determine el porcentaje de unidades despachadas de cada producto de la categoría 4 respecto al total despachado de la categoría. SELECT Producto.idProducto, Producto.nombre, NVL(SUM(Guia_detalle.cantidad), 0)AS Despachado, CAST(NVL(SUM(Guia_detalle.cantidad), 0) AS number) / (SELECT SUM(cantidad) FROM Guia_detalle INNER JOIN Producto ON Guia_detalle.idProducto = Producto.idProducto WHERE Producto.idCategoria = 4) * 100 AS Porcentaje FROM Producto LEFT OUTER JOIN Guia_detalle ON Producto.idProducto = Guia_detalle.idProducto WHERE Producto.idCategoria = 4 GROUP BY Producto.idProducto, Producto.nombre;

--Escriba una consulta que entregue una lista de los productos que se despacharon en la fecha que se despachó la última salida del almacén. -- Tenga en cuenta que en dicha fecha se puede haber registrado más de una salida. SELECT DISTINCT Guia_detalle.idProducto, Producto.nombre FROM Guia_detalle INNER JOIN Producto ON Guia_detalle.idProducto = Producto.idProducto INNER JOIN Guia ON Guia_detalle.idGuia = Guia.idGuia WHERE Guia.fechaSalida = (SELECT MAX(fechaSalida) FROM Guia);

--Mostrar una lista de los productos que no registran salida del almacén. SELECT idProducto, nombre FROM Producto WHERE idProducto NOT IN (SELECT idProducto FROM Guia_detalle) ORDER BY idProducto;

--Mostra el nombre y precio de los productos cuyo precio unitario sea menor QUE ALGUNOS de los precios de la categoria 4 select nombre,precioUnitario from producto where precioUnitario < ANY(select distinct precioUnitario from producto where idCategoria=4);

--Mostra el nombre y precio de los productos cuyo precio unitario sea menor QUE TODOS los precios de la categoria 4 select nombre,precioUnitario from producto where precioUnitario < ALL(select distinct precioUnitario from producto where idCategoria=4);

Página 68

Autor: Ing. Núñez Marinovich Néstor Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación Subconsulta correlacionada: Se presenta cuando la consulta externa debe entregar datos a la consulta interna para que se pueda ejecutar. La consulta interna se evalúa repetidamente, una vez por cada fila de la consulta externa. Se puede definir en la cláusula WHERE de la consulta externa usando el operador EXISTS (Test de existencia). /* SUBCONSULTA CORRELACIONADA: se ejecuta cada vez que se compara los elementos con la consulta principal */ -- Productos que no registran salida del almacén SELECT Producto.idProducto, Producto.nombre FROM Producto WHERE NOT EXISTS (SELECT * FROM Guia_detalle WHERE Producto.idProducto = Guia_detalle.idProducto) ORDER BY Producto.idProducto;

Inserción de filas con datos leídos por SELECT: --Creamos la tabla Correo para realizar el ejemplo CREATE TABLE Correo( Nombre varchar2(50), Email varchar2(35) );

--Insertamos en la tabal correo una consulta select de la tabla Proveedor, el cual va a insertar el nombre y el correo que es una cadena que se construirade acuierdo a -- la primera letra de su nombre concatenado con su apelido y concatenada con la cadena '@marketperu.com' INSERT INTO Correo SELECT representante, LOWER( CONCAT( CONCAT( SUBSTR( representante, INSTR( representante, ',', 1, 1 )+2, 1 ), SUBSTR( representante,1, INSTR( representante, ' ', 1, 1 )-1 ) ), '@marketperu.com' ) ) FROM Proveedor; commit; select * from correo;

Vistas: Es un objeto que almacena una consulta predefinida y que proporciona un modo alternativo de visualización de datos sin tener que redefinir la consulta. Las vistas mejoran el rendimiento de las consultas ya que la instrucción SELECT asociada se guarda compilada y con su plan de ejecución ya definido. --Con el usuario system conceder privilegios necesarios para manipular vistas: GRANT CREATE VIEW, DROP ANY VIEW, TO MarketPERU;

--Crear Vista: CREATE VIEW v_ListaPrecios AS SELECT Categoria.categoria, Producto.idProducto, Producto.nombre, Producto.unidadMedida, Producto.precioUnitario FROM Producto INNER JOIN Categoria ON Producto.idCategoria = Categoria.idCategoria;

--Obtener definciion de una vista: DESCRIBE v_ListaPrecios;

--Eliminar una Vista: DROP VIEW v_ListaPrecios;

Ejemplo con WITH CHECK OPTION: -- Vista que lista de productos de la categoría 2 CREATE OR REPLACE VIEW v_MisProductos AS SELECT idProducto, idCategoria, idProveedor, Nombre, Descontinuado FROM Producto WHERE idCategoria = 2; . SELECT * FROM v_MisProductos; select * from Producto; Autor: Ing. Núñez Marinovich Néstor Manuel Página 69 Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación -- Insertando un producto a través de la vista INSERT INTO v_MisProductos VALUES(139,1, 14, 'Chocolate Bitter Delicioso', 1); commit;

--El producto insertado no podra ser mostrado en la vista debido a que esta filtra para los productos de la categoría 2, pero si en la tabla producto. --Crearemos otra versión de la vista, pero que no permita hacer mantenimiento de los productos que no correspondan al filtro definido. Para ello, haremos uso de WITH CHECK OPTION. -- Creando una vista con WITH CHECK OPTION CREATE OR REPLACE VIEW v_MisProductos_CHECK AS SELECT idProducto, idCategoria, idProveedor,Nombre, Descontinuado FROM Producto WHERE idCategoria = 2 WITH CHECK OPTION;

-- Consultando la vista SELECT * FROM v_MisProductos_CHECK;

-- Insertando un producto que viola el filtro de la última vista INSERT INTO v_MisProductos_CHECK VALUES(140, 1, 14, 'Chocolate Bitter c/almendras', 0);

Bloque anónimo: Es la unidad básica de programación en PL/SQL. Ejemplo: DECLARE vFecha VARCHAR2(40); BEGIN SELECT TO_CHAR(SYSDATE, 'Day, DD "de" Month "de" YYYY', 'NLS_DATE_LANGUAGE=Spanish') INTO vFecha FROM DUAL; dbms_output.put_line('Hoy es: ' || vFecha); END;

--es necesario habilitar la salida ejecutando la instrucción set serveroutput on.

Declaracion de variables. %TYPE: Este operador permite declarar una variable del mismo tipo que otra variable, constante ó columna. DECLARE vNombre varchar2(20); nEdad number := 18; dFechaIngreso date := '15/11/2001'; dFechaContrato Empleado.fechaContrato%TYPE;

Asignacion de valores a variables: vNombre := 'Mónica'; nMonto := fnMontoGuia(87); SELECT SUM(precioVenta * cantidad) INTO nMonto FROM Guia_detalle WHERE idGuia = nGuia;

Página 70

Autor: Ing. Núñez Marinovich Néstor Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación Estructuras de control de flujo Condicional IF: Sintaxis IF (expresión_lógica) THEN ... END IF;

IF (expresión_lógica) THEN ... ELSE ... END IF;

IF (expresión_lógica1) THEN ... ELSEIF (expresión_lógica2) THEN ... ELSEIF (expresión_lógica3) THEN ... [ ELSE ... ] END IF;

Ejemplo: --Muestra el mensaje si hay suficiente stock, si hay que reponer mercaderia o si esta cercano al valor minimo del stock del producto. --Adicionalmente tambien valida si existe o no el producto DECLARE nActual Producto.stockActual%TYPE; nMinimo Producto.stockMinimo%TYPE; vMensaje VARCHAR2(50); vMensaje2 VARCHAR2(50); nProducto int:=27; nAux int; BEGIN select count(*) into nAux from Producto WHERE idProducto = nProducto; if (nAux>0) THEN --si existe el producto SELECT stockActual, stockMinimo INTO nActual, nMinimo FROM Producto WHERE idProducto = nProducto; vMensaje2:=chr(13) || 'Actual: ' ||nActual || chr(13) || 'Minimo: ' ||nMinimo; IF (nActual < nMinimo) THEN vMensaje := 'Hay que reponer mercadería'; ELSIF (nActual > nMinimo) AND (nActual < nMinimo*1.1) THEN vMensaje := 'Se está cerca al stock mínimo.'; ELSE vMensaje := 'Hay suficiente stock'; END IF; else -- no existe el producto vMensaje := 'El producto no existe.'; end if;

dbms_output.put_line(vMensaje||vMensaje2); END;

Condicional CASE: Sintaxis CASE selector WHEN valor1 THEN ... WHEN valor2 THEN ... ... [ ELSE ... ] END CASE;

Página 71

CASE WHEN expresión_lógica1 THEN ... WHEN expresión_lógica2 THEN ... ... [ ELSE ... ] END CASE; Autor: Ing. Núñez Marinovich Néstor Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación --La siguiente consulta muestra una lista de proveedores con una columna computada cuyo valor depende del valor encontrado en la columna departamento de la tabla Proveedor. SELECT idProveedor, nombre, CASE departamento WHEN 'LIMA' THEN 'Flete muy bajo' WHEN 'LA LIBERTAD' THEN 'Flete bajo' WHEN 'LAMBAYEQUE' THEN 'Flete moderado' WHEN 'AREQUIPA' THEN 'Flete medio' ELSE 'Flete alto' END CASE FROM Proveedor;

--La siguiente consulta califica el nivel de las unidades despachadas de los productos de la categoría 2. SELECT Producto.idProducto, Producto.nombre, CASE WHEN SUM(Guia_detalle.cantidad) < 200 THEN 'Nivel muy bajo, < 200 unidades' WHEN SUM(Guia_detalle.cantidad) >= 200 AND SUM(Guia_detalle.cantidad) < 350 THEN 'Nivel bajo, 200 <= unidades < 350' WHEN SUM(Guia_detalle.cantidad) >= 350 AND SUM(Guia_detalle.cantidad) < 500 THEN 'Nivel medio, 350 <= unidades < 500' WHEN SUM(Guia_detalle.cantidad) >= 500 AND SUM(Guia_detalle.cantidad) < 750 THEN 'Nivel alto, 500 <= unidades < 750' WHEN SUM(Guia_detalle.cantidad) >= 750 THEN 'Nivel muy alto, >= 750 unidades' END CASE FROM Producto INNER JOIN Guia_detalle ON Producto.idProducto = Guia_detalle.idProducto WHERE Producto.idCategoria = 2 GROUP BY Producto.idProducto, Producto.nombre;

--La siguiente función establece si el precio del producto X está por encima ó por debajo del precio promedio de todos los productos. CREATE OR REPLACE FUNCTION fnPrecioAltoBajo( nProducto Producto.idProducto%TYPE) RETURN VARCHAR2 IS vMensaje VARCHAR2(50); nPrecio Producto.precioUnitario%TYPE; nPromedio Producto.precioUnitario%TYPE; BEGIN SELECT AVG(precioUnitario) INTO nPromedio FROM Producto; SELECT precioUnitario INTO nPrecio FROM Producto WHERE idProducto = nProducto; CASE WHEN (nPrecio > nPromedio) THEN vMensaje := 'Precio por encima del promedio'; WHEN (nPrecio = nPromedio) THEN vMensaje := 'Precio promedio'; WHEN (nPrecio < nPromedio) THEN vMensaje := 'Precio por debajo del promedio'; END CASE; vMensaje := 'Producto ' || to_char(nProducto) || ' ' || to_char(nPrecio) || ' - ' || vMensaje; RETURN vMensaje; END; /

Página 72

Autor: Ing. Núñez Marinovich Néstor Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación Bucle LOOP: Permite ejecutar un conjunto de instrucciones en forma repetida. El número de repeticiones se controla mediante un condicional definido en el bloque del bucle.

Sintaxis:

LOOP ... IF (expresión_lógica) THEN ... EXIT; END IF; ... EXIT WHEN(expresión_lógica); ... END LOOP;

--Calcular el factorial de un numero: DECLARE n_Numero int:=5; n_Resultado int; v_Resultado VARCHAR2(50); BEGIN n_Resultado :=1; v_Resultado:= 'El factorial de ' ||to_char( n_Numero) ||' es:' ; LOOP n_Resultado:=n_Resultado*n_Numero; n_Numero:=n_Numero-1; EXIT WHEN (n_Numero=1); END LOOP; v_Resultado:= v_Resultado ||to_char(n_Resultado); dbms_output.put_line(v_Resultado); END;

Bucle WHILE: Permite ejecutar un conjunto de instrucciones en forma repetida. La ejecución del bucle se controla evaluando una expresión lógica antes del inicio de cada una de las repeticiones.

Sintáxis WHILE (expresión_lógica) LOOP ... END LOOP;

--Calcular el factorial de un numero: DECLARE n_Numero int:=6; n_Resultado int; v_Resultado VARCHAR2(50); BEGIN n_Resultado :=1; v_Resultado:= 'El factorial de ' ||to_char( n_Numero) ||' es:' ; WHILE (n_Numero>1) LOOP n_Resultado:=n_Resultado*n_Numero; n_Numero:=n_Numero-1; END LOOP; v_Resultado:= v_Resultado ||to_char(n_Resultado); dbms_output.put_line(v_Resultado); END;

Página 73

Autor: Ing. Núñez Marinovich Néstor Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación El bucle FOR: Permite ejecutar un conjunto de instrucciones en forma repetida estableciendo de antemano el número de repeticiones a ejecutar.

Sintáxis

FOR contador IN [ REVERSE ] límite_inferior .. límite_superior LOOP ... END LOOP;

--Calcular el factorial de un numero: DECLARE n_Numero int:=5; n_Resultado int; v_Resultado VARCHAR2(50); BEGIN n_Resultado :=1; v_Resultado:='El factorial de ' ||to_char( n_Numero)||' es:' ; FOR nContador IN 1 .. n_Numero LOOP n_Resultado:=n_Resultado*nContador; END LOOP; v_Resultado:= v_Resultado ||to_char(n_Resultado); dbms_output.put_line(v_Resultado); END;

De modo predeterminado, el valor de la variable de control se incrementa después de la ejecución de cada repetición hasta llegar al límite superior del rango. La cláusula REVERSE hace que la variable de control se inicie en el límite superior y su valor disminuya en uno luego de cada repetición hasta llegar al límite inferior. --Calcular el factorial de un numero: DECLARE nFactor int:=5; nContador int; vTexto VARCHAR2(50); BEGIN FOR nContador IN REVERSE 1..12 LOOP vTexto := nFactor || ' x ' || nContador || ' = ' || (nFactor * nContador); dbms_output.put_line(vTexto); END LOOP; END;

Mostrará como resultado: 5 x 12 = 60 5 x 11 = 55 5 x 10 = 50 5 x 9 = 45 5 x 8 = 40 5 x 7 = 35 5 x 6 = 30 5 x 5 = 25 5 x 4 = 20 5 x 3 = 15 5 x 2 = 10 5x1=5

Procedimientos Un procedimiento es un conjunto de instrucciones precompiladas almacenadas en la base de datos. Debido a que los procedimientos son precompilados, por lo general ofrecen mejor desempeño que cualquier consulta. Sintáxis CREATE [OR REPLACE] PROCEDURE nombre_procedimiento( parámetro1 [ modo_parámetro1 ] tipo_dato1, parámetro2 [ modo_parámetro2 ] tipo_dato2, ...) IS | AS ... BEGIN ... EXCEPTIONS ... END; modo_parámetro1, modo_parámetro2: Indica si el parámetro es de entrada (IN), de salida (OUT) ó de entrada-salida (IN OUT). El modo predeterminado es IN.

Página 74

Autor: Ing. Núñez Marinovich Néstor Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación Ejemplo1 – Procedimientos que recibe un parametro: --Procedimiento que recibe un parámetro: id del producto y muestra el nombre del producto, stock minimo y actual. CREATE OR REPLACE PROCEDURE prStockProducto( nProducto Producto.idProducto%TYPE) IS vProducto Producto.nombre%TYPE; nActual Producto.stockActual%TYPE; nMinimo Producto.stockMinimo%TYPE; BEGIN SELECT nombre, stockActual, stockMinimo INTO vProducto, nActual, nMinimo FROM Producto WHERE idProducto = nProducto; dbms_output.put_line('Producto: ' || vProducto); dbms_output.put_line('Stock Actual: ' || nActual); dbms_output.put_line('Stock Minimo: ' || nMinimo); END; /

--Ejecutamos el procedimiento: EXECUTE prStockProducto(50);

Ejemplo 2 – Procedimientos que recibe parametros: --Crear un procedimiento que entregue el monto total despachado ingresando mes y año CREATE OR REPLACE PROCEDURE prMontoMes(nMes NUMBER, nAño NUMBER) AS nMonto Guia_detalle.precioVenta%TYPE; BEGIN SELECT SUM(Guia_detalle.cantidad *Guia_detalle.precioVenta) INTO nMonto FROM Guia_detalle INNER JOIN Guia ON Guia_detalle.idGuia = Guia.idGuia WHERE EXTRACT(YEAR FROM Guia.fechaSalida) = nAño AND EXTRACT(MONTH FROM Guia.fechaSalida) = nMes; dbms_output.put_line('Periodo: Mes ' || nMes|| ' del ' || nAño); dbms_output.put_line('Monto: ' || nMonto); END; /

--Ejecutamos el procedimiento: DECLARE mes NUMBER := 9; año NUMBER := 2011; BEGIN prMontoMes(mes, año); END;

Ejemplo 3 – Procedimiento que recibe y entrega parametros: --Crear un procedimiento que devuelva el total de unidades ingresadas y total de unidades salientes ingresando id producto CREATE OR REPLACE PROCEDURE prBalanceProducto( nProducto Producto.idProducto%TYPE, nEntradas OUT Orden_detalle.cantidadRecibida%TYPE, nSalidas OUT Guia_detalle.cantidad%TYPE) IS BEGIN SELECT SUM(cantidadRecibida) INTO nEntradas FROM Orden_detalle WHERE idProducto = nProducto; SELECT SUM(cantidad) INTO nSalidas FROM Guia_detalle WHERE idProducto = nProducto; END; /

Página 75

Autor: Ing. Núñez Marinovich Néstor Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación --Ejecutamos el procedimiento: DECLARE entradas NUMBER; salidas NUMBER; producto NUMBER := 2; BEGIN prBalanceProducto(producto, entradas, salidas); dbms_output.put_line('Producto: ' || producto); dbms_output.put_line('Entradas: ' || entradas || ' unidades'); dbms_output.put_line('Salidas: ' || salidas || ' unidades'); END;

Ejemplo 4 – Procedimiento con parámetro IN OUT --Crear un procedimiento que reciba como parámetro una cadena formada por dígitos que representa un número telefónico y que devuelva la cadena con formato. CREATE OR REPLACE PROCEDURE prFormatoTelefono(vTelefono IN OUT VARCHAR2) AS nLongitud NUMBER; BEGIN nLongitud := LENGTH(vTelefono); IF (nLongitud = 7) THEN vTelefono := SUBSTR(vTelefono, 1, 3) || '-' || SUBSTR(vTelefono, 4); ELSE vTelefono := SUBSTR(vTelefono, 1, 4) || '-' || SUBSTR(vTelefono, 5); END IF; END; /

--Ejecutamos el procedimiento: DECLARE vFono VARCHAR2(10) := '949383634'; BEGIN prFormatoTelefono(vFono); dbms_output.put_line(vFono); END;

Registro (Record): El registro es una estructura de datos que puede almacenar datos de distinto tipo. Sintáxis TYPE tipo_registro IS RECORD ( campo1 tipo1 [NOT NULL] [:= valor1], campo2 tipo2 [NOT NULL] [:= valor2], ... ); nombre_variable_registro tipo_registro

Ejemplo: --Creacion del registro: TYPE regProducto IS RECORD( precio Producto.precioUnitario%type, unidad Producto.unidadMedida%type, stock Producto.stockActual%type);

--Declaracion de un registro: miProducto regProducto;

--Acceso a los campos de un registro: dbms_output.put_line( miProducto.precio ); dbms_output.put_line( miProducto.unidad ); dbms_output.put_line( miProducto.stock );

Página 76

Autor: Ing. Núñez Marinovich Néstor Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación Procedimiento que utiliza un registro: --Procedimiento que devuelve el precio, la unidad de medida y el stock del producto ingresando el id del producto CREATE OR REPLACE PROCEDURE prDatosProducto( nProducto Producto.idProducto%Type) IS TYPE regProducto IS RECORD( precio Producto.precioUnitario%TYPE, unidad Producto.unidadMedida%TYPE, stock Producto.stockActual%TYPE); miProducto regProducto; BEGIN SELECT precioUnitario, unidadMedida, stockActual INTO miProducto FROM Producto WHERE idProducto = nProducto; dbms_output.put_line('Precio: ' || miProducto.precio); dbms_output.put_line('Unidad: ' || miProducto.unidad); dbms_output.put_line('Stock : ' || miProducto.stock); END; /

--Ejecutamos el procedimiento: EXECUTE prDatosProducto(12);

Operador %ROWTYPE: Declara en forma implícita un registro que tiene la misma estructura que una fila de una tabla. Los campos del registro tienen el mismo nombre que las columnas correspondientes en la tabla. Sintáxis nombre_variable_registro nombre_tabla%ROWTYPE

Ejemplo: --Crear un procedimiento que permita obtener los datos de un proveedor ingresando su id CREATE OR REPLACE PROCEDURE prDatosProveedor(nProveedor Proveedor.idProveedor%TYPE) IS regProveedor Proveedor%ROWTYPE; BEGIN SELECT * INTO regProveedor FROM Proveedor WHERE idProveedor = nProveedor; dbms_output.put_line('Nombre: '|| regProveedor.nombre); dbms_output.put_line('Representante: '|| regProveedor.representante ); END; /

--Ejecutamos el procedimiento. EXECUTE prDatosProveedor(5);

Paso de los parámetros Por Referencia: los valores de los parámetros pueden especificarse en cualquier orden, y puede omitir parámetros que permiten valores nulos o que tienen un valor por defecto. [ EXECUTE ] nombre_procedimiento [ parámetro => valor ], [ parámetro => valor ], ...

Por Posición: los valores de los parámetros se listan en el orden en que se definieron en la sentencia CREATE PROCEDURE. Sintáxis [ EXECUTE ] nombre_procedimiento [ valor1 [ , valor2 ] , ... ]

Página 77

Autor: Ing. Núñez Marinovich Néstor Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación Ejemplo: --Creamos una tabla de prueba CREATE TABLE PruebaParametros( codigo NUMBER NOT NULL, nombre VARCHAR2(15) NOT NULL, cargo VARCHAR2(20) NULL );

--Creamos un procedimiento que permita insertar filas en la tabla. CREATE OR REPLACE PROCEDURE prAgregarFila( nCodigo IN PruebaParametros.codigo%TYPE DEFAULT 0, vNombre IN PruebaParametros.nombre%TYPE DEFAULT 'Desconocido', vCargo IN PruebaParametros.cargo%TYPE DEFAULT 'Desconocido') AS BEGIN INSERT INTO PruebaParametros VALUES(nCodigo, vNombre, vCargo); commit; END; /

-- Invocamos al procedimiento de distintas maneras: -- Sin pasar parámetros EXECUTE prAgregarFila;

-- Pasando los parámetros por posición EXECUTE prAgregarFila(1, 'Juan', 'Asistente');

-- Pasando los parámetros por referencia EXECUTE prAgregarFila(vNombre => 'Rosa', vCargo => 'Jefe', nCodigo => 2);

-- Pasando solo un parámetro (por posición) EXECUTE prAgregarFila(3);

-- Pasando un solo parámetro (por referencia) EXECUTE prAgregarFila(vNombre => 'Antonio');

--Mostrar la tabla con los valores insertados SELECT * FROM PruebaParametros;

Procedimiento que llama a otro procedimiento: CREATE OR REPLACE PROCEDURE esPrimo(nNumero int) AS nContador int; vResultado varchar2(50); BEGIN vResultado :=' Si es número primo.'; for nContador IN 2 .. nNumero-1 loop if (mod(nNumero,nContador)=0) then vResultado :=' No es número primo.'; exit ; end if ; end loop; dbms_output.put_line(nNumero || vResultado); END; / EXECUTE esPrimo(9); CREATE OR REPLACE PROCEDURE listaNumerosPrimos(nNumero int) AS nContador int; BEGIN for nContador IN 2 .. nNumero loop esPrimo(nContador); end loop; END;

Resultado: 2 Si es número primo. 3 Si es número primo. 4 No es número primo. 5 Si es número primo. 6 No es número primo. 7 Si es número primo. 8 No es número primo. 9 No es número primo. 10 No es número primo. 11 Si es número primo. 12 No es número primo. 13 Si es número primo. 14 No es número primo. 15 No es número primo. 16 No es número primo. 17 Si es número primo. 18 No es número primo. 19 Si es número primo. 20 No es número primo. PL/SQL procedure successfully completed. completed.

EXECUTE listaNumerosPrimos(20);

Página 78

Autor: Ing. Núñez Marinovich Néstor Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación Excepciones: Son errores producidos durante la ejecución de un programa Sintáxis DECLARE ... BEGIN ... EXCEPTION WHEN nombre_excepción1 THEN ... WHEN nombre_execpción1 THEN ... WHEN OTHERS THEN ... END;

Excepciones predefinidas Excepción VALUE_ERROR NO_DATA_FOUND TOO_MANY_ROWS INVALID_CURSOR CURSOR_ALREADY_OPEN

Descripción Se presenta cuando existe conflicto de tipos de datos. Ocurre cuando una instrucción SELECT no retorna filas. Ocurre cuando una instrucción SELECT retorna más de una fila. Se presenta cuando se hace referencia a un cursor que está cerrado. Se presenta cuando se trata de abrir un cursor abierto.

Ejemplo 1: uso de Exception --Obtener el precio ingresando id del producto CREATE OR REPLACE PROCEDURE prPrecioProducto( nProducto IN Producto.idProducto%TYPE, nPrecio OUT Producto.precioUnitario%TYPE) AS BEGIN SELECT precioUnitario INTO nPrecio FROM Producto WHERE idProducto = nProducto; EXCEPTION WHEN NO_DATA_FOUND THEN dbms_output.put_line ('El producto especificado no existe.'); END; /

--Ejecutamos el procedimiento. DECLARE precio Producto.precioUnitario%TYPE := 0; BEGIN prPrecioProducto(0, precio); dbms_output.put_line('Precio: ' || precio); END;

Ejemplo 2: Uso de RAISE --Procedimiento que devuelve la cantidad de despachos efectuados de un determinado mes y año. CREATE OR REPLACE PROCEDURE prDespachosMes(nMes IN NUMBER, nAño IN NUMBER, nDespachos OUT NUMBER) IS BEGIN SELECT COUNT(idGuia) INTO nDespachos FROM Guia WHERE EXTRACT(YEAR FROM fechaSalida) = nAño AND EXTRACT(MONTH FROM fechaSalida) = nMes; IF (nDespachos = 0) THEN

--RAISE genera un mensaje de error que se le envía al usuario. RAISE NO_DATA_FOUND; END IF; EXCEPTION WHEN NO_DATA_FOUND THEN

Página 79

Autor: Ing. Núñez Marinovich Néstor Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación dbms_output.put_line('Data no encontrada.'); END; /

--Ejecutamos el procedimiento. DECLARE despachos NUMBER; BEGIN prDespachosMes(7, 2000, despachos); dbms_output.put_line('Despachos: ' || despachos); END; /

Ejemplo 3: Excepciones de usuario --Procedimiento que devuelve la cantidad de despachos efectuados de un determinado mes y año. CREATE OR REPLACE PROCEDURE prDespachosMes2(nMes IN NUMBER,nAño IN NUMBER,nDespachos OUT NUMBER) IS no_hay_despachos EXCEPTION;--excepción de usuario, definida por el programador con un nombre propio BEGIN SELECT COUNT(idGuia) INTO nDespachos FROM Guia WHERE EXTRACT(YEAR FROM fechaSalida) = nAño AND EXTRACT(MONTH FROM fechaSalida) = nMes; IF (nDespachos = 0) THEN RAISE no_hay_despachos; END IF; EXCEPTION WHEN no_hay_despachos THEN dbms_output.put_line('Data no encontrada.'); END; /

--Ejecutamos el procedimiento. DECLARE despachos NUMBER; BEGIN prDespachosMes2(5, 2005, despachos); dbms_output.put_line('Despachos: ' || despachos); END;

Ejemplo 4: Uso de RAISE_APPLICATION_ERROR --Procedimiento que devuelve la cantidad de despachos efectuados de un determinado mes y año. CREATE OR REPLACE PROCEDURE prDespachosMes3(nMes IN NUMBER,nAño IN NUMBER,nDespachos OUT NUMBER) IS BEGIN SELECT COUNT(idGuia) INTO nDespachos FROM Guia WHERE EXTRACT(YEAR FROM fechaSalida) = nAño AND EXTRACT(MONTH FROM fechaSalida) = nMes; IF (nDespachos = 0) THEN

--RAISE_APPLICATION_ERROR sirve para levantar errores y definir mensajes de error. Su formato es el siguiente: --RAISE_APPLICATION_ERROR(numero_error,mensaje_error); RAISE_APPLICATION_ERROR(-20000,'Data no encontrada.'); END IF; END; /

--Ejecutamos el procedimiento. DECLARE despachos NUMBER; BEGIN prDespachosMes3(08, 2000, despachos); dbms_output.put_line('Despachos: ' || despachos); END;

Página 80

Autor: Ing. Núñez Marinovich Néstor Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación Ejemplo 5: Captura del número y mensaje de error: --Procedimiento que devuelve la cantidad de despachos efectuados de un determinado mes y año. CREATE OR REPLACE PROCEDURE prDespachosMes4(nMes IN NUMBER,nAño IN NUMBER,nDespachos OUT NUMBER) IS BEGIN SELECT COUNT(idGuia) INTO nDespachos FROM Guia WHERE EXTRACT(YEAR FROM fechaSalida) = nAño AND EXTRACT(MONTH FROM fechaSalida) = nMes; IF (nDespachos = 0) THEN RAISE_APPLICATION_ERROR(-20000,'Data no encontrada.'); END IF; EXCEPTION WHEN OTHERS THEN dbms_output.put_line('Error # ORA' ||TO_CHAR(SQLCODE)); dbms_output.put_line(SQLERRM); END; /

--Ejecutamos el procedimiento. DECLARE despachos NUMBER; BEGIN prDespachosMes4(5, 2000, despachos); dbms_output.put_line('Despachos: ' || despachos); END;

Funciones: Son rutinas que aceptan parámetros, ejecutan un proceso, y retornan el resultado del proceso como un valor. Sintáxis CREATE [OR REPLACE] FUNCTION nombre_función( parámetro1 [ modo_parámetro1 ] tipo_dato1, parámetro2 [ modo_parámetro2 ] tipo_dato2, ...) RETURN tipo_dato_valor_retorno IS | AS ... BEGIN ... EXCEPTIONS ... END;

Ejemplo. --Funcion que retorna el monto ingresando idGuia CREATE OR REPLACE FUNCTION fnMontoGuia(nGuia NUMBER) RETURN NUMBER IS nMonto NUMBER; BEGIN SELECT SUM(precioVenta * cantidad) INTO nMonto FROM Guia_detalle WHERE idGuia = nGuia; RETURN nMonto; END; /

--Ejecutamos la funcion SELECT fnMontoGuia(87) FROM DUAL;

Página 81

Autor: Ing. Núñez Marinovich Néstor Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación Transacciones: Son un conjunto de modificaciones de datos (operaciones) que debe ser procesado

como una unidad. El motor de base de datos utiliza los bloqueos como un mecanismo para garantizar las transacciones y mantener la consistencia de la base de datos cuando muchos usuarios acceden simultáneamente a ella. Deben de cumplir 4 propiedades fundamentales: Atomicidad, Cohesion, Aislamiento y Durabilidad

Inicio de una Transacción: Se inicia con la primera instrucción DML Finalización de una Transacción: -

La ejecución de una instrucción COMMIT (Confirmacion de la transacción)

-

La ejecución de una instrucción ROLLBACK (Cancela al transacción).

-

La ejecución de una sentencia DDL, por ejemplo ALTER VIEW.

-

La ejecución de una instrucción DCL, por ejemplo GRANT.

-

La finalización de la sesión.

-

La caída del sistema.

Ejemplo: CREATE TABLE PruebaBatch(ColA NUMBER PRIMARY KEY,ColB VARCHAR2(3) NOT NULL); INSERT INTO PruebaBatch VALUES(1, 'AAA'); INSERT INTO PruebaBatch VALUES(2, 'BBB'); INSERT INTO PruebaBatch VALUES(3, 'CCC'); rollback;--rechazar la transaccion select * from PruebaBatch; INSERT INTO PruebaBatch VALUES(1, 'AAA'); INSERT INTO PruebaBatch VALUES(2, 'BBB'); INSERT INTO PruebaBatch VALUES(3, 'CCC'); commit; --confirmacion de la transaccion select * from PruebaBatch;

Trigger: (Disparadores, desencadenantes) Desencadenantes a nivel de tabla (desencadenantes DML): se ejecutan cuando una declaración DML (Data Manipulation Language) como INSERT, UPDATE ó DELETE ocurre en la base de datos.

Desencadenantes a nivel de esquema (desencadenantes DDL): se disparan al ejecutarse las siguientes declaraciones DDL (Data Definition Language): CREATE ó ALTER.

Desencadenantes DML: Un desencadenante es definido específicamente para una tabla ó vista, y para ser ejecutado automáticamente cuando se produce una inserción, actualización o eliminación de filas. A diferencia de los procedimientos, un desencadenante no puede ser llamado directamente, y no acepta o retorna parámetros.

Página 82

Autor: Ing. Núñez Marinovich Néstor Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación -- Crear tablas MAESTRO-DETALLE CREATE TABLE Factura( IdFactura NUMBER PRIMARY KEY, FecFactura DATE DEFAULT SYSDATE, Cliente VARCHAR2(30) NOT NULL, MontoFactura NUMBER NULL ); CREATE TABLE DetalleFactura( IdFactura NUMBER NOT NULL, IdProducto NUMBER NOT NULL, PrecioUnitario NUMBER NOT NULL, Cantidad NUMBER NOT NULL );

ALTER TABLE DetalleFactura ADD CONSTRAINT pk_DetalleFactura PRIMARY KEY( IdFactura, IdProducto ); ALTER TABLE DetalleFactura ADD CONSTRAINT fk_DetalleFactura_Factura FOREIGN KEY( IdFactura ) REFERENCES Factura;

ALTER SESSION SET NLS_DATE_FORMAT = 'DD/MM/YYYY'; INSERT INTO Factura VALUES( 1, '31/10/2005', 'Comercial Gómez', NULL ); INSERT INTO Factura VALUES( 2, '02/11/2005', 'Juan López Cordero', NULL ); INSERT INTO DetalleFactura VALUES( 1, 101, 12.5, 100 ); INSERT INTO DetalleFactura VALUES( 1, 127, 15, 50 ); INSERT INTO DetalleFactura VALUES( 1, 107, 10, 50 ); INSERT INTO DetalleFactura VALUES( 2, 132, 15.5, 100 ); INSERT INTO DetalleFactura VALUES( 2, 107, 10, 250 ); UPDATE Factura SET montoFactura = 2500 WHERE idFactura = 1; UPDATE Factura SET montoFactura = 4050 WHERE idFactura = 2; commit;

Ejemplo: Desencadenante BEFORE CREATE OR REPLACE TRIGGER tg_insert_DetalleFactura BEFORE INSERT ON DetalleFactura FOR EACH ROW--FOR EACH ROW indica que en el desencadenante se debe disparar por cada una de las filas

afectadas, --WHEN indica una condición que se debe verificar para que el desencadenante se dispare. WHEN (new.idFactura > 0)--new.columna : hace referencia a los valores de la nueva fila DECLARE suma NUMBER; BEGIN

--Este desencadenante calcula primero el monto de la factura hasta ANTES de la inserción del nuevo detalle de la factura. SELECT SUM(cantidad * precioUnitario) INTO suma FROM DetalleFactura WHERE idFactura = :new.idFactura;

--Luego, al monto calculado le suma el monto del nuevo detalle de factura. suma := suma + (:new.cantidad * :new.precioUnitario);

--Finalmente, actualiza el nuevo monto en la factura correspondiente en la tabla Factura. UPDATE Factura SET montoFactura = suma WHERE idFactura = :new.idFactura; END;

-- Registrando la factura 3 INSERT INTO Factura VALUES( 3, '02/11/2005', 'Rep. Asunción', NULL );

-- Probando el desencadenante INSERT INTO DetalleFactura VALUES( 3, 101, 12.5, 100 ); INSERT INTO DetalleFactura VALUES( 3, 127, 15, 100 ); INSERT INTO DetalleFactura VALUES( 3, 107, 10, 100 ); commit;

-- Verificando la data SELECT * FROM DetalleFactura; SELECT * FROM Factura;

Página 83

Autor: Ing. Núñez Marinovich Néstor Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación Ejemplo: Desencadenante AFTER CREATE OR REPLACE TRIGGER tg_Factura AFTER INSERT OR DELETE OR UPDATE ON Factura BEGIN IF INSERTING THEN dbms_output.put_line('Se ha creado una nueva factura.'); END IF; IF DELETING THEN dbms_output.put_line('Se ha eliminado la factura.'); END IF; IF UPDATING THEN dbms_output.put_line('La factura se ha modificado.'); END IF; END;

--Prueba: Registrando la factura 4 INSERT INTO Factura VALUES( 4, '24/12/2005', 'Comercial Santa Claus', NULL );

Desencadenantes DCL: Se dispara en respuesta a la ejecución de una sentencia DDL. Puede ser usado para ejecutar tareas administrativas en la base de datos, tales como auditoría y control de las operaciones de bases de datos.

CREATE OR REPLACE TRIGGER tr_Elimina_Objeto BEFORE DROP ON MarketPeru.Schema BEGIN RAISE_APPLICATION_ERROR(-20000, 'No puede eliminar el objeto.'); END;

-- Tratando de eliminar la tabla DetalleFactura DROP TABLE DetalleFactura;

Cursores: Un cursor es un elemento de SQL que permite recorrer un conjunto de filas, y procesarlas una por una. Sintaxis: DECLARE CURSOR nombre_cursor IS sentencia_select; --Declaracion del cursor OPEN nombre_cursor; --Apertura del cursor FETCH nombre_cursor INTO lista_variables_o_registro; --Lectura del cursor CLOSE nombre_cursor; --Cierre del cursor

Atributo

%Found %NotFound %RowCount %IsOpen

Descripción Retorna TRUE si la última instrucción FETCH se llevó a cabo con éxito; es decir, recuperó una fila. Retorna TRUE si la última instrucción FETCH no tuvo éxito. Retorna la cantidad de filas extraídas del cursor. Retorna TRUE si el cursor está abierto. En caso contrario, retorna FALSE.

--Procedimiento 1 que extrae todas las filas de un CURSOR CREATE OR REPLACE PROCEDURE prTodasCategorias1 IS CURSOR cursorCategorias IS SELECT * FROM Categoria; regCategoria Categoria%rowtype; BEGIN

Página 84

Autor: Ing. Núñez Marinovich Néstor Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación OPEN cursorCategorias;

dbms_output.put_line('Código - Nombre - Detalle'); LOOP FETCH cursorCategorias INTO regCategoria; EXIT WHEN cursorCategorias%NotFound; dbms_output.put_line(regCategoria.idCategoria||' - '||regCategoria.categoria||' - '|| regCategoria.descripcion); END LOOP; CLOSE cursorCategorias; END; / execute prTodasCategorias1;

--Procedimiento 2 que extrae todas las filas de un CURSOR CREATE OR REPLACE PROCEDURE prTodasCategorias2 IS CURSOR cursorCategorias IS SELECT * FROM Categoria; regCategoria Categoria%rowtype; BEGIN OPEN cursorCategorias; dbms_output.put_line('Código - Nombre - Detalle'); FETCH cursorCategorias INTO regCategoria; WHILE cursorCategorias%NotFound LOOP dbms_output.put_line(regCategoria.idCategoria||' - '||regCategoria.categoria||' - '|| regCategoria.descripcion); FETCH cursorCategorias INTO regCategoria; END LOOP; CLOSE cursorCategorias; END; / execute prTodasCategorias2;

--Procedimiento 3 que extrae todas las filas de un CURSOR CREATE OR REPLACE PROCEDURE prTodasCategorias3 IS CURSOR cursorCategorias IS SELECT * FROM Categoria; BEGIN dbms_output.put_line('Código - Nombre - Detalle'); FOR registro IN cursorCategorias LOOP dbms_output.put_line(registro.idCategoria||' - '||registro.categoria||' - '|| registro.descripcion); END LOOP; END; / execute prTodasCategorias3;

SQL Dinámico: Permite crear y ejecutar sentencias SQL en tiempo de ejecución. Ejemplo: CREATE OR REPLACE PROCEDURE prEjecutaSQLDinamico(vComando VARCHAR2) IS BEGIN EXECUTE IMMEDIATE vComando; END; / EXECUTE prEjecutaSQLDinamico('CREATE TABLE PruebaSQLDinamico(codigo NUMBER, nombre VARCHAR2(15))'); EXECUTE prEjecutaSQLDinamico('INSERT INTO PruebaSQLDinamico VALUES(101, ''Rosa'')'); SELECT * FROM PruebaSQLDinamico;

Página 85

Autor: Ing. Núñez Marinovich Néstor Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación Paquetes (PACKAGE): Permite almacenar definiciones de variables, tipos, procedimientos y funciones

que están relacionados como una sola unidad. Consta de 2 partes:

Especificación del paquete: Es la interfaz del paquete y contiene las declaraciones de variables, constantes, tipos, cursores, excepciones y subprogramas a las que se puede hacer referencia desde fuera del paquete. Sintáxis CREATE [ OR REPLACE ] PACKAGE nombre_paquete AS definiciones END;

El cuerpo del paquete: Contiene la implementación de cada cursor y subprograma declarado en la especificación del paquete. Si un subprograma contenido en el cuerpo del paquete no se encuentra definido en la especificación del paquete, entonces este subprograma solo es accesible desde otro subprograma del mismo paquete. Para que un subprograma pueda ser accedido desde fuera del paquete tanto su definición como su implementación deben estar en el paquete. El cuerpo de un paquete se define con la instrucción CREATE PACKAGE BODY. Sintáxis CREATE [ OR REPLACE ] PACKAGE BODY nombre_paquete AS implementación END;

Ejemplo: CREATE OR REPLACE PACKAGE PaqueteGuia AS TYPE ResultCursor IS REF CURSOR;

--Procedimiento que ingresa el id del producto y devuelve el stock actual y stock minimo PROCEDURE SP_StockProducto(pi_idProducto Producto.idProducto%TYPE,po_stockActual OUT NUMBER,po_stockMinimo OUT NUMBER);

--Procedimiento que devuelve el resulatado de una cosnulta PROCEDURE SP_ReporteSalidasxDia(po_curResultado OUT ResultCursor);

--Funcion que devuelve el monto de las Guias durante un intervalo de fechas FUNCTION FN_MontoGuia(fecha1 date,fecha2 date ) RETURN NUMBER; END; CREATE OR REPLACE PACKAGE BODY PaqueteGuia AS PROCEDURE SP_StockProducto( pi_idProducto Producto.idProducto%TYPE, po_stockActual OUT NUMBER, po_stockMinimo OUT NUMBER) IS BEGIN SELECT stockActual INTO po_stockActual FROM Producto WHERE idProducto = pi_idProducto;

Página 86

Autor: Ing. Núñez Marinovich Néstor Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación SELECT stockMinimo INTO po_stockMinimo FROM Producto WHERE idProducto = pi_idProducto; END SP_StockProducto; PROCEDURE SP_ReporteSalidasxDia(po_curResultado OUT ResultCursor) IS BEGIN OPEN po_curResultado FOR SELECT SUM(gd.precioVenta*gd.cantidad) AS Monto, extract(year from g.fechaSalida) ||'-'||lpad(extract(month from g.fechaSalida),2,'0') ||'-'||lpad(extract(day from g.fechaSalida),2,'0') AS Tiempo FROM Guia G natural join guia_detalle gd GROUP BY extract(year from g.fechaSalida) ||'-'||lpad(extract(month from g.fechaSalida),2,'0') ||''||lpad(extract(day from g.fechaSalida),2,'0') order by extract(year from g.fechaSalida) ||'-'||lpad(extract(month from g.fechaSalida),2,'0') ||'-'||lpad(extract(day from g.fechaSalida),2,'0');

/* EXCEPTION WHEN OTHERS THEN po_intCodError := SQLCODE; po_strDetError := SUBSTR(SQLERRM, 1, 100); */ END SP_ReporteSalidasxDia;

FUNCTION FN_MontoGuia(fecha1 date,fecha2 date ) RETURN NUMBER IS nMonto NUMBER; BEGIN SELECT SUM(precioVenta * cantidad) INTO nMonto FROM Guia_detalle GD natural join Guia G WHERE TO_CHAR(fechaSalida, 'DD/MM/YYYY') BETWEEN fecha1 and fecha2 ; RETURN nMonto; END FN_MontoGuia; END;

Página 87

Autor: Ing. Núñez Marinovich Néstor Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación

MySQL es un sistema de gestión de bases de datos relacional, multihilo y multiusuario. Web: http://www.mysql.com/ Fuente: Senati – Curso Programación Web con PHP y MySQL SELECT VERSION(); /*muestra la versión de mysql*/ SELECT CURRENT_DATE(); /*muestra la fecha actual*/ SELECT VERSION(),CURRENT_DATE();

Crear una Base de datos y una tabla en MySQL DROP DATABASE IF EXISTS Gestion; CREATE DATABASE Gestion; USE GESTION; CREATE TABLE ALUMNOS (CodAlumno INT AUTO_INCREMENT, Apellidos CHAR(25), Nombres CHAR (25), PRIMARY KEY (CodAlumno) ) Engine= InnoDB;

CREATE TABLE Notas ( Curso CHAR(15), CodAlumno INT, Nota1 Numeric(4,2), Nota2 Numeric(4,2), PRIMARY KEY (Curso), FOREIGN KEY (CodAlumno) REFERENCES Alumnos(CodAlumno) ) Engine= InnoDB;

Insertar datos INSERT INTO Alumnos values (1010,'Abanto','Luis'); INSERT INTO NOTAS VALUES ('MYSQL', 1010, 15,18), ('PHP', 1010, 17,19), ('VB.NET', 1010, 16,17); Uso de Transacciones Begin, Commit, Rollback Ejemplo RollBack BEGIN;/*iniciamos la transacción*/ DELETE FROM notas; SELECT * FROM notas; /*verificamos el contenido de la tabla*/ ROLLBACK;/* deshacemos la transacción*/ SELECT * FROM notas; /*Si se verifica la tabla notas se verá que

se ha restaurado las notas*/

Ejemplo Commit

/*commit: Permite confirmar la transacción (ya no hay marcha atras) */ begin; delete from notas; commit; SELECT * from notas;

Implementar la recursividad en la tabla empleados: Create table Empleados (codEmpleado int AUTO_INCREMENT, NCompleto char(50), Jefe int, Primary key (codEmpleado), Foreign key (jefe) references Empleados (codEmpleado) ON UPDATE CASCADE ON DELETE SET NULL) Engine = InnoDB; Ejemplo BD Northwind use northwind; SELECT * from suppliers; SELECT * from products; SELECT * from orders; SELECT * from customes;

Página 88

Autor: Ing. Núñez Marinovich Néstor Manuel Ingeniero Informático

SELECT * from orderdetails;

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


/* Solo mostrar algunas columnas */ SELECT CustomerId, CompanyName, Country from customers;

/* A las columnas se les pide poner un alias */ SELECT CustomerID as Codigo, companyName as Cliente, Country as Pais from customers;

/* Mostrar el codigo y el nombre completo de los empleados*/ SELECT employeeId as Codigo, CONCAT(LastName,' ',FirstName) as Empleado from Employees;

/* Mostrar el codigo y el nombre completo de los empleados y fecha de nacimiento*/ SELECT employeeId as Codigo, CONCAT(LastName,' ',FirstName) as Empleado, birthdate from Employees; SELECT employeeId as Codigo, CONCAT(LastName,' ',FirstName) as Empleado, Datediff(current_date(),birthdate)/365 as Edad from Employees;

/*Muestra los 10 primeros registros de la consulta:*/ SELECT productID, quantity, UnitPrice, quantity * UnitPrice as Subtotal from orderDetails Limit 10 ; LIMIT 0,10 : Empieza desde el registro 0, hasta los 10 siguientes registros. LIMIT 10,10 : Empieza desde el registro 10, hasta los 10 siguientes registros.

/* Mostrar los paises en los cuales la empresa tiene clientes*/ SELECT country from customers;

/* Eliminamos los registros duplicados */ SELECT distinct country from customers;

/* Ordenar registros */ SELECT distinct country from customers order by country;

/* Ordenar registros ALEATORIAMENTE */ SELECT * from customers order by RAND();

/*Mostrar el producto más caro */ SELECT productName, UnitPrice,UnitsInStock from Products order by unitPrice desc limit 1;

/* mostrar el nombre, precio y las unidades de stock de los productos ordenados por el nombre del producto*/ SELECT productName, UnitPrice,UnitsInStock from Products order by productName;

/*Mostrar los 3 productos más baratos */ SELECT productName, UnitPrice,UnitsInStock from Products order by unitPrice asc limit 3;

/*Mostrar los productos y mostrar ‘Si’ en caso estén descontinuados y ‘NO’ en cualquier otro caso*/ SELECT productName, case when discontinued =1 then 'Si' else 'No' END as Suspendido from products; /* Funciones de agrupamiento:COUNT(*), SUM( ), AVG( ), MAX( ), MIN( ) */

/*Obtener el número de clientes */ /*Consultas Escalares*/ SELECT count(*) as NroClientes from customers; SELECT count(*) as NroProductos from Products;

/*Obtener el numero de países en los que hay clientes*/ SELECT count( distinct country) from customers;

/*Obtener el Flete cobrado por el envió de productos*/ SELECT sum(Freight) as Flete from Orders;

/*Obtener las ventas totales efectuadas por la empresa*/ SELECT sum(unitprice*quantity) as Total from OrderDetails;

/*Obtener el precio promedio de los productos */ SELECT AVG(UnitPrice) as Productos from Products;


Aromas de Bases de Datos y otras fragancias de Programación /* Obtener el precio más alto y el más bajo de los productos*/ SELECT MAX(UnitPrice) as Alto, MIN(UnitPrice) as Bajo from Products;

/* Obtener de todo*/ SELECT COUNT(*) as NroProductos,SUM(UnitPrice) as Stock, AVG(UnitPrice) as PrecioPromedio, MAX(UnitPrice) as Alto,MIN(UnitPrice) as Bajo from Products;

/*Obtener el producto más vendido usar orderdetails*/ SELECT ProductId,sum(quantity) as Productos from orderdetails group by productIdorder by productos desc limit 1

/*Obtener el nro de clientes agrupados por pais*/ SELECT country, count(*) as Nro from Customers group by country with rollup; // with rollup crea resúmenes por agrupamiento

/*Obtener el nro de pedidos agrupados por el codigo de clienteusar ORDERS */ SELECT customerId, count(*) as nro from orders group by customerId;

/*Obtener el nro de productos agrupados por el codigo de la categoría usar Products */ SELECT CategoryId, count(*) as nro from Products group by categoryId;

/* Obtener el codigo del empleado que mas pedidos atendió Usar ORDERS*/ SELECT EmployeeId, count(*) as nro from orders group by EmployeeId order by nro desc limit 1;

/* Obtener el codigo del Producto que más rentableUsar ORDERDETAILS*/ SELECT ProductId, sum(Unitprice*quantity) as nro from orderDetails group by ProductId order by nro desc limit 1;

/*Mostrar al cliente mas fidelizado (el que más veces ha comprado)Usar Orders */ SELECT CustomerId, count(*) as NroPedidos from orders group by CustomerId order by NroPedidos desc limit 1;

/* Restricciones de agrupamiento - Mostrar los países en los que hay más de 7 clientes*/ SELECT country, count(*) as nro from Customers group by country having count(*) >7; RESTRICCIONES - WHERE EXPRESION Operadores de comparacion:

/*Mostrar los clientres del pais USA*/ SELECT CustomerId,CompanyName,Country from Customers where country='USA'order by CompanyName;

/*Mostrar los cliebntes de Argentina y Brazil*/ SELECT CustomerId,CompanyName,Country from Customers where country='Argentina' OR country='Brazil' order by Country;

/*Mostrar los cliebntes de Argentina, Brazil, Venezuela, Mexico, USA y Canada*/ SELECT CustomerId,CompanyName,Country from Customers where country='Argentina' OR country='Brazil' or country='Venezuela' OR country='USA' OR country='Canada 'order by Country; SELECT CustomerId,CompanyName,Country from Customers where country IN('Argentina','Brazil','Venezuela','USA','Canada')order by Country;

/*Mostrar los productos cuyo precio unitario es menor a 50*/ SELECT ProductName, UnitPrice from Products where UnitPrice<50;

/*Mostrar los productos cuyo precio unitario es mayor o igual a 50*/ SELECT ProductName, UnitPrice from Products where UnitPrice>=50;

/*Mostrar los productos cuyo precio unitario esta entre 10 y 50*/ SELECT ProductName, UnitPrice from Products where UnitPrice>=10 and UnitPrice<=50ORDER BY UnitPrice; SELECT ProductName, UnitPrice from Products where UnitPrice between 10 and 50ORDER BY UnitPrice;

Página 90

Autor: Ing. Núñez Marinovich Néstor Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación /*Obtener el numero de paises en los cuales existe clientes*/ SELECT count(distinct country) from customers;

/*Mostrar los clientes cuyo nombre empieza con la letra A*/ SELECT customerID, CompanyName from Customers where CompanyName like 'A%'

/*Mostrar los clientes cuyo nombre termina con la letra S*/ SELECT customerID, CompanyName from Customerswhere CompanyName like '%S'

/*Mostrar los clientes cuyo nombre contenga la palabra STOP*/ SELECT customerID, CompanyName from Customers where CompanyName like '%STOP%'

/*Mostrar los pedidos del año 1997*/ SELECT SELECT SELECT SELECT

orderId, orderId, orderId, orderId,

OrderDate, OrderDate, OrderDate, OrderDate,

Freight Freight Freight Freight

from from from from

orders orders orders orders

where where where where

year(OrderDate)=1997; OrderDate>=’1997/01/01’ and OrderDate<=’1997/12/31’; OrderDate between ’1997/01/01’ and ’1997/12/31’; OrderDate between ’19970101’ and ’19971231’;

/*obtener el producto mas vendido*/ SELECT productId, sum(quantity) as Ventas from orderdetails group by productid order by Ventas desc limit 1;

/*Obtener el producto mas rentable*/ select productId,sum(quantity*unitPrice) as Ventas from orderdetails group by productid order by Ventas desc limit 1;

/*Mostrar al cliente mas fidelizado**/ SELECT customerId, count(customerId) as Nro from orders group by customerId order by Nro desc limit 1; /*SUBCONSULTAS*/

/*Obtener el número de clientes totales*/ SELECT count(*) from customers;

/*Obtener el número de clientes que han comprado por lo menos una vez*/ SELECT count(distinct customerId) from orders;

/*Quienes son los clientes que no han efectuado compra alguna*/ SELECT customerId, companyNamefrom customerswhere not customerId in (SELECT customerId from Orders);

/*Obtener el nombre del producto, el precio Unitario y el precio Promedio del producto*/ SELECT productName, UnitPrice, (SELECT AVG(UnitPrice) as Promedio from Products) Promediofrom Products;

/*Obtener el nombre del producto mas vendido*/ SELECT productName from products where productid=(SELECT productId from orderdetails group by productid order by sum(quantity) desc limit 1);

/*Obtener el nombre del cliente mas fidelizado*/ SELECT companyName from customerswhere customerId=(SELECT customerIdfrom orders group by customerId order by count(customerId) desc limit 1); JUNTURAS

/*obtener los productos que se vendieron en el pedido 10248*/ SELECT * from orderdetails where orderid=10248;

/*mostrar la categoria a la cual pertenece cada producto*/ SELECT products.productid, products.productname,categories.categoryname from productsinner join categories on(products.categoryid=categories.categoryid); SELECT p.productid, p.productname,c.categoryname From products as p inner join categories as c on (p.categoryid=c.categoryid); SELECT p.productid, p.productname,c.categoryname from products as p inner join categories as c using (categoryid); SELECT p.productid, p.productname,c.categoryname from products as p natural join categories as c;

Página 91

Autor: Ing. Núñez Marinovich Néstor Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación /*mostrar la categoria a la cual pertenece cada producto con idcategoria=7*/ SELECT p.productid, p.productname,c.categoryname from products as p, categories as c where p.categoryid=c.categoryid and c.categoryid=7; SELECT p.productid, p.productname,c.categoryname from products as p inner join categories as c using (categoryid) where c.categoryid=7;

/*obtener el nombre de los productos que se vendieron en el pedido 10248 usar: products y orderdetails */ SELECT p.productname, o.unitprice, o.quantity from products p join orderdetails ousing (productid) where orderid=10248;

/*obtener el nombre del cliente del pedido 10248 usar: customers y orders*/ SELECT companyname, orderdate, ordered from customers join orders using(customerid)where orderid=10248;

/*mostrar el flete (freight) cobrado por cada compañia de envio. usar: orders(shipvia) y shippers(shipperid)*/ SELECT companyname, sum(freight) as flete from shippers s join orders o on (s.shipperid=o.shipvia) group by companyname with rollup;

--si se utilize order by ya no se usa rollup /*hacer una consulta de union para mostrar el nombre de la categoria, el nombre del producto, el precio del productoy el nombre del proveedorusar:categories, products y suppliers */ SELECT categoryname, productname, unitprice, companyname from products join categories using (categoryid) join suppliers using (supplierid);

/*hacer una consulta de union para mostrar el nombre del cliente, el nombre completo del empleado que lo atendió y la fecha en que se vendio el pedido 10248 */ SELECT companyname, concat(lastname, ' ' ,firstname) as empleado, orderdate from orders join customers using (customerid) join employees using (employeeid);

/*utilizando left join. mostrar los clientes que aun no han efectuado compra alguna */ SELECT c.customerid, c.companyname, o.customerid from customers c left join orders o using (customerid) where o.customerid is null; SELECT c.customerid, c.companyname, o.customerid from orders o right join customers c using (customerid) where o.customerid is null;

/*obtener el nombre del producto mas vendido. Usar: products y orderdetails*/ SELECT productname, sum(quantity) as cant from products join orderdetails using(productid) group by productname order by cant desc limit 1;

/*obtener el nombre completo del empleadoque mas pedidos atendió. Usar:employees y orders*/ SELECT concat(lastname, ' ', firstname) emp,count(*) nro from employees join orders using(employeeid) group by lastname, firstname order by nro desc limit 1;

/*obtener el nombre de la empresa que tiene la mayorrecaudación de flete (freight).usar shippers y orders*/ SELECT companyname, sum(freight) as flete from shippers s join orders o on (s.shipperid=o.shipvia) group by companyname order by flete desc limit 1;

/*obtener el nombre del producto mas rentable*/ SELECT productname, sum(quantity*o.unitprice*(1-discount)) total from products p join orderdetails o using(productid) group by productname order by total desc limit 1;

Página 92

Autor: Ing. Núñez Marinovich Néstor Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación /*obtener el nro de productos, agrupados por el nombre del proveedor y de la categoria usar products, suppliers y categories */ SELECT categoryname, companyname, count(*) from products join categories using(categoryid) join suppliers using(supplierid)group by categoryname, companyname;

/*union de resultados*/ SELECT companyname from customers UNION SELECT companyname from suppliers UNION SELECT companyname from shippers; SELECT supplierid, companyname from suppliers UNION SELECT shipperid, companyname from shippers; EJERCICIO REFERENCIA CRUZADA CREATE TABLE profesores (id INT, nombres CHAR(25)); CREATE TABLE cursos(nombre CHAR(25), id INT); INSERT INTO profesores VALUES (1, 'abanto'); INSERT INTO profesores VALUES (2, 'alfaro'); INSERT INTO profesores VALUES (3, 'viñas'); INSERT INTO cursos VALUES('winoffice', 1); INSERT INTO cursos VALUES('diseño', 1); INSERT INTO cursos VALUES('diseño', 2); INSERT INTO cursos VALUES('macromedia', 2); SELECT * FROM profesores JOIN cursos USING(id); /*UNION PRODUCTO CARTESIANO*/ SELECT * from profesores, cursos; /*LAS FUNCIONES DE AGRUPAMIENTO PERMITEN OBTENERRESULTADOS AL ESTILO REFERENCIA CRUZADA*/ CREATE TEMPORARY TABLE tempo(anio INT, TRIM INT, nro INT); INSERT INTO tempo SELECT YEAR(orderdate) AS anio, QUARTER(orderdate) AS TRIM, orderid FROM orders; SELECT anio, SUM(CASE WHEN SUM(CASE WHEN SUM(CASE WHEN SUM(CASE WHEN FROM tempo GROUP BY anio;

TRIM=1 TRIM=2 TRIM=3 TRIM=4

THEN THEN THEN THEN

1 1 1 1

ELSE ELSE ELSE ELSE

0 0 0 0

END) END) END) END)

t1, t2, t3, t4

/*OBTENER EL FLETE COBRADO POR AÑO Y TRIMESTRE */ DROP TABLE IF EXISTS tempo; CREATE TEMPORARY TABLE tempo(anio INT, TRIM INT, monto NUMERIC(12,2)); INSERT INTO tempo SELECT YEAR(orderdate) AS anio, QUARTER(orderdate) AS TRIM, freight FROM orders; SELECT *, t1+t2+t3+t4 AS total FROM (SELECT anio, SUM(CASE WHEN TRIM=1 THEN monto ELSE 0 END) t1, SUM(CASE WHEN TRIM=2 THEN monto ELSE 0 END) t2, SUM(CASE WHEN TRIM=3 THEN monto ELSE 0 END) t3, SUM(CASE WHEN TRIM=4 THEN monto ELSE 0 END) t4 FROM tempo GROUP BY anio) AS t; Autor: Ing. Núñez Marinovich Néstor Manuel Página 93 Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación /*OBTENER LAS VENTAS TOTALES AGRUPADO POR AÑO Y TRIMETREUSAR ORDERS Y ORDERDETAILS*/ drop table if exists tempo; create temporary table tempo(anio int, trim int, monto numeric(12,2)); insert into tempo SELECT year(o.orderdate) as anio, quarter(o.orderdate) as trim, sum(od.quantity*od.unitprice*(1-od.discount)) monto from orders as o join orderdetails as od using (orderid)group by o.orderdate; SELECT *, t1+t2+t3+t4 as total from (SELECT anio, sum(case when trim=1 then monto sum(case when trim=2 then monto sum(case when trim=3 then monto sum(case when trim=4 then monto from tempo group by anio) as t;

else else else else

0 0 0 0

end) end) end) end)

t1, t2, t3, t4

/*USAR JOIN PARA ACTUALIZAR DATOS - ACTUALIZAR EL PRECIO DE LOS PRODUCTOS EN 10%*/ UPDATE products SET unitprice = unitprice * 1.1;

/*ACTUALIZAR EL FLETE COBRADO CON EL 10% DEL VALOR DE LA VENTAS TOTALES DE CADA PEDIDO*/ /***************OJO : MYSQL NO SOPORTA ACTUALIZACION CON UNIONES**************/ UPDATE orders SET freight=od.unitprice*od.quantity*(1-od.discount)*0.1 FROM orders o INNER JOIN orderdetails od ON (o.orderid=od.orderid); SELECT orderid, SUM(freight), SUM(unitprice*quantity*(1-discount)) AS venta,SUM(unitprice*quantity*(1discount))*0.1 AS porcfrom orders JOIN orderdetails USING(orderid)GROUP BY orderid;

/*ACTUALIZAR EL PRECIO DE LSO PRODUCTOS DE ACUERDO A LA SGTE TABLA:*/

Precio Menor que 50 Entre 51 y 100 Mayor que 100

Página 94

Aumentar 15% 20% 25%

update products set unitprice = case when unitprice<50 then unitprice*0.15 when unitprice>=51 and unitprice<=100 then unitprice*0.2 when unitprice>100 then unitprice*0.25 end ;

Autor: Ing. Núñez Marinovich Néstor Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación FUNCIONES SELECT CONCAT(LASTNAME, ' ', FIRSTNAME) AS EMPLEADO FROM EMPLOYEES drop function if exists ncompleto; create function ncompleto(id int) returns char(50) return (SELECT concat(lastname, ' ', firstname) from employees where employeeid=id); SELECT NCompleto(1) AS Empleado; SELECT NCompleto(7) AS Empleado; SELECT EmployeeID, NCompleto(EmployeeID) as Empleado FROM Employees;

/*CREAR UN FUNCION PARA OBTENER EL SUBTOTAL DE LAS VENTAS. USAR LA TABLA ORDERDETAILS STOTAL=UNIPRICE*QUANTITY*(1-DISCOUNT)*/ SELECT orderid, productid, unitprice, quantity,discount, unitprice*quantity*(1-discount) as st from orderdetails where orderid=10248; create function stotal1(unitprice numeric(10,2), quantity int, discount numeric(5,2)) returns numeric(10,2) return (unitprice*quantity*(1-discount)); create function stotal2(oid int, pid int) returns numeric(10,2) return ( SELECT unitprice*quantity*(1-discount) from orderdetails where orderid=oid and productid=pid);

/****PROBANDO *****/ SELECT orderid, productid, unitprice, quantity, discount, stotal1(unitprice,quantity,discount) st from orderdetails where orderid=10248; SELECT orderid, productid, unitprice, quantity,discount, stotal2(orderid,productid) st from orderdetails where orderid=10248;

/*USANDO LA FUNCION STOTAL. OBTENER EL PRODUCTO MAS RENTABLE*/ SELECT PRODUCTID, STOTAL2(ORDERID,PRODUCTID) ST FROM ORDERDETAILS ORDER BY ST DESC LIMIT 1; drop function if exists nproducto; create function nproducto(id int) returns char(50) return (SELECT productname from products where productid=id);

/*OBTENIENDO EL NOMBRE DEL PRODCUTO MAS RENTABLE*/ SELECT NPRODUCTO(PRODUCTID) PRODUCTO, STOTAL2(ORDERID,PRODUCTID) ST FROM ORDERDETAILS ORDER BY ST DESC LIMIT 1;

/*VER LAS INTRUCCIONES QUE PERMITIERON CREAR LA FUNCION*/ SHOW CREATE FUNCTION STOTAL2 \G

Página 95

Autor: Ing. Núñez Marinovich Néstor Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación PROCEDIMIENTOS delimiter // create procedure ncompleto_sp( ) begin SELECT concat(lastname, ' ', firstname) as empleado from employees; end // delimiter ; CALL NCOMPLETO_SP;

/*CREAR UN PROCEDIMIENTO ALMACENADO PARA OBTENER LA FACTURACION TOTAL DE UN NROPEDIDO*/ drop procedure if exists factura; delimiter // create procedure factura(oid int) begin SELECT o.orderid, p.productname, o.unitprice, o.quantity, o.discount, (o.unitprice*o.quantity*(1-o.discount)) stotal from products p join orderdetails o using (productid) where o.orderid=oid; end // delimiter ; CALL FACTURA(10248);

/*CREAR UN PROCEDIMIENTO PARA MOSTRAR EL TOTAL DE LAS VENTAS, DISTRIBUIDOS POR AÑO (FILAS) Y TRIMESTRE (COLUMNAS)*/ drop procedure if exists rcruzada; delimiter // create procedure rcruzada( ) begin drop table if exists resumen; create temporary table resumen (anio int, trim int, monto numeric(12,2)); insert into resumen SELECT year(orderdate), quarter(orderdate), unitprice*quantity*(1-discount) from orders join orderdetails using(orderid); SELECT *, t1+t2+t3+t4 as total from ( SELECT anio, sum(case when trim=1 then monto sum(case when trim=2 then monto sum(case when trim=3 then monto sum(case when trim=4 then monto from resumen group by anio) as t ; end // delimiter ; CALL RCRUZADA();

else else else else

0 0 0 0

end) end) end) end)

t1, t2, t3, t4

/*USANDO LA TABLA EMPLOYEES. CREAR UN PROCEDIMIENTO PARA MOSTRAR LOS DATOS DE LOS EMPLEADOS DE LA SIGUIENTE FORMA: CODIGO, NCOMPLETO DEL EMPLEADO, NCOMPLETO DEL JEFE*/ drop procedure if exists empleados_sp; delimiter // create procedure empleados_sp( ) begin SELECT employeeid as codigo, ncompleto(employeeid) as empleado, ncompleto(reportsto) as jefe from employees; end // delimiter ; CALL EMPLEADOS_SP();

Página 96

Autor: Ing. Núñez Marinovich Néstor Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación Usuarios y Privilegios Sentencia

Descripción

GRANT

Crea al usuario y concede permisos

REVOKE

Niega permisos

DROP

Elimina al usuario

Usuarios y privilegios Crear usuarios

CREATE USER

Otorgar permisos

GRANT

/*Se puede usar GRANT para ambas cosas*/ GRANT USAGE ON *.* TO jperez IDENTIFIED BY '1234';

/*para probar el nuevo login*/ mysql -h localhost -u jperez -p

/*Conceder privilegios solo a una tabla*/ GRANT SELECT ON NORTHWIND.Products TO jperez;

/*tratar de actualizar el precio de los productos en un 10%, usando el usuario jperez*/ UPDATE Products SET unitprice=unitprice*1.1;

/*se ha generado un error, jperez solo privilegios de SELECCION*/ /*los privilegios que le puede conceder a un usuario son:SELECT , CREATE, INSERT, UPDATE, DELETE, DROP, ALL. Para que JPEREZ pueda actualizar hay que concederle permisos de ACTUALIZACION*/ GRANT UPDATE ON NORTHWIND.Products TO jperez; GRANT SELECT , UPDATE ON NORTHWIND.Products TO jperez;

/*Para visualizar los permisos de un usuario*/ SHOW GRANTS FOR jperez;

/*Conceder permisos de seleccion a toda la BD Northwind*/ GRANT SELECT ON NORTHWIND.* TO jperez;

/*para hacer efectivos estos permisos, se tiene que desconectar y volver a ingresar al usuario*/ /*REVOCAR LOS PRIVILEGIOS*/ REVOKE UPDATE ON Northwind.Products FROM jperez;

/*Probar la sgte instruccion*/ UPDATE Products SET unitprice=unitprice/1.1; REVOKE SELECT ON Northwind.Products FROM jperez;

/*Concer todos los privilegios al usuario labanto*/ GRANT ALL ON NORTHWIND.* TO labanto IDENTIFIED BY '1234';

/*crear al usuario ealfaro con las capacidades de ROOT*/ GRANT ALL ON *.* TO ealfaro IDENTIFIED BY '1234';

/*BORRAR O ELIMINAR A UN USUARIO*/ DROP USER jperez; Los permisos son: SELECT , CREATE, INSERT, UPDATE, DELETE, DROP, ALL

Página 97

Autor: Ing. Núñez Marinovich Néstor Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Examen Parcial de MySQL

Crear una base de datos de Nombre PRACTICA 1. Crear las tablas que se muestran en la figura anterior. Sugiera el tipo de dato que debe tener cada campo en cada tabla. Relacione las diferentes tablas 2. Ingrese 5 registros en cada tabla principal: Productos, Empleados, Clientes, Pedidos; en la tabla de DeataPedidos, 4 registros por cada pedido. 3. Actualice el precio unitario de los productos con el 15% DROP DATABASE IF EXISTS Ventas; Create Database Ventas; Use Ventas; CREATE TABLE CLIENTES ( IdCliente INT AUTO_INCREMENT, NombreCliente varchar(30), direccion varchar(50), ciudad varchar(50), telefono varchar(15), tieneDeuda BIT, PRIMARY KEY (IdCliente) ) ENGINE=MyISAM; CREATE TABLE EMPLEADOS ( IdEmpleado INT AUTO_INCREMENT, Nombres varchar(30), Apellidos varchar(30), Direccion varchar(50), telefono varchar(15), FNacimiento date, PRIMARY KEY (IdEmpleado) ) ENGINE=MyISAM; CREATE TABLE PEDIDOS (

IdPedidos INT AUTO_INCREMENT, IdCliente INT, IdEmpleado INT, FechaPedido date, DireccionDestino varchar(50), CiudadDestino varchar(20), MontoTotal Decimal(8,2), PRIMARY KEY (IdPedidos), FOREIGN KEY (IdCliente) REFERENCES Clientes(IdCliente), FOREIGN KEY (IdEmpleado) REFERENCES Empelados(IdEmpleado) ) ENGINE=MyISAM; CREATE TABLE PRODUCTOS ( IdProducto INT AUTO_INCREMENT, NombreProducto varchar(40), PrecioUnitario decimal(8,2), UnidadesEnStock INT, EstaSuspendido BIT, PRIMARY KEY (IdProducto) ) ENGINE=MyISAM; CREATE TABLE DEATAPEDIDOS ( IdPedido INT, IdProducto INT, PrecioUnitario decimal(8,2), Cantidad INT, MontoDescuento decimal(8,2), FOREIGN KEY (IdPedido) REFERENCES Pedidos(IdPedido), FOREIGN KEY (IdProducto) REFERENCES IdProductos(IdProducto) ) ENGINE=MyISAM;

/* INSERCIONES */ INSERT INTO CLIENTES VALUES(DEFAULT,'Pepito Loyola','Los Naranjos 201 San Miguel','Lima','01-4568921',1), (DEFAULT,'Pamela Chu','La Perla 465','Callao','014568921',0), (DEFAULT,'Juanito Perez','Loros Verdes 549','Trujillo','044-468921',1), (DEFAULT,'Susanita Benites','Los Tilos 465','Chimbote','68921',1), (DEFAULT,'Ingridcita Meza','Bolognesi 165','Ica','568921',0);

/*************************************/ INSERT INTO Empleados VALUES(DEFAULT,'Luchito','Barrios','La Esperanza 465','295641','1980/12/12'), (DEFAULT,'Jose','Barrios','Moche 585','214921','1981/12/12'), (DEFAULT,'Mary','Suarez','Porvenir','268921','1980/12/ 12'), (DEFAULT,'Betty','Rojas','Florencia 231','208921','1980/12/12'),


Aromas de Bases de Datos y otras fragancias de Programación (DEFAULT,'Violeta','Alva','Colon 475','568921','1980/12/12');

SEGUNDA PRACTICA CALIFICADA DE MYSQL

/*************************************/

CREAR LA TABLA ALUMNOS CON LA SGTE ESTRUCTURA IDALUMNO INT AUTO_INCREMENT PRIMARY KEY, APELLIDOS CHAR(25), NOMBRES CHAR(25), DIRECCION VARCHAR(100), DNI CHAR(8), FNACIM DATE, SEXO BIT

INSERT INTO PEDIDOS Values (DEFAULT,1,1,'2005/10/05','Baños del Inca 755', 'Cajamarca', 112.50), (DEFAULT,2,2,'2005/10/06','Paseo de la Republica 4225', 'Lima', 1012.30), (DEFAULT,3,3,'2005/10/07','Av. España 1250', 'Trujillo', 2112.50), (DEFAULT,4,4,'2005/10/08','Los Tilos 755', 'Piura', 112.50), (DEFAULT,5,5,'2005/10/09','La Merced 272', 'Iquitos', 112.50) ;

/*************************************/ INSERT INTO PRODUCTOS VALUES (DEFAULT,'Caja Chelas',38, 200, 0), (DEFAULT,'Cajetilla Fallos',3.5, 150, 1), (DEFAULT,'Galletas Soda',0.5, 360, 0), (DEFAULT,'Mixtos',10, 120, 1), (DEFAULT,'Ron',12.5, 80, 0);

/*************************************/ INSERT INTO DEATAPEDIDOS (1,1,0.3,10,5), (1,2,0.4,15,7), (1,3,0.5,20,2), (1,4,0.6,40,3), (1,5,0.7,60,6); INSERT INTO DEATAPEDIDOS (2,1,1.3,12,7), (2,2,2.4,18,6), (2,3,3.5,20,2), (2,4,2.6,30,3), (2,5,1.7,50,2); INSERT INTO DEATAPEDIDOS (3,1,10.3,100,15), (3,2,20.4,150,17), (3,3,40.5,200,12), (3,4,60.6,400,13), (3,5,20.7,600,16); INSERT INTO DEATAPEDIDOS (4,1,0.3,10,5), (4,2,0.4,15,7), (4,3,0.5,20,2), (4,4,0.6,40,3), (4,5,0.7,60,6); INSERT INTO DEATAPEDIDOS (5,1,0.3,310,50), (5,2,2.4,215,70), (5,3,3.5,220,20), (5,4,1.6,240,30), (5,5,0.7,260,35);

Values

Values

Values

Values

/**************************************/ DROP TABLE IF EXISTS NOTAS; CREATE TABLE NOTAS (IDALUMNO INT, CURSO CHAR(15), NOTA1 NUMERIC(4,1), NOTA2 NUMERIC(4,1) ); INSERT INTO NOTAS VALUES (1,'EXCEL', 13, 15), (1,'ACCESS', 17, 12), (1,'WORD', 18, 17), (2,'EXCEL', 16, 17), (2,'ACCESS', 18, 15), (2,'WORD', 19, 19); EXAMEN DROP DATABASE IF EXISTS Demo; CREATE DATABASE Demo; USE Demo; CREATE TABLE Personas (IdPersona Int Auto_Increment PRIMARY KEY, Apellidos Char(25) Not Null, Nombres Char(25) Not Null, FNacim Date, DNI Char(8), Direccion VarChar(100), Sexo Bit Not Null DEFAULT 0, Telefono Char(15), Celular Char(15), Email Char(50));

Insert into Personas Values (1, 'Alarcon Campos', 'Segundo Felipe', '1984/01/12','42191808', 'Antenor Orrego 585 Buenos Aires Sur', 1, NULL, '9750037',NULL), (2, 'Caballero Murga', 'Walter Miguel', '1986/09/29','43932570', '21 de Octubre 927 Florencia de Mora',1, /**************************************/ '380300',NULL,NULL), /*3. Actualice el precio unitario de los productos con el (3, 'Cedeño Ruiz','Edgar Javier', 15% */ '1984/11/30','43292512', 'Jr. San UPDATE PRODUCTOS SET Martín Nro. 3 Cartavio',1, '432929', NULL, NULL), PrecioUnitario=PrecioUnitario*1.15; (4, 'De Bracamonte Chávez','Luis José', '1969/05/01', '18099640', 'Av. América Sur 3867 Urb. La Merced', 1, '282532', NULL, NULL), Autor: Ing. Núñez Marinovich Néstor Manuel URL: http://manhiuco.es.tl Página 99 Ingeniero Informático Email: manhiuco@hotmail.com Values


Aromas de Bases de Datos y otras fragancias de Programación (5, 'Flores Alvarado', 'Percy Orlando', '1977/10/02', '18214932', 'Jr. Reforma 146 El Cortijo', 1, '242813', NULL, NULL), (6, 'Izquierdo Chavez', 'Janette Paola', '1979/05/25', '40442774', 'Jr. Napo 189', 0, NULL, '9670397', NULL), (7, 'Caceres Paredes', 'Fiorela Aracely', '1987/10/13', '44856277', 'Calle Juan Velasco Alvarado MZ-13 L-7', 0,'273428', NULL, NULL), (8, 'Castillo Espinoza', 'Silvia Consuelo', '1976/10/24', '18201280', 'Av. Larco 397 - Dpto A', 0, '347155', NULL, NULL) , (9, 'Flores Castillo', 'Claudia María', '1986/09/03', '43905880', 'Urb. Parque Industrial MZ-K L-15', 0, '273380', NULL, NULL), (10,'Ramos Aliaga Castro', 'Julia María Cristina', '1978/08/14', '40073972', 'Av. Los Incas 236',0, '208880', NULL, NULL), (11,'Alfaro Asmad', 'Enrique Mercedes', '1962/10/26', '17813638', 'Av. Larco 505', 1, '201723', NULL, NULL), (12,'Abanto Salazar', 'Luis Alberto', '1963/05/16', '17808440', 'Av. Larco 505', 1, '201723', NULL, NULL), (13,'Pajares Alva', 'Luis Alberto', '1964/06/16', '17878770', 'Av. Larco 505', 1, '201723', NULL, NULL); CREATE TABLE Alumnos (CodAlumno Char(8) Primary Key, IdPersona Int Not Null UNIQUE References Personas (IdPersona), NEstudios Char(1) Default 'S' Check NEstudios IN ('B','P','S','X'), CEstudios Char(25), NomApoderado Char(50), DirApoderado Char(100), TelApoderado Char(15), CelApoderado char(15), Retirado Bit Not Null Default 0) ; INSERT INTO Alumnos (CodAlumno, idPersona, NEstudios) VALUES ('06145751', 1, 'S'), ('06145703', 2, 'S'), ('06145744', 3, 'X'), ('06145718', 4, 'S'), ('06145747', 5, 'X'), ('06145766', 6, 'X'), ('06145660', 7, 'S'), ('06146002', 8, 'S'), ('06145605', 9, 'X'), ('01151673', 10, 'X');

ESSALUD Char(20), AFP Char(20), Cussp Char(20), Profesion Char(20), ECivil Char(1) Not Null Default 'C' Check ECivil IN ('C','D','S','V'), NomConyuge Char(25), NroHijos Tinyint Not Null Default 0, Jubilado Bit Not Null Default 0, Cesado Bit Not Null Default 0, UNIQUE (IdPersona) ); INSERT INTO Profesores values ('16187', 13, '6406160PAAL004', 'INTEGRA', '235421LPAAA3','Ingeniero', 'C', NULL, 2, 0, 0), ('01239', 11, '6210260AAAAE002', 'PRIMA', '229431EAAA0','Ingeniero', 'C', NULL, 2, 0, 0), ('01248', 12, '6305160ANSAL002', 'INTEGRA', '231451LASNA0','Ingeniero', 'C', NULL, 1, 0, 0); Create table Modulos (IdModulo Int Auto_Increment Primary Key, NombCorto char(15) Not Null, NombLargo char(50) Not Null, NroHoras Numeric(5,1) Default 0 Check NroHoras>0, Vigente bit Not Null Default 0, Observac varchar(100) ); INSERT INTO MODULOS(NombCorto, NombLargo, NroHoras, Vigente) VALUES ('WINOFFICE', 'WINOFFICE PROFESSIONAL', 210, 1), ('DISEÑO', 'DISEÑO PUBLICITARIO', 180, 1), ('DISEÑO WEB', 'TECNOLOGIAS DE DISEÑO WEB', 150, 1), ('PROG. VB.NET', 'PROGRAMADOR DE APLICACIONES EN VB.NET', 120, 1), ('ENSAMBLAJE', 'ENSAMBLAJE', 150, 1), ('SQL 2000', 'ADMINISTRACION DE BASE DE DATOS CON SQL 2000', 120, 1);

Create table Cursos (IdCurso Int Auto_Increment Primary Key, IdModulo Int Not Null References Modulos(IdModulo), NombCorto Char(15) Not Null, NombLargo Char(50) Not Null, NroHoras Numeric(5,1) Default 0 Check NroHoras>0, Precio Decimal (10,2) Not Null Default 0, CREATE TABLE Profesores Certifica bit not null (CodProfesor Char(5) Primary Key, Default 1, IdPersona Int Not Null Vigente bit Not Null References Personas (IdPersona), Default 1, Autor: Ing. Núñez Marinovich Néstor Manuel URL: http://manhiuco.es.tl Página 100 Ingeniero Informático Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación Observac

varchar(100));

INSERT INTO CURSOS (IdModulo, NombCorto, NombLargo, NroHoras, Precio, Certifica, Vigente) VALUES (1, 'WINDOWS XP', 'MICROSOFT WINDOWS XP', 30, 118, 1, 1), (1, 'INTERNET', 'REDES E INTERNET', 30, 118, 1, 1), (1, 'MS WORD', 'MICROSOFT WORD', 30, 118, 1, 1), (1, 'MS EXCEL', 'MICROSOFT EXCEL', 30, 118, 1, 1), (1, 'MS ACCESS', 'MICROSOFT ACCESS', 30, 118, 1, 1), (1, 'MS POWERPOINT', 'MICROSOFT POWERPOINT', 15, 60, 1, 1), (1, 'MS FRONTPAGE', 'MICROSOFT FRONTPAGE', 15, 60, 1, 1), (1, 'MS PPT/FPAGE', 'POWERPOINT/FRONTPAGE', 30, 118, 1, 1), (1, 'INTEGRACION', 'INTEGRACION OFFICE', 30, 118, 1, 1), (4, 'VB-APRENDIZAJE', 'VB.NET-APRENDIZAJE', 30, 118, 1, 1), (4, 'VB-INTERMEDIO', 'VB.NET-INTERMEDIO', 60, 236, 1, 1), (4, 'VB-BASE DATOS', 'VB.NET-BASE DE DATOS', 30, 118, 1, 1), (6, 'MODELAMIENTO', 'MODELAMIENTO DE BASE DE DATOS', 30, 118, 1, 1), (6, 'ADMINISTRACION', 'ADMINISTRACION DE BASE DE DATOS CON SQL SERVER', 30, 118, 1, 1), (6, 'T-SQL', 'TRANSACT-SQL', 30, 118, 1, 1), (6, 'PROGRAMACION', 'PROGRAMACION DE BASE DE DATOS CON SQL SEVER', 30, 118, 1, 1);

('06082',1, '01239', '2006/05/10', NULL, 0), ('06022',6, '01239', '2006/07/17', NULL, 0); Create table GrupoDeta (IdGrupo Int not null References Grupos (IdGrupo), CodAlumno char(8) not null References Alumnos (CodAlumno), IdCurso INT NOT NULL References Cursos (idCurso), PR Decimal(8,1) Default 0.1, EE Decimal(8,1) Default 0.1, Observac varchar(100), Primary Key (IdGrupo, CodAlumno, idCurso) );

INSERT INTO GrupoDeta(IdGrupo, codAlumno, IdCurso, PR, EE) VALUES (1, '06145751', 1 , 20,20), (1, '06145703', 1, 19, 17.5), (1, '06145744', 1, 17, 15), (1, '06145718', 1, 18.5, 17.5), (1, '06145747', 1, 19, 18), (1, '06145766', 1, 19, 17.5), (1, '06145660', 1, 15.5, 13.5), (1, '06146002', 1, 16, 16), (1, '06145605', 1, 14.5, 14), (1, '01151673', 1, 16, 14.5), (1, '06145751', 2, 20, 13), (1, '06145703', 2, 20, 17), (1, '06145744', 2, 20, 18.5), (1, '06145718', 2, 20, 13), (1, '06145747', 2, 15, 17), (1, '06145766', 2, 18, 15.5), (1, '06145660', 2, 18.5, 12), Create table Conceptos (1, '06146002', 2, 17, 15), (IdConcepto Int Auto_Increment Primary key, (1, '06145605', 2, 19, 14.5), NombCorto char(15) not null, (1, '01151673', 2, 14, 14), Nomblargo char(50) not null, (1, '06145751', 3, 18.3, 17), Vigente bit not null (1, '06145703', 3, 15, 13.5), Default 0 ); (1, '06145744', 3, 16, 18), (1, '06145718', 3, 16, 17), INSERT INTO Conceptos VALUES (1, '06145747', 3, 15, 13.5), (1, 'Matrícula','Matrícula',1), (1, '06145766', 3, 14.3, 14), (2, 'Mensualidad', 'Mensualidad',1), (1, '06145660', 3, 15.7, 15.5), (3, 'A Cuenta', 'Pago a Cuenta',1), (1, '06146002', 3, 15, 14), (4, 'Certificados', 'Certificados',1); (1, '06145605', 3, 11.4, 14), (1, '01151673', 3, 14.7, 14.5), Create table Grupos (1, '06145751', 4, 15, 13.5), (IdGrupo Int Auto_Increment Primary Key, (1, '06145703', 4, 14, 14.5), NroGrupo char(5) not null, (1, '06145744', 4, 5.5, 12.5), IdModulo Int not null (1, '06145718', 4, 17, 13.5), References Modulos(idModulo), (1, '06145747', 4, 13.5, 16.5), CodProfesor char(5) not null (1, '06145766', 4, 5.5, 8.5), References Profesores(CodProfesor), (1, '06145660', 4, 15, 13.5), Finicio Date, (1, '06146002', 4, 19, 20), FFin Date, (1, '06145605', 4, 14, 14), Cerrado bit default 0 ); (1, '01151673', 4, 16, 15), (1, '06145751', 5, 14, 14), INSERT INTO Grupos (NroGrupo, IdModulo, (1, '06145718', 5, 16, 16.5), CodProfesor, FInicio, FFin, (1, '06145747', 5, 14, 14), Cerrado) VALUES (1, '06145660', 5, 12, 15), Autor: Ing. Núñez Marinovich Néstor Manuel URL: http://manhiuco.es.tl Página 101 Ingeniero Informático Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación (1, (1, (1, (1, (1, (1, (1, (1, (1, (1, (1, (1,

'06146002', '01151673', '06145751', '06145718', '06145747', '06146002', '01151673', '06145751', '06145718', '06145747', '06146002', '01151673',

5, 5, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7,

17, 15, 20, 20, 18, 18, 18, 16, 17, 16, 16, 17,

15), 13.5), 15), 16), 12), 13), 19), 15), 13), 14), 13), 18);

use Demo;

/*Pregunta Nro 1*/ SELECT codAlumno as Codigo, concat(apellidos,' ',nombres) as Alumno, (case NEstudios when 'P' then 'Primaria' when 'S' then 'Secundaria' when 'B' then 'Bachillerato' when 'X' then 'Superior' END) as Nivel from Alumnos a inner join personas P using(idPersona);

/*Pregunta Nro 2*/ Create table Bancos (IdBanco Int Auto_Increment Primary key, Descripcion char(50) not null, NroCuenta char(15) not null ); INSERT INTO BANCOS VALUES (1, 'Banco Continental-PNI', '908'), (2, 'Banco Continental-CI', '603'), (3, 'Banco Credito', '512'); Segunda Practica Calificada de MySQL Utilizando la BD proporcionada por el instructor, realizar las siguientes consultas: 1) Consulta de seleccion para mostrar: El codigo del alumno, su nombre completo, y el nivel de estudios que tiene. Recuerde que el campo NEstudios considera: P=Primaria, S=Secundaria, B=Bachillerato, X=Superior (usar las tablas Personas y alumnos) 2) Consulta de seleccion, con agrupamiento para mostrar : El Nro de alumnos por cada nombre de modulo de estudios (Usar las tablas Modulos, Cursos y grupodeta) 3) Consulta de seleccion, con agrupamiento para mostrar : El precio total por cada nombre de modulo (Usar las tablas Modulos y Cursos) 4) Consulta de selección, con agrupamiento para mostrar : El promedio general por cada nombre de curso (Usar las tablas Cursos y GrupoDeta) 5) Consulta de Seleccion para mostrar: El Nro de grupo, el Codigo del alumno, el nombre completo del alumno (usar una funcion), el nombre del curso (usar funcion) y el promedio del curso basado en la sgte. formula (PP + 2*EE)/3 (usar funcion) (Usar la tabla GrupoDeta)

Página 102

SELECT m.nombLargo as Modulo,count(*) as Nro from Modulos m join Cursos c using(idModulo) inner join GrupoDeta g using(idCurso) group by modulo order by Nro desc ;

/*Pregunta 3*/ SELECT m.nombLargo as Modulo,sum(precio) as Costo from Modulos m join Cursos c using(idModulo) group by Modulo order by Costo desc;

/*Pregunta 4*/ SELECT nombLargo as Curso, avg((PR+EE)/2) as Promedio from cursos c join GrupoDeta g using(idCurso) group by Curso;

/*Pregunta 5*/ drop function if exists NCompletoAlumno; create function NCompletoAlumno(cod char(8)) returns char(70) return( SELECT concat(apellidos,' ',nombres) as Alumno from Alumnos a inner join personas P using(idPersona) where codAlumno=cod); drop function if exists NCurso; create function NCurso(idC int) returns char(70) return( SELECT nombLargo as Curso from cursos where idCurso=idc); drop function if exists Promedio; create function Promedio (NPP Decimal(8,1),NEE Decimal(8,1)) returns Decimal(8,1) return((NPP + 2*NEE)/3); SELECT idGrupo as Grupo, CodAlumno as Codigo, NCompletoAlumno(CodAlumno) Alumno, NCurso(IdCurso) Curso, avg(promedio(PR,EE)) as Promedio from GrupoDeta group by Grupo, Codigo, Alumno,Curso;

Autor: Ing. Núñez Marinovich Néstor Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


PostgreSQL es un sistema de gestión de base de datos relacional orientada a objetos (ORDBMS) y libre basado en el proyecto POSTGRES, de la universidad de Berkeley. Web: http://www.postgresql.org.pe/ pgAdmin III : Es una aplicación gráfica para gestionar el gestor de bases de datos PostgreSQL.

Descripción

Sentencia SQL

Crear una Base de datos

CREATE DATABASE BDLibros;

Eliminar una Base de datos

DROP DATABASE BDLibros;

Crear 2 tablas Editorial y Libro, usando clave primaria y foránea.

create table Editorial( idEditorial serial, nombreEditorial varchar(100), primary key(idEditorial) );

Para definir un campo autoincrementable lo hacemos con la palabra clave serial.

Insertar un registro en la Tabla

create table Libro( idLibro serial, idEditorial int, titulo varchar(100), autor varchar(80) not null default 'Anonimo', precio decimal(5,2), cantidad smallint default 0, primary key(idLibro), foreign key (idEditorial) references Editorial(idEditorial) ); insert into Editorial(nombreEditorial) values('San Marcos'); insert into Libro (idEditorial, titulo, autor, precio, cantidad) values(1,'A puro codigo con Marinovich', 'Nuñez Marinovich', 50, 20);

Insertar varios registros en la Tabla Selección, concatenación (||) Mostrar una tabla mostrando aleatoriamente los registros. La cláusula limit recibe un argumento numérico positivo

insert into Libro (idEditorial, titulo, autor, precio, cantidad) values(1, 'Geometría Analítica', 'Charles H. Lehmann', 60, 12); insert into Libro (idEditorial, titulo, autor, precio, cantidad) values (1, 'Philosophiæ naturalis principia mathematica', 'Isaac Newton' , 20, 70), (1, 'Redes De Computadoras', 'Tanenbaum', 30, 50), (1, 'El Calculo', 'Leithold', 35, 60); select titulo||'-'||autor as Libro from libro; SELECT * FROM libro ORDER BY RANDOM();

--Muestra los primeros 3 registros, 0,1,2 select * from libro limit 3 offset 0;


Aromas de Bases de Datos y otras fragancias de Programación que indica el número máximo --Muestra los primeros 3 (igual al anterior) de registros a retornar; la select * from libro limit 3; cláusula offset indica el número del primer registro a retornar. El número de registro --Devolver 3 registros, desde el 6 al 8. select * from libro limit 3 offset 6; inicial es 0 (no 1). Ojo: es posible tambien escribir las tablas y columnas entre comillas, pero esto diferenciará entre mayúsculas y minúsculas. Si creamos tablas y columnas por el asistente, al escribir las consultas tendremos que escribir las tablas y columnas entre comillas.

Funciones de cadena Retorna los titulos del libro y su longitud de texto del titulo y ordenarlos descendentemente por la segunda columna. Mostrar el nombre de los autores en su texto original, también en mayúscula y en minuscula. Retorna la posición de un string dentro de otro. Si no está contenido retorna un 0. Devolver los autores y además otra columna que muestre una subcadena de la columna ‘autor’ que comience a partir del 4to carácter y que tenga longitud 2.

Sentencia SQL select titulo , char_length(titulo) as "Longitud" from libro order by 2 desc select autor , upper(autor) as "Autor en Mayuscula", lower(autor) as "Autor en minuscula" from libro order by 1 select position('PostreSQL' in 'Bienvenido PostreSQL'); --retorna 12 select position('POSTRESQL' in 'Bienvenido PostreSQL'); --retorna 0 select autor, substring(autor from 4 for 2) from libro; select autor, substr(autor, 4, 2) from libro; trim([leading|trailing|both] [string] from string) select trim(' Hola Mundo ');--retorna. "Hola Mundo"

Elimina caracteres del principio o o final de select trim(leading ' ' from ' Hola Mundo '); -- retorna: "Hola Mundo " un string. Por defecto elimina los espacios debido a que indicamos que elimine los espacios en blanco de la cadena en blanco si no indicamos el caracter o solo del comienzo (leading). string. select trim(trailing '-' from '--Hola Mundo----');-- retorna: "--Hola Mundo", esto debido a indicamos que elimine los guiones del final del string (trailing). Elimina los caracteres de la izquierda según select ltrim(' Hola ');--retorna "Hola " el dato del segundo parámetro de la función. select ltrim('****Hola*','*');--Retorna "Hola*" Elimina los caracteres de la derecha según select rtrim(' Hola ');--retorna " Hola" el dato del segundo parámetro de la función. select rtrim('**Hola*****','*');--Retorna "**Hola" Rellena de caracteres por la izquierda. El tamaño total de campo es indicado por el select lpad('Hola',10,'-'); -- retorna: "------Hola" segundo parámetro y el texto a insertar se indica en el tercero. Rellena de caracteres por la derecha. El tamaño total de campo es indicado por el select rpad('Hola',10,'-'); -- retorna: "Hola------" segundo parámetro y el texto a insertar se indica en el tercero.

Página 104

Docente: Ing. Núñez Marinovich Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación Funciones de fecha Retorna la fecha actual. Retorna la hora actual con la zona horaria. Retorna la fecha y la hora actual con la zona horaria. Retorna una parte de la fecha u hora. extract(valor from timestamp) Retorna el año actual Retorna el mes actual Retorna el dia actual Retorna la hora actual Retorna el minuto actual Retorna el segundo actual Retorna el siglo actual Retorna el dia de la semana actual Retorna el dia del año actual Retorna el nro de semana actual Retirna el trimestre actual

Sentencia SQL select current_date; select current_time; select current_timestamp; select extract(year from timestamp'2009-12-31 12:25:50'); select extract(year from current_timestamp); select extract(month from current_timestamp); select extract(day from current_timestamp); select extract(hour from current_timestamp); select extract(minute from current_timestamp); select extract(second from current_timestamp); select extract(century from current_timestamp); select extract(dow from current_timestamp); select extract(doy from current_timestamp); select extract(week from current_timestamp); select extract(quarter from current_timestamp);

Herencia entre Tablas: CREATE TABLE ciudad ( nombre text, poblacion float, altitud int ); CREATE TABLE capital( departamento char(2) ) INHERITS (ciudad);

--Para eliminarlas no se podra eliminar primero ciudad porque al otra tabal depende de esta. --Lo correcto seria: drop table capital; drop table ciudad;

Página 105

Docente: Ing. Núñez Marinovich Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación

El ADO.NET es un conjunto de componentes del software que pueden ser usados por los programadores para acceder a datos y a servicios de datos. Es una parte de la biblioteca de clases base que están incluidas en el Microsoft .NET Framework. Es comúnmente usado por los programadores para acceder y para modificar los datos almacenados en un Sistema Gestor de Bases de Datos Relacionales, aunque también puede ser usado para acceder a datos en fuentes no relacionales.

Conexión ADO.NET a SQL Server Desarrollo: ♦ ♦ ♦ ♦ ♦ ♦ ♦ ♦

Devolver cadena de Conexión Llenar DataGrid con DataTable Llenar DataGrid con DataSet Llenar un ListBox con DataReader Ejecutar Command Devolver un dato (escalar) Devolver DataRow Stored Procedure – Funciones o Procedimiento que ejecuta un Stored Procedure con parámetros de entrada y de salida opcionales. o Función que devuelve el resultado de una consulta en un DataTable o Función que devuelve el resultado de una función de usuario en SQL Server. También podrá ser usado en aquellos procedimientos almacenados que tienen instrucción RETURN. o Función que devuelve el resultado de una consulta de una Función de Tabla en Linea o Función de Tabla Multilinea Página 106

Docente: Ing. Núñez Marinovich Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación Cadenas de conexión Autenticación Windows Autenticación SQL Server

Data Source = ServidorSQL; Initial Catalog = BaseDatos; Integrated Security = True Data source = ServidorSQL; initial catalog = BaseDatos; user id = Usuario; password = Contraseña

Ejemplos de cadenas de conexión: "Data "Data "Data "Data "Data

Source=.;Initial Catalog=Northwind;Integrated Security=SSPI" Source=(local);Initial Catalog=Northwind;Integrated Security=SSPI" Source= GSIE-ALQ-NNUÑEZ\SQLEXPRESS;Initial Catalog=Northwind;Integrated Security=SSPI" Source= GSIE-TMP-PPORTUGAL;Initial Catalog=Northwind;user id=sa;password=filtech3949o" Source= 192.168.1.33;Initial Catalog=Northwind;user id=sa;password=PITAGORAS"

Espacio de nombres para conectarse SQL Server: Imports System.Data.SqlClient

1. Devolver cadena de Conexión a SQL Server Shared Function generarCadenaConexionSQL(ByVal nombreBaseDatos As String, _ Optional ByVal IP As String = "(local)", _ Optional ByVal usarAutenicacionWindows As Boolean = True, _ Optional ByVal usuario As String = "", Optional ByVal contraseña As String = "", _ Optional ByVal parametrosAdicionales As String = "") ' Falta considerar : ' Connection TimeOut or Connect Timeout: Es el espacio de tiempo en segundo ' en que se esperara una respuesta del servidor, por defecto es 15 segundos. Dim cadenaConexion As String cadenaConexion = "Data Source="& IP &";Initial Catalog="& nombreBaseDatos &";" If usarAutenicacionWindows Then 'Usando autenticacion windows cadenaConexion&= "Integrated Security=SSPI" Else 'Usando Conexion SQL cadenaConexion&= "user id="& usuario & ";password="& contraseña &";" End If cadenaConexion = cadenaConexion & parametrosAdicionales Return cadenaConexion End Function

2. Llenar DataGrid con DataTable Sub llenarDataGrid(ByVal cadenaConexion As String, ByVal sentenciaSQL As String, ByVal dataGrid As DataGrid) ' Procedimiento que ejecuta una sentencia SQL y el resultado lo muestra en un dataGrid ' El procedimiento llena un DataTable mediante una consulta Dim CN As New SqlConnection(cadenaConexion) Dim DA As New SqlDataAdapter(sentenciaSQL, CN) Dim DT As New DataTable' actua como un repositorio de la informacion consultada ' abre la conexion, ejecuta la consulta, llena el DT y cierra la conexion DA.Fill(DT) dataGrid.DataSource = DT 'Hacemos el enlace del DataTable al datagrid (Databind) 'dt.Rows.Count ' numero de filas del DataTable End Sub

Página 107

Docente: Ing. Núñez Marinovich Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación 3. Llenar DataGrid con DataSet Sub llenarDataGrid_DataSet(ByVal cadenaConexion As String, ByVal sentenciaSQL As String, ByVal dataGrid As DataGrid) ' Procedimiento que ejecuta una sentencia SQL y el resultado lo muestra en un dataGrid ' El procedimiento llena un DataSet mediante una consulta Dim CN As New SqlConnection(cadenaConexion) Dim DA As New SqlDataAdapter(sentenciaSQL, CN) Dim DS As New DataSet' actua como un repositorio de la informacion consultada ' abre la conexion, ejecuta la consulta, llena el DS y cierra la conexion DA.Fill(DS, "Tabla") dataGrid.DataSource = DS 'HAcemos el enlace del DataSet al datagrid (Databind) 'dt.Rows.Count ' numero de filas del DataTable dataGrid.DataMember = "Tabla" End Sub

4. Llenar un ListBox con DataReader Sub llenarListBox_DataReader(ByVal cadenaConexion As String, ByVal sentenciaSQL As String, ByVal campo As String, ByVal ListBox AsListBox, Optional ByVal limpiarLista As Boolean = True) ' Funcion que ejecuta una sentencia SQL y el resultado lo muestra en un ListBox ' En este codigo usamos el objeto DataReader para el acceso rapido y optimo a la BD Dim cn As New SqlConnection(cadenaConexion) Dim CMD As New SqlCommand(sentenciaSQL, cn) Dim DR As SqlDataReader If limpiarLista Then ListBox.Items.Clear() With CMD .Connection.Open() 'abrimos la conexion DR = .ExecuteReader While DR.Read ListBox.Items.Add(DR(campo)) End While .Connection.Close() End With End Sub

5. Ejecutar Command Function ejecutarCommand(ByVal cadenaConexion As String, ByVal sentenciaSQL As String) ' Funcion que ejecuta una sentencia SQL (Insert , Delete, Update) Dim CN As New SqlConnection(cadenaConexion) Dim Cmd As New SqlCommand(sentenciaSQL, CN) Try CN.Open() ' ejecuta la consulta y devolvemos el numero de filas afectadas Return Cmd.ExecuteNonQuery CN.Close() Catch ex As SqlException MsgBox(ex.Message) End Try End Function

6. Devolver un dato (escalar) Function devolverEscalar(ByVal cadenaConexion As String, ByVal sentenciaSQL As String) ' Funcion que devuelve el resultado de una consulta Dim CN As New SqlConnection(cadenaConexion) Dim Cmd As New SqlCommand(sentenciaSQL, CN) Try CN.Open() ' ejecuta la consulta y devolvemos la primera columna de la 'primera fila del conjunto de resultado devuelto por la consulta Return Cmd.ExecuteScalar CN.Close() Catch ex As SqlException MsgBox(ex.Message) End Try End Function

Página 108

Docente: Ing. Núñez Marinovich Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación 7. Devolver DataRow Function devolverDataRow(ByVal cadenaConexion As String, ByVal sentenciaSQL As String, Optional ByVal indice As Integer = 0) ' Funcion que devuelve un DataRow, es decir de una determinada consulta, devuelve los campos de ' una determinada fila(por defecto la primera). Dim CN As New SqlConnection CN.ConnectionString = cadenaConexion ' Creamos el adaptador Dim DA As New SqlDataAdapter(sentenciaSQL, CN) ' Creamos el DataSet Dim DS As New DataSet ' abrimos la conexion, llenamos el DataSet y cerramos la conexion CN.Open() DA.Fill(DS, "Tabla") CN.Close() Dim DR AsDataRow DR = DS.Tables("Tabla").Rows(indice) Return DR End Function

8. Stored Procedure 8.1. Procedimiento que ejecuta un Stored Procedure con parámetros de entrada y de salida opcionales. Sub SP_ejecutarStoreProcedure _ (ByVal cadenaConexion As String, _ ByVal nombreStoreProcedure As String, _ Optional ByVal nombreParametrosEntrada() As String = Nothing, _ Optional ByVal valorParametrosEntrada() As String = Nothing, _ Optional ByVal nombreParametrosSalida() As String = Nothing, _ Optional ByRef valorParametrosSalida() As String = Nothing) ' Procedimiento que ejecuta un Store Procedure ' usarlo para sentencias como: Update, Insert, Delete Dim cn As New SqlConnection(cadenaConexion) 'instancio el comando indicando el nombre del procedure y entregandole la conexion Dim CMD As New SqlCommand(nombreStoreProcedure, cn) Try 'indicamos que el comando es de tipo StoredProcedure CMD.CommandType = CommandType.StoredProcedure If Not nombreParametrosEntrada Is Nothing Then Dim i As Integer For i = 0 To nombreParametrosEntrada.GetUpperBound(0) CMD.Parameters.Add(New SqlParameter(nombreParametrosEntrada(i), valorParametrosEntrada(i))) Next End If If Not nombreParametrosSalida Is Nothing Then Dim i As Integer Dim PR As SqlParameter For i = 0 TonombreParametrosSalida.GetUpperBound(0) PR = New SqlParameter(nombreParametrosSalida(i), valorParametrosSalida(i)) PR.Direction = ParameterDirection.Output PR.Size = 50 CMD.Parameters.Add(PR) Next End If CMD.Connection.Open() CMD.ExecuteNonQuery() If Not nombreParametrosSalida Is Nothing Then Dim i As Integer For i = 0 To nombreParametrosSalida.GetUpperBound(0) valorParametrosSalida(i) = CMD.Parameters(nombreParametrosSalida(i)).SqlValue.ToString

Página 109

Docente: Ing. Núñez Marinovich Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación Next End If Catch ex AsSqlException MsgBox(ex.Message) Finally CMD.Connection.Close() End Try End Sub

8.2.

Función que devuelve el resultado de una consulta en un DataTable

Function SP_devolverDataTable _ (ByVal cadenaConexion As String, _ ByVal nombreStoreProcedure As String, _ Optional ByVal nombreParametros() As String = Nothing, _ Optional ByVal valorParametros() As String = Nothing, _ Optional ByVal datagrid As DataGrid = Nothing) ' Funcion que devuelve una consulta de un procedimiento almacenado Dim cn As New SqlConnection(cadenaConexion) 'instancio el comando indicando el nombre del procedure y entregandole la conexion Dim CMD As New SqlCommand(nombreStoreProcedure, cn) 'indicamos que el comando es de tipo StoredProcedure CMD.CommandType = CommandType.StoredProcedure If Not nombreParametros Is Nothing Then Dim i As Integer For i = 0 To nombreParametros.GetUpperBound(0) CMD.Parameters.Add(New SqlParameter(nombreParametros(i), valorParametros(i))) Next End If 'le entrego al DA el commando para q este se encargue de ejecutar la consulta Dim DA As New SqlDataAdapter(CMD) Dim DT As New DataTable DA.Fill(DT) 'llenamos el DataTable Return DT End Function

8.3.

Función que devuelve el resultado de una función de usuario en SQL Server. También podrá ser usado en aquellos procedimientos almacenados que tienen instrucción RETURN.

Function FN_devolverEscalar _ (ByVal cadenaConexion As String, _ ByVal nombreFuncion As String, _ Optional ByVal nombreParametros() As String = Nothing, _ Optional ByVal valorParametros() As String = Nothing) ' Procedimiento que devuelve el resultado de una funcion Escalar de la BD. ' Usarlo tambien para aquellos procedimientos almacenados con instruccion RETURN Dim CN As New SqlConnection(cadenaConexion) Dim CMD As New SqlCommand(nombreFuncion, CN) CMD.CommandType = CommandType.StoredProcedure If Not nombreParametros Is Nothing Then Dim i As Integer For i = 0 To nombreParametros.GetUpperBound(0) CMD.Parameters.Add(New SqlParameter(nombreParametros(i), valorParametros(i))) Next End If Dim PR As New SqlParameter PR = New SqlParameter("@resultado", "") PR.Direction = ParameterDirection.ReturnValue PR.Size = 100 CMD.Parameters.Add(PR)

Página 110

Docente: Ing. Núñez Marinovich Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación CMD.Connection.Open() CMD.ExecuteNonQuery() CMD.Connection.Close() Return CMD.Parameters("@resultado").SqlValue.ToString End Function

8.4.

Función que devuelve el resultado de una consulta de una Función de Tabla en Linea o Función de Tabla Multilinea

Function FN_devolverDT_FuncionReturnTable _ (ByVal cadenaConexion As String, _ ByVal nombreFuncion As String, _ Optional ByVal nombreParametros() As String = Nothing, _ Optional ByVal valorParametros() As String = Nothing) ' Procedimiento que devuelve el resultado de una funcion Tabla en linea o Tabla Multisentencia de la BD. Dim cn As New SqlConnection(cadenaConexion) 'instancio el comando indicando el nombre del procedure y entregandole la conexion Dim CMD As New SqlCommand(nombreFuncion, cn) 'indicamos que el comando es de tipo Text (SELECT * from ...) CMD.CommandType = CommandType.Text If Not nombreParametros Is Nothing Then Dim i As Integer For i = 0 TonombreParametros.GetUpperBound(0) CMD.Parameters.Add(New SqlParameter(nombreParametros(i), valorParametros(i))) Next End If 'le entrego al DA el commando para q este se encargue de ejecutar la consulta Dim DA As New SqlDataAdapter(CMD) Dim DT As New DataTable DA.Fill(DT) 'llenamos el DataTable Return DT '---------------------------------------------------------'Ejemplo de uso: ' Ejemplo1 - Funcion de Tabla En Linea: 'Dim np() As String = {"@idPedido"} 'Dim vp() As String = {"10"} 'Me.DataGridView1.DataSource = Base_Datos.SQLServer.FN_devolverDT_FuncionReturnTable(Str, "SELECT from dbo.DevolverDetallePedido(@idpedido)", np, vp) ' Ejemplo2 - Funcion Multisentencia: 'Me.DataGridView1.DataSource = Base_Datos.SQLServer.FN_devolverDT_FuncionReturnTable(str, "SELECT from dbo.fn_CategoriaClientes()") End Function

El uso de los anteriores procedimientos se realizará en el capitulo del proyecto computienda!!! Ejercicios Propuestos En cada enunciado realizar un método para lo que se indica. 1. Mostrar en un comboBox con los años existentes en un campo de tipo fecha. El método debe de tener como parámetros: Sub llenarComboBox_AñosCampoFecha(ByVal cadenaConexion As String, ByVal CBO As ComboBox, ByVal tabla As String, ByVal campo As String) 2. Llenar un ListView con una determinada sentencia SQL. Sub llenarListView(ByVal cadenaConexion As String, ByVal sentenciaSQL As String, ByVal LV As ListView)

Página 111

Docente: Ing. Núñez Marinovich Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com

*

*


Aromas de Bases de Datos y otras fragancias de Programación 3. Procedimiento en la que se ingresa una lista de campos y sus respectivas sentencias SQL en las q se mostraran cada campo con sus respectivos datos en un Treeview. Como nodo padre estará el nombre del campo, y sus hijos seran sus respectivos datos de acuerdo a la sentencia. Sub llenarCamposTreeView(ByVal cadenaConexion As String, ByVal listaCampos() As String, ByVal sentenciasSQL() As String, ByVal TV As TreeView) 4. Función que ejecuta una sentencia SQL y devuelve un DataTable. Function devolverDataTable(ByVal cadenaConexion As String, ByVal sentenciaSQL As String). 5. Función que ejecuta una sentencia y el resultado lo devuelve en un array bidimensional. Function devolverMatrizBidimensional(ByVal cadenaConexion As String, ByVal sentenciaSQL As String) 6. Función que ejecuta una sentencia y devuelve en una lista (array unidimensional) una determinada columna (nroColumna) o campo de dicho resultado de la sentencia. Function devolverColumna_ComoLista (ByVal cadenaConexion As String, ByVal sentenciaSQL As String, Optional ByVal nroColumna As Integer = 0) 7. Función que ejecuta una sentencia y el resultado lo devuelve como un String, teniendo un string como separadores de fila y otro string de separador de columna. Function devolverConsulta_ComoString( ByVal cadenaConexion As String, ByVal sentenciaSQL As String, Optional ByVal caracterSeparacionFilas As String = vbCrLf, Optional ByVal caracterSeparacionColumnas As String = " “) As String 8. Función que retorna el mayor valor de un campo de una Tabla. Function devolverMayorValorCampo(ByVal cadenaConexion As String, ByVal nombreTabla As String, ByVal nombreCampo As String). 9. Función que retorna el menor valor de un campo de una Tabla Function devolverMenorValorCampo(ByVal cadenaConexion As String, ByVal nombreTabla As String, ByVal nombreCampo As String) 10. Funcion que devuelve Verdadero si la tabla es vacia, si la tabla tuviera datos devuelve false Public Function esTablaVacia(ByVal cadenaConexion As String, ByVal nombreTabla As String) As Boolean 11. Función que devuelve Verdadero si la tabla es vacía, si la tabla tuviera datos, devuelve false Public Function esConsultaVacia(ByVal cadenaConexion As String, ByVal sentencia As String) As Boolean 12. Verifica si existe cierto dato en la BD, ingresando el nombre del campo y el dato a buscar Public Function verificarExistenciaDato(ByVal cadenaConexion As String, ByVal nombreTabla As String, ByVal nombreCampo As String, ByVal dato_a_buscar As String) As Boolean 13. Función que devuelve el número de registros de una Tabla Function totalRegistrosTabla(ByVal cadenaConexion As String, ByVal nombreTabla As String) 14. Función que devuelve el número de registros de una consulta Function totalRegistrosConsulta(ByVal cadenaConexion As String, ByVal sentenciaSQL As String) 15. Función que devuelve el número de columnas de una Tabla Function totalCamposTabla(ByVal cadenaConexion As String, ByVal nombreTabla As String)

Página 112

Docente: Ing. Núñez Marinovich Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación

Conexión ADO.NET a Oracle Al crear el proyecto debemos de agregar la referencia: System.Data.OracleClient

Clase BD_Oracle:Clase que contiene los diferentes metodos ADO.NET using using using using using using

System; System.Collections.Generic; System.Text; System.Data;// uso del datatable System.Data.OracleClient;//Agregamos la referencia System.Windows.Forms;

namespace ADO_Oracle { class BD_Oracle { static public void establecerConexion(String cadenaConexion) {/* * Ejemplos de cadena de conexion: * cadenaConexion = "Data Source=DBODPE;uid=system;pwd=system"; * DBODPE segun el tsname del archivo de oracle: "D:\oracle\product\10.2.0\client_1\NETWORK\ADMIN\tnsnames.ora" * * DBODPE= (DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.40.207)(PORT = 1521)) (CONNECT_DATA = (SERVER = DEDICATED) (SERVICE_NAME = dbodpe) ) ) */ OracleConnection CN = new OracleConnection(cadenaConexion); try { CN.Open();

Página 113

Docente: Ing. Núñez Marinovich Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación MessageBox.Show("Conexion establecida satisfactoriamente." + "\n Estado:" + CN.State.ToString()); CN.Close(); } catch (Exception e) { MessageBox.Show(e.Message + "\n Estado:" + CN.State.ToString()); } } static public int llenarDataGrid(String cadenaConexion , String sentenciaSQL, DataGridView DG) { /* Procedimiento que ejecuta una sentencia SQL y el resultado lo muestra en un dataGrid El procedimiento llena un DataTable mediante una consulta */ try { OracleConnection CN = new OracleConnection(cadenaConexion); OracleDataAdapter DA= new OracleDataAdapter(sentenciaSQL, cadenaConexion); DataTable DT = new DataTable();// actua como un repositorio de la informacion consultada // abre la conexion, ejecuta la consulta, llena el DT y cierra la conexion DA.Fill(DT); DG.DataSource = DT ;//'Hacemos el enlace del DataTable al datagrid (Databind) return DT.Rows.Count; //' numero de filas del DataTable } catch (Exception) { throw; } } static public int llenarDataGrid_DS(String cadenaConexion, String sentenciaSQL, DataGridView DG) { /* Procedimiento que ejecuta una sentencia SQL y el resultado lo muestra en un dataGrid El procedimiento llena un DATASET mediante una consulta */ try { OracleConnection CN = new OracleConnection(cadenaConexion); OracleDataAdapter DA = new OracleDataAdapter(sentenciaSQL, cadenaConexion); DataSet DS = new DataSet();// actua como un repositorio de la informacion consultada // abre la conexion, ejecuta la consulta, llena el DT y cierra la conexion DA.Fill(DS, "Tabla"); DG.DataSource = DS;//'Hacemos el enlace del DataTable al datagrid (Databind) DG.DataMember = "Tabla"; return DS.Tables[0].Rows.Count; } catch (Exception) { throw; } } static public void llenarListBox_DataReader(String cadenaConexion, String sentenciaSQL, String campo, ListBox LB, Boolean limpiarLista = true) { /* Procedimiento que ejecuta una sentencia SQL y el resultado lo muestra en un ListBox En este codigo usamos el objeto DataReader para el acceso rapido y optimo a la BD instancia el objeto y en el constructor le entrego a la cadena de conexion */ try { OracleConnection CN = new OracleConnection(cadenaConexion);

Página 114

Docente: Ing. Núñez Marinovich Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación OracleDataReader DR; OracleCommand CMD = new OracleCommand(sentenciaSQL, CN); //limpiamos la lista por defecto if (limpiarLista) LB.Items.Clear(); CMD.Connection.Open();//Abrimos la conexion DR = CMD.ExecuteReader(); while (DR.Read()){ LB.Items.Add(DR[campo]); } CMD.Connection.Close();//cerramos la conexion } catch (Exception) { throw; } }

static public int ejecutarComando(String cadenaConexion, String sentenciaSQL) { /* ' Funcion que ejecuta una sentencia SQL (Insert , Delete, Update) * y devuelve el total de filas afectadas. */ try { OracleConnection CN = new OracleConnection(cadenaConexion); OracleCommand CMD = new OracleCommand(sentenciaSQL, CN); CN.Open(); //ejecuta la consulta y devolvemos el numero de filas afectadas int totalFilas=CMD.ExecuteNonQuery(); CN.Close(); return totalFilas; } catch (Exception) { throw; } } static public String devolverEscalar(String cadenaConexion, String sentenciaSQL) { /* Funcion que devuelve el resultado de una consulta escalar */ try { OracleConnection CN = new OracleConnection(cadenaConexion); OracleCommand CMD = new OracleCommand(sentenciaSQL, CN); CN.Open(); String resultado = (String) CMD.ExecuteScalar(); CN.Close(); return resultado; } catch (Exception) { throw; } } static public void SP_ejecutarStoreProcedure(String cadenaConexion, String nombreStoreProcedure, String [] nombreParametrosEntrada, String [] valorParametrosEntrada , String [] nombreParametrosSalida, String [] valorParametrosSalida ) { /*' Procedimiento que ejecuta un Store Procedure ' usarlo para sentencias como: Update, Insert, Delete

Página 115

Docente: Ing. Núñez Marinovich Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación */ OracleConnection CN = new OracleConnection(cadenaConexion); //instancio el comando indicando el nombre del procedure y entregandole la conexion OracleCommand CMD = new OracleCommand(nombreStoreProcedure, CN); try{ //'indicamos que el comando es de tipo StoredProcedure CMD.CommandType = CommandType.StoredProcedure; //asignamos los parametros de entrada if (nombreParametrosEntrada !=null) { for (int i = 0; i < nombreParametrosEntrada.GetLength(0); i++) { CMD.Parameters.Add(new OracleParameter((String)nombreParametrosEntrada[i], (String)valorParametrosEntrada[i])); } } //configuramos los parametros de entrada if (nombreParametrosSalida !=null) { OracleParameter PR; for (int i = 0; i < nombreParametrosSalida.GetLength(0); i++) { PR = new OracleParameter(nombreParametrosSalida[i], valorParametrosSalida[i]); PR.Direction = ParameterDirection.Output; PR.Size = 50; CMD.Parameters.Add(PR); } } CMD.Connection.Open(); CMD.ExecuteNonQuery(); //asignamos los resultados a los parametros de salida if (nombreParametrosSalida != null) { for (int i = 0; i < nombreParametrosSalida.GetLength(0); i++) { valorParametrosSalida[i] = (String) CMD.Parameters[nombreParametrosSalida[i]].Value; } } CMD.Connection.Close(); } catch (Exception) { throw; } finally { CMD.Connection.Close(); } } static public Object SP_devolverDataTable(string cadenaConexion, string nombreStoreProcedure, string nombreCursor, string[] nombreParametros = null, string[] valorParametros = null) { // Funcion que devuelve una consulta de un procedimiento almacenado

Página 116

Docente: Ing. Núñez Marinovich Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación OracleConnection cn = new OracleConnection(cadenaConexion); //instancio el comando indicando el nombre del procedure y entregandole la conexion OracleCommand CMD = new OracleCommand(nombreStoreProcedure, cn); //indicamos que el comando es de tipo StoredProcedure CMD.CommandType = CommandType.StoredProcedure; if ((nombreParametros != null)) { int i = 0; for (i = 0; i <= nombreParametros.GetUpperBound(0); i++) { CMD.Parameters.Add(new OracleParameter(nombreParametros[i], valorParametros[i])); } } OracleParameter PR; PR = new OracleParameter(nombreCursor, OracleType.Cursor); //PR.Size = 50; PR.Direction = ParameterDirection.Output; CMD.Parameters.Add(PR);

//le entrego al DA el commando para q este se encargue de ejecutar la consulta OracleDataAdapter DA = new OracleDataAdapter(CMD); DataTable DT = new DataTable(); DA.Fill(DT); //llenamos el DataTable return DT; } static public Object FN_devolverEscalar(string cadenaConexion, string nombreFuncion, string[] nombreParametros = null, string[] valorParametros = null) { // Procedimiento que devuelve el resultado de una funcion Escalar de la BD. // Usarlo tambien para aquellos procedimientos almacenados con instruccion RETURN OracleConnection CN = new OracleConnection(cadenaConexion); OracleCommand CMD = new OracleCommand(nombreFuncion, CN); CMD.CommandType = CommandType.StoredProcedure; if ((nombreParametros != null)) { int i = 0; for (i = 0; i <= nombreParametros.GetUpperBound(0); i++) { CMD.Parameters.Add(new OracleParameter(nombreParametros[i], valorParametros[i])); } } OracleParameter PR = new OracleParameter(); PR = new OracleParameter("resultado", ""); PR.Direction = ParameterDirection.ReturnValue; PR.Size = 100; CMD.Parameters.Add(PR); CMD.Connection.Open(); CMD.ExecuteNonQuery(); CMD.Connection.Close(); return CMD.Parameters["resultado"].Value; } }//fin de la clase }

Página 117

Docente: Ing. Núñez Marinovich Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación Formulario: Para realizar las pruebas de los métodos usados anteriormente.

using using using using using using using

System; System.Collections.Generic; System.ComponentModel; System.Data; System.Drawing; System.Text; System.Windows.Forms;

namespace ADO_Oracle { public partial class Form1 : Form { String strCn; // cadena de conexion public Form1() { InitializeComponent(); } private void Form1_Load(object sender, EventArgs e) { strCn= "Data Source=DBODPEflor;uid=MarketPeru;pwd=mercado"; //cadena de conexion this.textBox1.Text = strCn; } private void btnProbarConexion_Click(object sender, EventArgs e) { //Metodo para probar conexion BD_Oracle.establecerConexion(this.textBox1.Text); } private void btnLlenarGrilla_Click(object sender, EventArgs e) { String sentencia = this.txtConsultaSQL.Text; //Llenamos la grilla mediante un DataTable //int n = BD_Oracle.llenarDataGrid(strCn, sentencia, this.dataGridView1); //Llenamos la grilla mediante un DataSet int n = BD_Oracle.llenarDataGrid_DS(strCn, sentencia, this.dataGridView1); MessageBox.Show(n.ToString());// muestre el numero de filas retornadas de la consulta } private void btnRecorrerDataReader_Click(object sender, EventArgs e) {

Página 118

Docente: Ing. Núñez Marinovich Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación String sentencia = "select * from categoria order by categoria"; BD_Oracle.llenarListBox_DataReader (strCn, sentencia, "categoria",this.listBox1); } private void btnEjecutarCMD_Click(object sender, EventArgs e) { String consultaSQL="insert into categoria(idcategoria, categoria, descripcion)" + " VALUES(20, 'Cat01', NULL) "; BD_Oracle.ejecutarComando(strCn, consultaSQL); MessageBox.Show("INSERT OK"); } private void btnDevolverScalar_Click(object sender, EventArgs e) { String sentencia = "select categoria from categoria where idcategoria=1"; MessageBox.Show(BD_Oracle.devolverEscalar(strCn, sentencia)); } private void btnEjecutarStoreProcedure_Click(object sender, EventArgs e) { //ejecuta un procedimiento que devuelve 2 parametros de salida: stock actual y stock minimo String[] NPE = {"pi_idProducto"}; String[] VPE = {"3"};//valor del id del producto String[] NPS = { "po_stockActual", "po_stockMinimo" }; String[] VPS = {"",""}; BD_Oracle.SP_ejecutarStoreProcedure(strCn, "PaqueteGuia.SP_StockProducto", NPE, VPE, NPS, VPS); String resultado; resultado="Stock Actual: " + VPS[0] + "\n Stock Minimo: " + VPS[1]; MessageBox.Show(resultado); } private void btnDevolverDataTableStoreProcedure_Click(object sender, EventArgs e) { DataTable DT; DT = (DataTable)BD_Oracle.SP_devolverDataTable(strCn, "PaqueteGuia.SP_ReporteSalidasxDia", "po_curResultado", null, null); this.dataGridView1.DataSource = DT; } private void btnDevolverEscalar_FuncionOracle_Click(object sender, EventArgs e) { //ejecuta un procedimiento que devuelve 2 parametros de salida: stock actual y stock minimo String[] NPE = { "fecha1", "fecha2" }; String[] VPE = { "28/08/2011","31/08/2011" }; String resultado; resultado = (String) BD_Oracle.FN_devolverEscalar(strCn, "PaqueteGuia.FN_MontoGuia", NPE,

VPE); MessageBox.Show(resultado); } }

}

Página 119

Docente: Ing. Núñez Marinovich Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación

Conexión ADO.NET a MySQL A continuación se desarrolla una clase para al conexión a MySQL, la cual contiene funciones y procedimientos muy parecidos a los desarrollados en la conexión de ADO.NET a SQL Server. Muy importante agregar el conector de MySQL para VS.NET, lo extraemos de: http://sourceforge.net/projects/mysqldrivercs/

No olvidar tambien importar el espacio de nombres: Imports MySQLDriverCS Codigo: Imports MySQLDriverCS #Region "Conexion a MySQL" Public Class BD_MySQL

'El conector de MySQL con VS.NET 'http://dev.mysql.com/downloads/connector/j/3.1.html 'http://sourceforge.net/projects/mysqldrivercs/ 'Agregar Referencia: MySQLDriverCS Shared Function devuelveDato(ByVal campo) If IsDBNull(campo) Then devuelveDato = "" Else devuelveDato = campo End If End Function #Region "Generar Cadena Conexion" Shared Function generarCadenaConexionMySQL(ByVal BaseDatos As String, _ Optional ByVal Servidor As String = "localhost", _ Optional ByVal Usuario As String = "root", Optional ByVal Contraseña As String = "", _ Optional ByVal nroPuerto As String = "3306", _ Optional ByVal parametrosAdicionales As String = "") 'Genera la cadena de conexion a MySQL Dim cadenaConexion As String cadenaConexion = _ "Provider=MySQLProv" & _ "; Location=" & Servidor & _ "; Data Source=" & BaseDatos & _ "; User Id=" & Usuario & _ "; Password=" & Contraseña & _ "; Port=" & nroPuerto & _ "; " & parametrosAdicionales Return cadenaConexion '"Data Source=BDMediciones_dbo;Password=321814;User ID=root;Location=190.41.140.220;Port=3306;Extended Properties=""" 'http://www.connectionstrings.com/mysql 'Server=serverAddress1 & serverAddress2 & etc..;Database=myDataBase;Uid=myUsername;Pwd=myPassword; 'Server=myServerAddress;Database=myDataBase;Uid=myUsername;Pwd=myPassword;Encryption=true; 'Server=myServerAddress;Database=myDataBase;Uid=myUsername;Pwd=myPassword;Encrypt=true; 'Server=myServerAddress;Database=myDataBase;Uid=myUsername;Pwd=myPassword;Connection Timeout=5;

Página 120

Docente: Ing. Núñez Marinovich Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación 'User ID=root;Password=myPassword;Host=localhost;Port=3306;Database=myDataBase; Direct=true;Protocol=TCP;Compress=false;Pooling=true;Min Pool Size=0;Max Pool Size=100;Connection Lifetime=0; End Function #End Region Function Optional Optional Optional Optional

verificarConexionBD(ByVal BaseDatos As String, _ ByVal Servidor As String = "localhost", _ ByVal Usuario As String = "root", _ ByVal Password As String = "", _ ByVal Puerto As String = "3306") As Boolean

'Creamos un objeto de tipo Connection y configuramos los parámetros de la conexión Dim DBCon As MySQLConnection 'Los parámetros de la sobrecarga con más parámetros son: '1. Dirección IP o nombre de la máquina con el servidor de MySQLS '2. Nombre de la base de datos '3. Nombre de usuario con acceso a la base de datos señalada anteriormente '4. Contraseña para el nombre de usuario citado '5. Puerto por el que se acede al servidor. Típicamente 3306 'DBCon = New MySQLConnection(New MySQLConnectionString("192.168.0.1", "net", "root", "xxxxxxxxx", 3306).As String) 'DBCon = New MySQLConnection(New MySQLConnectionString("localhost", "northwind", "root", "pni", 3306).As String) DBCon = New MySQLConnection(New MySQLConnectionString(Servidor, BaseDatos, Usuario, Password, Puerto).As String) Dim resultado As Boolean Try 'Abrimos la conexión y comprobamos que no hay error DBCon.Open() resultado = True DBCon.Close() Catch ex As MySQLException 'Si hubiese error en la conexión mostramos el texto de la descripción 'MsgBox(ex.Message.ToString) resultado = False End Try Return resultado End Function #Region "Devolver Mayor - Menor Valor de Campo" Function devolverMayorValorCampo(ByVal cadenaConexion As String, ByVal nombreTabla As String, ByVal nombreCampo As String) ' Funcion que retorna el mayor valor de un campo de una Tabla Dim sentenciaSQL As String sentenciaSQL = _ "select " & nombreCampo & " from " & nombreTabla & _ " order by " & nombreCampo & " desc limit 1 " Return devolverCelda(cadenaConexion, sentenciaSQL, nombreTabla, nombreCampo) End Function Function devolverMenorValorCampo(ByVal cadenaConexion As String, ByVal nombreTabla As String, ByVal nombreCampo As String) ' Funcion que retorna el menor valor de un campo de una Tabla Dim sentenciaSQL As String sentenciaSQL = _ "select " & nombreCampo & " from " & nombreTabla & _ " order by " & nombreCampo & " asc limit 1 " Return devolverCelda(cadenaConexion, sentenciaSQL, nombreTabla, nombreCampo) End Function #End Region

Página 121

Docente: Ing. Núñez Marinovich Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación #Region "Funciones Booleanas" Public Function esTablaVacia(ByVal cadenaConexion As String, ByVal nombreTabla As String) As Boolean ' Funcion que devuelve Verdadero si la tabla es vacia, ' si la tabla tuviera datos, devuelve false Dim CN As New MySQLConnection(cadenaConexion) Dim DA As New MySQLDataAdapter("select * from " & nombreTabla, CN) Dim DT As New DataTable ' actua como un repositorio de la informacion consultada ' abre la conexion, ejecuta la consulta, llena el DT y cierra la conexion DA.Fill(DT) If DT.Rows.Count > 0 Then ' La tabla si tiene datos Return False Else ' La tabla no tiene Datos Return True End If End Function Public Function esConsultaVacia(ByVal cadenaConexion As String, ByVal sentencia As String) As Boolean ' Funcion que devuelve Verdadero si la tabla es vacia, ' si la tabla tuviera datos, devuelve false Dim CN As New MySQLConnection(cadenaConexion) Dim DA As New MySQLDataAdapter(sentencia, CN) Dim DT As New DataTable ' actua como un repositorio de la informacion consultada ' abre la conexion, ejecuta la consulta, llena el DT y cierra la conexion DA.Fill(DT) If DT.Rows.Count > 0 Then ' La tabla si tiene datos Return False Else ' La tabla no tiene Datos Return True End If End Function Public Function verificarExistenciaDato(ByVal cadenaConexion As String, ByVal nombreTabla As String, ByVal nombreCampo As String, ByVal dato_a_buscar As String) As Boolean 'Verifica si existe cierto dato en la BD, ingresando el nombre del campo y el dato a buscar Dim CN As New MySQLConnection(cadenaConexion) Dim sentencia As String Try sentencia = "select count(" & nombreCampo & ") from " & nombreTabla & " where " & _ nombreCampo & " = '" & dato_a_buscar & "'" Dim Cmd As New MySQLCommand(sentencia, CN) CN.Open() Dim n As Integer = Cmd.ExecuteScalar CN.Close() If n >= 1 Then ' existe algun elemento Return True Else ' no existe en la tabla del campo especificado dicho elemento Return False End If Catch ex As Exception MsgBox(ex.Message) CN.Close() Return False End Try End Function #End Region

Página 122

Docente: Ing. Núñez Marinovich Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación #Region "Devolver Total registros: Tabla, Consulta" Public Function totalRegistrosTabla(ByVal cadenaConexion As String, ByVal nombreTabla As String) ' Funcion que devuelve el numero de registros de una Tabla Dim sentencia As String = "select count(*) from " & nombreTabla ' retorna el numero de registros de una Tabla Return devolverEscalar(cadenaConexion, sentencia) End Function Public Function totalRegistrosConsulta(ByVal cadenaConexion As String, ByVal sentenciaSQL As String) ' Funcion que devuelve el numero de registros de una consulta Dim CN As New MySQLConnection(cadenaConexion) Dim DA As New MySQLDataAdapter(sentenciaSQL, CN) Dim DT As New DataTable ' actua como un repositorio de la informacion consultada ' abre la conexion, ejecuta la consulta, llena el DT y cierra la conexion DA.Fill(DT) ' retorna el numero de registros de una consulta Return DT.Rows.Count End Function #End Region #Region "Devolver DataTable, DataRow, DataColumn,Celda,Escalar,Matriz Bidimensional" Function devolverDataTable(ByVal cadenaConexion As String, ByVal sentenciaSQL As String) ' Funcion que ejecuta una sentencia SQL y el resultado lo muestra en un dataGrid ' El procedimiento llena un DataTable mediante una consulta Dim CN As New MySQLConnection(cadenaConexion) Dim DA As New MySQLDataAdapter(sentenciaSQL, CN) Dim DT As New DataTable ' actua como un repositorio de la informacion consultada ' abre la conexion, ejecuta la consulta, llena el DT y cierra la conexion DA.Fill(DT) Return DT 'devolvemos el dataTable End Function Function devolverDataRow(ByVal cadenaConexion As String, ByVal sentenciaSQL As String, Optional ByVal indice As Integer = 0) ' Funcion que devuelve un DataRow, es decir de una determinada consulta, devuelve los campos de ' una determinada fila(por defecto la primera). Dim CN As New MySQLConnection CN.ConnectionString = cadenaConexion ' Creamos el adaptador Dim DA As New MySQLDataAdapter(sentenciaSQL, CN) ' Creamos el DataSet Dim DS As New DataSet ' abrimos la conexion, llenamos el DataSet y cerramos la conexion CN.Open() DA.Fill(DS, "Tabla") CN.Close() Dim DR As DataRow DR = DS.Tables("Tabla").Rows(indice) Return DR End Function Function devolverDataColumn(ByVal cadenaConexion As String, ByVal sentenciaSQL As String, ByVal tabla As String, Optional ByVal indice As Integer = 0) ' Funcion que devuelve un DataColumn , es decir de una determinada consulta, devuelve los campos de ' una determinada columna (por defecto la primera). Dim CN As New MySQLConnection CN.ConnectionString = cadenaConexion ' Creamos el adaptador Dim DA As New MySQLDataAdapter(sentenciaSQL, CN)

Página 123

Docente: Ing. Núñez Marinovich Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación ' Creamos el DataSet Dim DS As New DataSet ' abrimos la conexion, llenamos el DataSet y cerramos la conexion CN.Open() DA.Fill(DS, tabla) CN.Close() Dim DC As DataColumn DC = DS.Tables(tabla).Columns(indice) Return DC End Function Function devolverCelda(ByVal cadenaConexion As String, ByVal sentenciaSQL As String, ByVal tabla As String, ByVal nombreCampo As String, Optional ByVal indice As Integer = 0) ' Funcion que devuelve una celda, es decir de una determinada consulta, devuelve ' el valor de un dterminado campo, de una determinada fila(por defecto la primera). Try Dim CN As New MySQLConnection CN.ConnectionString = cadenaConexion ' Creamos el adaptador Dim DA As New MySQLDataAdapter(sentenciaSQL, CN) ' Creamos el DataSet Dim DS As New DataSet ' Abrimos la conexion, llenamos el DataSet y cerramos la conexion CN.Open() DA.Fill(DS, tabla) CN.Close() Dim DR As DataRow DR = DS.Tables(tabla).Rows(indice) Return devuelveDato(DR.Item(nombreCampo)) Catch ex As Exception Return ex.Message() End Try End Function

#Region "Devolver Escalar" Function devolverEscalar(ByVal cadenaConexion As String, ByVal sentenciaSQL As String) Dim CN As New MySQLConnection(cadenaConexion) Dim Cmd As New MySQLCommand(sentenciaSQL, CN) Try CN.Open() ' ejecuta la consulta y devolvemos la primera columna de la 'primera fila del conjunto de resultado devuelto por la consulta Return devuelveDato(Cmd.ExecuteScalar) CN.Close() Catch ex As MySQLException MsgBox(ex.Message) End Try End Function Function devolverEscalar(ByVal cadenaConexion As String, _ ByVal Tabla As String, ByVal campo_a_devolver As String, _ ByVal condicion As String) ' Funcion que deuelve el resultado de una consulta Dim sentenciaSQL As String sentenciaSQL = "select " & campo_a_devolver & " from " & Tabla & " where " & condicion Dim CN As New MySQLConnection(cadenaConexion) Dim Cmd As New MySQLCommand(sentenciaSQL, CN) Try CN.Open() ' ejecuta la consulta y devolvemos la primera columna de la 'primera fila del conjunto de resultado devuelto por la consulta Return devuelveDato(Cmd.ExecuteScalar) CN.Close()

Página 124

Docente: Ing. Núñez Marinovich Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación Catch ex As SqlException MsgBox(ex.Message) End Try End Function Function devolverEscalar(ByVal cadenaConexion As String, _ ByVal Tabla As String, ByVal campo_a_devolver As String, _ ByVal campoCondicion As String, ByVal valorCondicion As String) ' Funcion que deuelve el resultado de una consulta Dim sentenciaSQL As String sentenciaSQL = "select " & campo_a_devolver & " from " & Tabla & _ " where " & campoCondicion & "='" & valorCondicion & "'" Dim CN As New MySQLConnection(cadenaConexion) Dim Cmd As New MySQLCommand(sentenciaSQL, CN) Try CN.Open() ' ejecuta la consulta y devolvemos la primera columna de la 'primera fila del conjunto de resultado devuelto por la consulta Return devuelveDato(Cmd.ExecuteScalar) CN.Close() Catch ex As SqlException MsgBox(ex.Message) End Try End Function #End Region

Function devolverMatrizBidimensional(ByVal cadenaConexion As String, ByVal sentenciaSQL As String, _ Optional ByVal incluirCabecerasColumna As Boolean = False, _ Optional ByVal CabecerasColumna() As String = Nothing) ' Funcion que ejecuta una sentencia SQL y el resultado lo muestra en un dataGrid ' El procedimiento llena un DataTable mediante una consulta Dim CN As New MySQLConnection(cadenaConexion) Dim DA As New MySQLDataAdapter(sentenciaSQL, CN) Dim DT As New DataTable ' actua como un repositorio de la informacion consultada ' abre la conexion, ejecuta la consulta, llena el DT y cierra la conexion DA.Fill(DT) Return devolverMatrizBidimensional(DT, incluirCabecerasColumna, CabecerasColumna) End Function Function devolverMatrizBidimensional(ByVal DT As DataTable, _ Optional ByVal incluirCabecerasColumna As Boolean = False, _ Optional ByVal CabecerasColumna() As String = Nothing) ' Funcion que el contenido de un DataTable lo pasa a una matriz Dim i, j, nroColumnas, nroFilas As Integer nroColumnas = DT.Columns.Count nroFilas = DT.Rows.Count Dim matriz(,) As String If incluirCabecerasColumna Then ReDim matriz(nroFilas, nroColumnas - 1) If CabecerasColumna Is Nothing Then ' ponemos las cabeceras propias del DataTable For j = 0 To nroColumnas - 1 matriz(0, j) = DT.Columns(j).Caption Next For i = 0 To nroFilas - 1 For j = 0 To nroColumnas - 1 matriz(i + 1, j) = DT.Rows(i).Item(j).ToString() Next Next Else For j = 0 To nroColumnas - 1

Página 125

Docente: Ing. Núñez Marinovich Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación matriz(0, j) = CabecerasColumna(j) Next For i = 0 To nroFilas - 1 For j = 0 To nroColumnas - 1 matriz(i + 1, j) = DT.Rows(i).Item(j).ToString() Next Next ' ponemos las cabeceras de columna ingresadas en el argumento End If Else ' no incluimos cabeceras de columna ReDim matriz(nroFilas - 1, nroColumnas - 1) For i = 0 To nroFilas - 1 For j = 0 To nroColumnas - 1 matriz(i, j) = DT.Rows(i).Item(j).ToString() Next Next End If Return matriz End Function

Function devolverColumna_ComoLista _ (ByVal cadenaConexion As String, ByVal sentenciaSQL As String, _ Optional ByVal nroColumna As Integer = 0) Dim DT As New DataTable DT = devolverDataTable(cadenaConexion, sentenciaSQL) Dim i, nroFilas As Integer nroFilas = DT.Rows.Count Dim listaResultado(nroFilas - 1) As String For i = 0 To nroFilas - 1 listaResultado(i) = DT.Rows(i).Item(nroColumna).ToString Next Return listaResultado End Function Function devolverColumna_ComoString _ (ByVal cadenaConexion As String, ByVal sentenciaSQL As String, _ Optional ByVal nroColumna As Integer = 0) Dim DT As New DataTable DT = devolverDataTable(cadenaConexion, sentenciaSQL) Dim i, nroFilas As Integer nroFilas = DT.Rows.Count Dim cadenaResultado As String For i = 0 To nroFilas - 1 If i = nroFilas - 1 Then ' si es el ultimo q ya no ponga vbcrlf cadenaResultado &= DT.Rows(i).Item(nroColumna).ToString Else cadenaResultado &= DT.Rows(i).Item(nroColumna).ToString & vbCrLf End If Next Return cadenaResultado End Function

Public Function devolverMatrizResumenContenido1BD(ByVal nombreBaseDatos As String, _ Optional ByVal cadenaConexion As String = "", _ Optional ByVal usuario As String = "root", Optional ByVal contraseña As String = "") As String() ' devuelve una matriz resumen de lo que contiene una BD, indicando: ' Nombre de la BD Nro Tablas - NroColumnas - NroFilas Dim matrizResultado(3) As String Dim i As Integer If cadenaConexion = "" Then

Página 126

Docente: Ing. Núñez Marinovich Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación cadenaConexion End If matrizResultado(0) matrizResultado(1) matrizResultado(2) matrizResultado(3)

= Me.generarCadenaConexionMySQL(nombreBaseDatos, , usuario, contraseña) = = = =

nombreBaseDatos Me.totalTablas(cadenaConexion, nombreBaseDatos) Me.totalCamposBD(cadenaConexion, nombreBaseDatos) Me.totalRegistrosBD(cadenaConexion, nombreBaseDatos)

Return matrizResultado End Function

Public Function devolverMatrizResumenContenidoBDs(Optional ByVal usuario As String = "root", _ Optional ByVal contraseña As String = "") As String(,) ' devuelve una matriz resumen de lo que contiene una BD, indicando: ' Nombre de la BD Nro Tablas - NroColumnas - NroFilas Dim listaBD() As String Dim cadenaConexion, nombreBaseDatos As String cadenaConexion = Me.generarCadenaConexionMySQL("test", , usuario, contraseña) listaBD = Me.listarBasesDatos(cadenaConexion) Dim matrizResultado(listaBD.GetUpperBound(0) - 4, 3) As String Dim i, cont As Integer cont = 0 For i = 0 To listaBD.GetUpperBound(0) nombreBaseDatos = listaBD(i) cadenaConexion = Me.generarCadenaConexionMySQL(nombreBaseDatos, , usuario, contraseña) If Not (nombreBaseDatos = "information_schema" Or nombreBaseDatos = "mysql" _ Or nombreBaseDatos = "phpmyadmin" Or nombreBaseDatos = "test") Then matrizResultado(cont, matrizResultado(cont, matrizResultado(cont, matrizResultado(cont, cont += 1 End If

0) 1) 2) 3)

= = = =

nombreBaseDatos Me.totalTablas(cadenaConexion, nombreBaseDatos) Me.totalCamposBD(cadenaConexion, nombreBaseDatos) Me.totalRegistrosBD(cadenaConexion, nombreBaseDatos)

Next Return matrizResultado End Function #End Region

#Region "Total Bases de Datos - Tablas - Campos BD" Function totalBasesDatos(ByVal cadenaConexion As String) As Integer ' Funcion que devuelve el total de Base de Datos en MySQL Return Me.listarBasesDatos(cadenaConexion).GetLongLength(0) End Function Function totalTablas(ByVal cadenaConexion As String, ByVal NombreBaseDatos As String ) As Integer ' Funcion que devuelve el total de las tablas de ' una determinada Base de Datos en MySQL Return Me.listarTablas(cadenaConexion, NombreBaseDatos).GetLongLength(0) End Function Function totalColumnasTabla(ByVal cadenaConexion As String, ByVal nombreTabla As String) As Integer ' Funcion que lista los campos de una determinada tabla de una base de datos Return Me.listarCampos(cadenaConexion, nombreTabla).GetLongLength(0) End Function

Página 127

Docente: Ing. Núñez Marinovich Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación Public Function totalCamposBD(ByVal cadenaConexion As String, ByVal nombreBaseDatos As String) As Integer ' Devuelve la suma del total de campos de toda la BD Dim listaTablas() As String listaTablas = Me.listarTablas(cadenaConexion, nombreBaseDatos) If listaTablas Is Nothing Then Return 0 Dim i As Integer Dim resultado As Long For i = 0 To listaTablas.GetUpperBound(0) resultado += Me.totalColumnasTabla(cadenaConexion, listaTablas(i)) Next Return resultado End Function Public Function totalRegistrosBD(ByVal cadenaConexion As String, ByVal nombreBaseDatos As String) As Long ' Devuelve la suma del total de registros de toda la BD Dim listaTablas() As String listaTablas = Me.listarTablas(cadenaConexion, nombreBaseDatos) If listaTablas Is Nothing Then Return 0 Dim i As Integer Dim resultado As Long For i = 0 To listaTablas.GetUpperBound(0) resultado += totalRegistrosTabla(cadenaConexion, listaTablas(i)) Next Return resultado End Function #End Region #Region "Devolver al azar"

Function devolverEscalar_al_azar(ByVal cadenaConexion As String, _ ByVal Tabla As String, ByVal campo_a_devolver As String ) ' Funcion que devuelve el resultado de una consulta Dim sentenciaSQL As String sentenciaSQL = "select " & campo_a_devolver & " from " & Tabla & " ORDER BY RAND() limit 1 " Dim CN As New MySQLConnection(cadenaConexion) Dim Cmd As New MySQLCommand(sentenciaSQL, CN) Try CN.Open() ' ejecuta la consulta y devolvemos la primera columna de la 'primera fila del conjunto de resultado devuelto por la consulta Return devuelveDato(Cmd.ExecuteScalar) CN.Close() Catch ex As SqlException MsgBox(ex.Message) End Try End Function #End Region #Region "DataGrid" Sub llenarDataGrid_DataSet(ByVal cadenaConexion As String, ByVal sentenciaSQL As String, ByVal dataGrid As DataGrid) ' Procedimiento que ejecuta una sentencia SQL y el resultado lo muestra en un dataGrid ' El procedimiento llena un DataTable mediante una consulta Dim CN As New MySQLConnection(cadenaConexion) Dim DA As New MySQLDataAdapter(sentenciaSQL, CN) Dim DS As New DataSet ' actua como un repositorio de la informacion consultada

Página 128

Docente: Ing. Núñez Marinovich Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación ' abre la conexion, ejecuta la consulta, llena el DT y cierra la conexion DA.Fill(DS, "Tabla") dataGrid.DataSource = DS 'HAcemos el enlace del DataTable al datagrid (Databind) 'dt.Rows.Count ' numero de filas del DataTable dataGrid.DataMember = "Tabla" End Sub Sub redimensionarDatagrid_DataSet(ByVal DG As DataGrid, ByVal arregloDimensiones() As Integer, Optional ByVal arregloCabecerasTexto() As String = Nothing) Dim TableStyle1 As New DataGridTableStyle Dim COLUMNA As New DataGridTextBoxColumn Dim DS As New DataSet Dim j As Integer DS = DG.DataSource DG.TableStyles.Clear() TableStyle1.MappingName = DS.Tables(0).TableName TableStyle1.AlternatingBackColor = DG.AlternatingBackColor TableStyle1.BackColor = DG.BackColor TableStyle1.HeaderBackColor = DG.HeaderBackColor TableStyle1.HeaderForeColor = DG.HeaderForeColor TableStyle1.ForeColor = DG.ForeColor TableStyle1.SelectionBackColor = DG.SelectionBackColor TableStyle1.GridLineColor = DG.GridLineColor If DS.Tables(0).Columns.Count = UBound(arregloDimensiones) + 1 Then For j = 0 To DS.Tables(0).Columns.Count - 1 COLUMNA = New DataGridTextBoxColumn COLUMNA.MappingName = DS.Tables(0).Columns(j).ToString If arregloCabecerasTexto Is Nothing Then COLUMNA.HeaderText = DS.Tables(0).Columns(j).ToString Else COLUMNA.HeaderText = arregloCabecerasTexto(j) End If COLUMNA.Width = arregloDimensiones(j) TableStyle1.GridColumnStyles.Add(COLUMNA) Next Else MsgBox("Ingrese dimensiones completas") End If DG.TableStyles.Add(TableStyle1) End Sub Sub llenarDataGrid(ByVal cadenaConexion As String, ByVal sentenciaSQL As String, ByVal dataGrid As DataGrid) ' Procedimiento que ejecuta una sentencia SQL y el resultado lo muestra en un dataGrid ' El procedimiento llena un DataTable mediante una consulta Dim CN As New MySQLConnection(cadenaConexion) Dim DA As New MySQLDataAdapter(sentenciaSQL, CN) Dim DT As New DataTable ' actua como un repositorio de la informacion consultada ' abre la conexion, ejecuta la consulta, llena el DT y cierra la conexion DA.Fill(DT) dataGrid.DataSource = DT 'HAcemos el enlace del DataTable al datagrid (Databind) 'dt.Rows.Count ' numero de filas del DataTable End Sub Sub redimensionarDatagrid(ByVal DG As DataGrid, ByVal arregloDimensiones() As Integer, Optional ByVal arregloCabecerasTexto() As String = Nothing) Dim TableStyle1 As New DataGridTableStyle Dim COLUMNA As New DataGridTextBoxColumn Dim DT As New DataTable Dim j As Integer DT = DG.DataSource

Página 129

Docente: Ing. Núñez Marinovich Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación DG.TableStyles.Clear() TableStyle1.MappingName = DT.TableName TableStyle1.AlternatingBackColor = DG.AlternatingBackColor TableStyle1.BackColor = DG.BackColor TableStyle1.HeaderBackColor = DG.HeaderBackColor TableStyle1.HeaderForeColor = DG.HeaderForeColor TableStyle1.ForeColor = DG.ForeColor TableStyle1.SelectionBackColor = DG.SelectionBackColor TableStyle1.GridLineColor = DG.GridLineColor

If DT.Columns.Count = UBound(arregloDimensiones) + 1 Then For j = 0 To DT.Columns.Count - 1 COLUMNA = New DataGridTextBoxColumn COLUMNA.MappingName = DT.Columns(j).ToString If arregloCabecerasTexto Is Nothing Then COLUMNA.HeaderText = DT.Columns(j).ToString Else COLUMNA.HeaderText = arregloCabecerasTexto(j) End If COLUMNA.Width = arregloDimensiones(j) TableStyle1.GridColumnStyles.Add(COLUMNA) Next Else MsgBox("Ingrese dimensiones completas.") End If DG.TableStyles.Add(TableStyle1) End Sub Sub llenarDataGridTablas(ByVal cadenaConexion As String, ByVal sentenciasSQL() As String, ByVal dataGrid As DataGrid, Optional ByVal nombreTablas() As String = Nothing) ' Procedimiento que muestra en un dataGrid varias tablas ' El procedimiento llena un DataTable mediante varias consultas ingresadas en un arreglo Dim i As Integer Dim CN As New MySQLConnection(cadenaConexion) Dim DA As MySQLDataAdapter Dim DS As New DataSet For i = 0 To sentenciasSQL.GetUpperBound(0) DA = New MySQLDataAdapter(sentenciasSQL(i), CN) If nombreTablas Is Nothing Then 'Si no se ingreso el nombre de las tablas DA.Fill(DS, "Tabla " & i + 1) Else 'Si se ingreso el nombre de las tablas DA.Fill(DS, nombreTablas(i)) End If Next dataGrid.DataSource = DS End Sub Sub llenarDataGrid2TablasRelacionadas(ByVal cadenaConexion As String, ByVal nombreTabla1 As String, ByVal nombreTabla2 As String, ByVal campoEnlace As String, ByVal dataGrid As DataGrid, Optional ByVal nombreRelacion As String = "") ' Procedimiento que muestra en un dataGrid 2 Tablas Relacionadas Dim i As Integer Dim CN As New MySQLConnection CN.ConnectionString = cadenaConexion ' Crear Adaptadores Dim DA1 As New MySQLDataAdapter("select * from " & CStr(nombreTabla1), CN) Dim DA2 As New MySQLDataAdapter("select * from " & CStr(nombreTabla2), CN) ' Crear DataSet Dim DS As New DataSet DA1.Fill(DS, nombreTabla1) DA2.Fill(DS, nombreTabla2) ' Relacionar las dos tablas del dataset por el campo comun

Página 130

Docente: Ing. Núñez Marinovich Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación DS.Relations.Add( _ nombreRelacion, _ DS.Tables(nombreTabla1).Columns(campoEnlace), _ DS.Tables(nombreTabla2).Columns(campoEnlace) _ ) dataGrid.DataSource = DS End Sub Sub llenarDataGrid2TablasRelacionadas_Consultas(ByVal cadenaConexion As String, ByVal consultaSQL1 As String, ByVal consultaSQL2 As String, ByVal campoEnlace As String, ByVal dataGrid As DataGrid, Optional ByVal nombreRelacion As String = "") ' Procedimiento que muestra en un dataGrid 2 Tablas Relacionadas Dim i As Integer Dim CN As New MySQLConnection CN.ConnectionString = cadenaConexion ' Crear Adaptadores Dim DA1 As New MySQLDataAdapter(consultaSQL1, CN) Dim DA2 As New MySQLDataAdapter(consultaSQL2, CN) ' Crear DataSet Dim DS As New DataSet DA1.Fill(DS, "Tabla1") DA2.Fill(DS, "Tabla2") ' Relacionar las dos tablas del dataset por el campo comun DS.Relations.Add( _ nombreRelacion, _ DS.Tables("Tabla1").Columns(campoEnlace), _ DS.Tables("Tabla2").Columns(campoEnlace) _ ) dataGrid.DataSource = DS End Sub #End Region #Region "ListView" Sub llenarListView_con_DataTable(ByVal DT As DataTable, ByVal LV As ListView, _ Optional ByVal cabeceras() As String = Nothing, Optional ByVal enumerarFilas As Boolean = False) ' Procedimiento que llena un dataTable en un ListView Dim i, j As Integer LV.Items.Clear() LV.View = View.Details LV.FullRowSelect = True ' permite la seleccion de toda una fila 'lv.GridLines = True ' muestra el listview una grilla LV.AllowColumnReorder = True ' permite cambiarle el orden de aparicion de las columnas If Not cabeceras Is Nothing Then LV.Columns.Clear() For i = 0 To cabeceras.GetUpperBound(0) LV.Columns.Add(cabeceras(i), 100, HorizontalAlignment.Center) Next End If Dim ls As ListViewItem If enumerarFilas Then ' enumeramos las filas en la primera columna del listview For i = 0 To DT.Rows.Count - 1 ls = LV.Items.Add(i + 1) For j = 0 To DT.Columns.Count - 1 ls.SubItems.Add(DT.Rows(i).Item(j).ToString) Next Next Else ' No enumeramos las filas For i = 0 To DT.Rows.Count - 1 ls = LV.Items.Add(DT.Rows(i).Item(0).ToString) For j = 1 To DT.Columns.Count - 1 ls.SubItems.Add(DT.Rows(i).Item(j).ToString) Next

Página 131

Docente: Ing. Núñez Marinovich Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación Next End If End Sub Sub llenarListView(ByVal cadenaConexion As String, ByVal sentenciaSQL As String, _ ByVal listaCampos() As String, ByVal ListView As ListView, _ Optional ByVal cabeceraColumna() As String = Nothing, _ Optional ByVal enumerarFilas As Boolean = False, _ Optional ByVal anchoColumna() As Integer = Nothing, _ Optional ByVal alineamientoColumna() As HorizontalAlignment = Nothing) ' Procedimiento que ejecuta una sentencia SQL ' y el resultado lo muestra en un listView Dim CN As New MySQLConnection(cadenaConexion) Dim CMD As New MySQLCommand(sentenciaSQL, CN) Dim DR As MySQLDataReader Dim ls As ListViewItem Dim i As Integer Try ' Configuramos el ListView ListView.View = View.Details ListView.FullRowSelect = True ' permite la seleccion de toda una fila 'ListView.GridLines = True ' muestra el listview una grilla ListView.AllowColumnReorder = True ' permite cambiarle el orden de aparicion de las columnas ' Limpiampos las columnas y los items dentro del ListView ListView.Columns.Clear() ListView.Items.Clear() If enumerarFilas Then ' Enumeramos las filas ' llenamos las cabeceras de columna del ListView ListView.Columns.Add("Nro", 40, HorizontalAlignment.Center) For i = 0 To listaCampos.GetUpperBound(0) ListView.Columns.Add(listaCampos(i), 100, HorizontalAlignment.Left) Next CN.Open() DR = CMD.ExecuteReader() ' llenamos el ListView con los datos del dataReader Dim reg As Integer = 0 While DR.Read 'ls = ListView.Items.Add(Trim(DR.Item(listaCampos(0)))) reg += 1 ls = ListView.Items.Add(reg) For i = 0 To listaCampos.GetUpperBound(0) ls.SubItems.Add(DR.Item(listaCampos(i).ToString).ToString) Next End While CN.Close() Else ' No enumeramos las filas ' llenamos las cabeceras de columna del ListView For i = 0 To listaCampos.GetUpperBound(0) ListView.Columns.Add(listaCampos(i), 100, HorizontalAlignment.Center) Next CN.Open() DR = CMD.ExecuteReader() ' llenamos el ListView con los datos del dataReader While DR.Read ls = ListView.Items.Add(DR.Item(listaCampos(0)).ToString) For i = 1 To listaCampos.GetUpperBound(0) ls.SubItems.Add(DR.Item(listaCampos(i)).ToString) Next End While CN.Close() End If If Not cabeceraColumna Is Nothing Then For i = 0 To listaCampos.GetUpperBound(0)

Página 132

Docente: Ing. Núñez Marinovich Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación ListView.Columns.Item(i).Text = cabeceraColumna(i).Trim Next End If If Not anchoColumna Is Nothing Then For i = 0 To listaCampos.GetUpperBound(0) ListView.Columns.Item(i).Width = anchoColumna(i) Next End If If Not alineamientoColumna Is Nothing Then For i = 0 To listaCampos.GetUpperBound(0) ListView.Columns.Item(i).TextAlign = alineamientoColumna(i) Next End If Catch ex As MySQLException MsgBox(ex.Message) End Try End Sub Sub llenarListView(ByVal cadenaConexion As String, ByVal sentenciaSQL As String, ByVal ListView As ListView, _ Optional ByVal cabeceras() As String = Nothing, Optional ByVal enumerarFilas As Boolean = False) ' Procedimiento que ejecuta una sentencia SQL y el resultado lo muestra en un ListView ' El procedimiento llena un ListView mediante una consulta Dim CN As New MySQLConnection(cadenaConexion) Dim DA As New MySQLDataAdapter(sentenciaSQL, CN) Dim DT As New DataTable ' actua como un repositorio de la informacion consultada ' abre la conexion, ejecuta la consulta, llena el DT y cierra la conexion DA.Fill(DT) llenarListView_con_DataTable(DT, ListView, cabeceras, enumerarFilas) End Sub #End Region #Region "TreeView" Sub llenarCamposTreeView(ByVal cadenaConexion As String, ByVal listaCampos() As String, ByVal sentenciasSQL() As String, ByVal TreeView As TreeView, Optional ByVal nombreNodosPadres() As String = Nothing) ' Procedimiento en la que se ingresa una lista de campos y sus respectivas sentencias SQL ' en las q se mostraran cada campo con sus respectivos datos en un Treeview ' Como nodo padre estara el nombre del campo, y sus hijos seran sus respectivos datos ' de acuerdo a la sentencia Dim cn As New MySQLConnection(cadenaConexion) Dim ParentNode As TreeNode Dim ChildNode As TreeNode Dim i As Integer TreeView.Nodes.Clear() For i = 0 To listaCampos.GetUpperBound(0) Dim CMD As New MySQLCommand(sentenciasSQL(i), cn) Dim DR As MySQLDataReader If nombreNodosPadres Is Nothing Then ParentNode = New TreeNode(Trim(listaCampos(i))) Else ' si es q hemos ingresado el nombre de los nodos padres ParentNode = New TreeNode(Trim(nombreNodosPadres(i))) End If TreeView.Nodes.Add(ParentNode) With CMD .Connection.Open() 'abrimos la conexion DR = .ExecuteReader While DR.Read ChildNode = ParentNode.Nodes.Add(Trim(DR(listaCampos(i)).ToString)) End While .Connection.Close() End With Next End Sub

Página 133

Docente: Ing. Núñez Marinovich Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación Public Sub llenarTreeView_ResumenContenidoBDs(ByVal TV As TreeView, _ Optional ByVal usuario As String = "root", Optional ByVal clave As String = "") ' devuelve una matriz resumen de lo que contiene una BD, indicando: ' Nombre de la BD Nro Tablas - NroColumnas - NroFilas TV.Nodes.Clear() Dim i, j, k As Integer Dim cadenaConexion, nombreBaseDatos, nombreTabla, nombreCampo As String Dim listaBD() As String cadenaConexion = Me.generarCadenaConexionMySQL("test", , usuario, clave) listaBD = Me.listarBasesDatos(cadenaConexion) For i = 0 To listaBD.GetUpperBound(0) nombreBaseDatos = listaBD(i) If Not (nombreBaseDatos = "information_schema" Or nombreBaseDatos = "mysql" _ Or nombreBaseDatos = "phpmyadmin" Or nombreBaseDatos = "test") Then cadenaConexion = Me.generarCadenaConexionMySQL(nombreBaseDatos, , usuario, clave) ' añadimos las BDs Dim tvn As TreeNode = TV.Nodes.Add(nombreBaseDatos, nombreBaseDatos) Dim listaTablas() As String listaTablas = Me.listarTablas(cadenaConexion, nombreBaseDatos) If Not listaTablas Is Nothing Then For j = 0 To listaTablas.GetUpperBound(0) ' añadimos las Tablas nombreTabla = listaTablas(j) Dim tvn2 As TreeNode = tvn.Nodes.Add(nombreBaseDatos & nombreTabla, nombreTabla) Dim listaCampos() As String listaCampos = Me.listarCampos(cadenaConexion, nombreTabla) If Not listaCampos Is Nothing Then For k = 0 To listaCampos.GetUpperBound(0) ' añadimos los campos nombreCampo = listaCampos(k) tvn2.Nodes.Add(nombreBaseDatos & nombreTabla & nombreCampo, nombreCampo) Next End If Next End If End If Next End Sub Public Sub llenarTreeView_ResumenContenidoBDs_2(ByVal TV As TreeView, _ Optional ByVal usuario As String = "root", Optional ByVal clave As String = "") ' devuelve una matriz resumen de lo que contiene una BD, indicando: ' Nombre de la BD Tablas - Columnas TV.Nodes.Clear() Dim i, j As Integer Dim cadenaConexion, nombreBaseDatos, nombreTabla, etiquetaTabla As String Dim listaBD() As String cadenaConexion = Me.generarCadenaConexionMySQL("test", , usuario, clave) listaBD = Me.listarBasesDatos(cadenaConexion) For i = 0 To listaBD.GetUpperBound(0) nombreBaseDatos = listaBD(i) If Not (nombreBaseDatos = "information_schema" Or nombreBaseDatos = "mysql" _

Página 134

Docente: Ing. Núñez Marinovich Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación Or nombreBaseDatos = "phpmyadmin" Or nombreBaseDatos = "test") Then cadenaConexion = Me.generarCadenaConexionMySQL(nombreBaseDatos, , usuario, clave) ' añadimos las BDs Dim tvn As TreeNode = TV.Nodes.Add(nombreBaseDatos, nombreBaseDatos) Dim listaTablas() As String listaTablas = Me.listarTablas(cadenaConexion, nombreBaseDatos) If Not listaTablas Is Nothing Then For j = 0 To listaTablas.GetUpperBound(0) ' añadimos las Tablas con sus campos nombreTabla = listaTablas(j) etiquetaTabla = nombreTabla & " (" Dim listaCampos() As String listaCampos = Me.listarCampos(cadenaConexion, nombreTabla) If Not listaCampos Is Nothing Then etiquetaTabla &= Mañuco.Lista.devolverListaEstatica_ComoCadena(listaCampos, " , ") End If etiquetaTabla &= ")" Dim tvn2 As TreeNode = tvn.Nodes.Add(nombreBaseDatos & nombreTabla, etiquetaTabla) Next End If End If Next End Sub #End Region #Region "List Box" Sub llenarListBox_DataReader(ByVal cadenaConexion As String, ByVal ListBox As ListBox, ByVal tabla As String, ByVal campo As String, Optional ByVal ordenacion As TipoOrdenacion = TipoOrdenacion.Ninguna, Optional ByVal limpiarLista As Boolean = True) ' Funcion que ejecuta una sentencia SQL y el resultado lo muestra en un ListBox ' En este codigo usamos el objeto DataReader para el acceso rapido y optimo a la BD ' instancia el objeto y en el constructor le entrego a la cadena de conexion Dim sentenciaSQL As String = "select " & campo & " from " & tabla If ordenacion = TipoOrdenacion.Ascendente Then sentenciaSQL &= " order by " & campo & " asc" ElseIf ordenacion = TipoOrdenacion.Descendente Then sentenciaSQL &= " order by " & campo & " desc" End If Dim cn As New MySQLConnection(cadenaConexion) Dim CMD As New MySQLCommand(sentenciaSQL, cn) Dim DR As MySQLDataReader If limpiarLista Then ListBox.Items.Clear() With CMD .Connection.Open() 'abrimos la conexion DR = .ExecuteReader While DR.Read ListBox.Items.Add(DR(campo)) End While .Connection.Close() End With End Sub Sub llenarListBox_DataReader(ByVal cadenaConexion As String, ByVal sentenciaSQL As String, ByVal campo As String, ByVal ListBox As ListBox, Optional ByVal limpiarLista As Boolean = True) ' Funcion que ejecuta una sentencia SQL y el resultado lo muestra en un ListBox ' En este codigo usamos el objeto DataReader para el acceso rapido y optimo a la BD ' instancia el objeto y en el constructor le entrego a la cadena de conexion Dim cn As New MySQLConnection(cadenaConexion) Dim CMD As New MySQLCommand(sentenciaSQL, cn) Dim DR As MySQLDataReader If limpiarLista Then ListBox.Items.Clear() With CMD

Página 135

Docente: Ing. Núñez Marinovich Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación .Connection.Open() 'abrimos la conexion DR = .ExecuteReader While DR.Read ListBox.Items.Add(DR(campo)) End While .Connection.Close() End With End Sub #End Region #Region "Combo Box" Sub llenarComboBox_DataReader(ByVal cadenaConexion As String, ByVal ComboBox As ComboBox, ByVal tabla As String, ByVal campo As String, Optional ByVal ordenacion As TipoOrdenacion = TipoOrdenacion.Ninguna, Optional ByVal limpiarLista As Boolean = True) ' Funcion que ejecuta una sentencia SQL y el resultado lo muestra en un ListBox ' En este codigo usamos el objeto DataReader para el acceso rapido y optimo a la BD ' instancia el objeto y en el constructor le entrego a la cadena de conexion Dim sentenciaSQL As String = "select " & campo & " from " & tabla If ordenacion = TipoOrdenacion.Ascendente Then sentenciaSQL &= " order by " & campo & " asc" ElseIf ordenacion = TipoOrdenacion.Descendente Then sentenciaSQL &= " order by " & campo & " desc" End If Dim cn As New MySQLConnection(cadenaConexion) Dim CMD As New MySQLCommand(sentenciaSQL, cn) Dim DR As MySQLDataReader If limpiarLista Then ComboBox.Items.Clear() With CMD .Connection.Open() 'abrimos la conexion DR = .ExecuteReader While DR.Read ComboBox.Items.Add(DR(campo)) End While .Connection.Close() End With End Sub Sub llenarComboBox_DataReader(ByVal cadenaConexion As String, ByVal sentenciaSQL As String, ByVal campo As String, ByVal ComboBox As ComboBox, Optional ByVal limpiarLista As Boolean = True) ' Funcion que ejecuta una sentencia SQL y el resultado lo muestra en un ComboBox ' En este codigo usamos el objeto DataReader para el acceso rapido y optimo a la BD ' instancia el objeto y en el constructor le entrego a la cadena de conexion Dim cn As New MySQLConnection(cadenaConexion) Dim CMD As New MySQLCommand(sentenciaSQL, cn) Dim DR As MySQLDataReader If limpiarLista Then ComboBox.Items.Clear() With CMD .Connection.Open() 'abrimos la conexion DR = .ExecuteReader While DR.Read ComboBox.Items.Add(DR(campo)) End While .Connection.Close() End With End Sub Sub llenarComboBox_AñosCampoFecha(ByVal cadenaConexion As String, ByVal CBO As ComboBox, _ ByVal tabla As String, ByVal campo As String, Optional ByVal seleccionarPrimerElemento As Boolean = False) ' Muestra en un combobox, con los años existentes en un campo de tipo fecha Dim sentencia As String sentencia = _ "select distinct year(" & campo & ") AS año from " & tabla & _ " order by year(" & campo & ") asc"

Página 136

Docente: Ing. Núñez Marinovich Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación llenarComboBox_DataReader(cadenaConexion, sentencia, "año", CBO) If seleccionarPrimerElemento Then CBO.SelectedIndex = CBO.Items.Count - 1 End Sub #End Region #Region "Insertar" Sub insertarRegistro(ByVal cadenaConexion As String, ByVal nombreTabla As String, _ ByVal valoresCampos() As Object, ByVal valoresInsertar() As Object) Using CN As MySQLConnection = New MySQLConnection(cadenaConexion) '("localhost", "test", "root", "", 3306).As String) CN.Open() Dim i, nroFilas As Integer nroFilas = valoresCampos.GetLongLength(0) Dim camposValores(nroFilas - 1, 1) As Object For i = 0 To nroFilas - 1 camposValores(i, 0) = valoresCampos(i) camposValores(i, 1) = valoresInsertar(i) Next 'Dim icmd As MySQLInsertCommand = New MySQLInsertCommand(CN, _ ' New Object(,) {{"field1", "111"}, _ ' {"field2", "222"}, _ ' {"field3", "333"}}, nombreTabla) Dim icmd As MySQLInsertCommand = New MySQLInsertCommand(CN, camposValores, nombreTabla) End Using ''''''''''''''''''''''''''' Modo de uso: 'Dim strMySQL As String 'strMySQL = Mañuco.Base_Datos.MySql.generarCadenaConexionMySQL("hotel", , , "pni") 'Dim vc() As Object = {"campoS", "CampoE", "CampoD", "CampoB"} ' 'Dim vi() As Object = {Me.TextBox1.Text, val(me.textbox2.text), "3000-05-20", 0} 'Mañuco.Base_Datos.MySql.insertarRegistro(strMySQL, "TablaT", vc, vi) End Sub Sub insertarRegistro(ByVal cadenaConexion As String, ByVal nombreTabla As String, _ ByVal campo_y_valores_Insertar(,) As Object) Using CN As MySQLConnection = New MySQLConnection(cadenaConexion) '("localhost", "test", "root", "", 3306).As String) CN.Open() 'Dim icmd As MySQLInsertCommand = New MySQLInsertCommand(CN, _ ' New Object(,) {{"field1", "111"}, _ ' {"field2", "222"}, _ ' {"field3", "333"}}, nombreTabla) Dim icmd As MySQLInsertCommand = New MySQLInsertCommand(CN, campo_y_valores_Insertar, nombreTabla) End Using ''''''''''''''''''''''''''' Modo de uso: 'Dim strMySQL As String 'strMySQL = Mañuco.Base_Datos.MySql.generarCadenaConexionMySQL("hotel", , , "pni") 'Dim valores(,) As Object = {{"campoS", Me.TextBox1.Text}, {"CampoE", 25}, {"CampoD", "300005-20"}, {"CampoB", 0}} 'Mañuco.Base_Datos.MySql.insertarRegistro(strMySQL, "TablaT", valores) End Sub #End Region #Region "Modificar"

Página 137

Docente: Ing. Núñez Marinovich Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación Sub modificarRegistro(ByVal cadenaConexion As String, ByVal nombreTabla As String, _ ByVal campo_y_valores_Actualizar(,) As Object, _ Optional ByVal whereParamFields(,) As Object = Nothing, _ Optional ByVal whereNonParamFields(,) As Object = Nothing) Using CN As MySQLConnection = New MySQLConnection(cadenaConexion) '("localhost", "test", "root", "", 3306).As String) CN.Open() 'Dim icmd As MySQLInsertCommand = New MySQLInsertCommand(CN, _ ' New Object(,) {{"field1", "111"}, _ ' {"field2", "222"}, _ ' {"field3", "333"}}, nombreTabla) Dim icmd As MySQLUpdateCommand = _ New MySQLUpdateCommand(CN, campo_y_valores_Actualizar, nombreTabla, _ whereParamFields, whereNonParamFields) ',New Object(,) {{"id", "=", "4"}}, Nothing) End Using '....................................... Modo de uso: 'Dim strMySQL As String 'strMySQL = Mañuco.Base_Datos.MySql.generarCadenaConexionMySQL("hotel", , , "pni") 'Dim valores(,) As Object = {{"campoS", Me.TextBox1.Text}, {"CampoE", 9000}, {"CampoD", "5000-05-20"}, {"CampoB", 1}} 'Mañuco.Base_Datos.MySql.modificarRegistro(strMySQL, "TablaT", valores, New Object(,) {{"campoAut", "=", "4"}}) End Sub #End Region Function ejecutarCommand(ByVal cadenaConexion As String, ByVal sentenciaSQL As String, Optional ByVal devolverNumeroFilasAfectadas As Boolean = False) ' Funcion que ejecuta una sentencia SQL (Insert , Delete, Update) ' Opcionalment devuelve el numero de filas afectadas Dim CN As New MySQLConnection(cadenaConexion) Dim Cmd As New MySQLCommand(sentenciaSQL, CN) Try CN.Open() If devolverNumeroFilasAfectadas Then ' ejecuta la consulta y devolvemos el numero de filas afectadas Return Cmd.ExecuteNonQuery Else Cmd.ExecuteNonQuery() ' ejecuta la sentencia SQL End If CN.Close() Catch ex As MySQLException MsgBox(ex.Message) End Try End Function Function ejecutarCommand(ByVal sentenciaSQL As String, Optional ByVal devolverNumeroFilasAfectadas As Boolean = False, _ Optional ByVal BaseDatos As String = "test", Optional ByVal Servidor As String = "localhost", _ Optional ByVal Usuario As String = "root", Optional ByVal Password As String = "") ' Funcion que ejecuta una sentencia SQL (Insert , Delete, Update) ' Opcionalment devuelve el numero de filas afectadas Dim cadenaConexion As String cadenaConexion = generarCadenaConexionMySQL(BaseDatos, Servidor, Usuario, Password) Dim CN As New MySQLConnection(cadenaConexion) Dim Cmd As New MySQLCommand(sentenciaSQL, CN) Try CN.Open() If devolverNumeroFilasAfectadas Then

Página 138

Docente: Ing. Núñez Marinovich Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación ' ejecuta la consulta y devolvemos el numero de filas afectadas Return Cmd.ExecuteNonQuery Else Cmd.ExecuteNonQuery() ' ejecuta la sentencia SQL End If CN.Close() Catch ex As MySQLException MsgBox(ex.Message) End Try End Function #Region "Visualizar Lista Texto" Public Sub visualizarListaTexto(ByVal cadenaConexion As String, _ ByVal text As TextBox, ByVal ListBox As ListBox, _ ByVal nombreTabla As String, ByVal nombreCampo As String, _ Optional ByVal TipoBusqueda As TipoBusqueda = TipoBusqueda.Contenga, _ Optional ByVal listBoxHaciaAbajo As Boolean = True, _ Optional ByVal altoListBox As Integer = 0) ' Este modulo sirve para visualizar una lista desplegable ' de acuerdo al nombre q se va ingresando ' Programarlo sobre el evento Change del TextBox Dim sentencia As String ListBox.Items.Clear() If text.Text = "" Then ListBox.Visible = False Exit Sub End If ' asignamos el alto del ListBox si es q se ha ingresado If altoListBox <> 0 Then ListBox.Height = altoListBox ListBox.Width = text.Width If listBoxHaciaAbajo Then ListBox.Top = Val(text.Top) + Val(text.Height) Else ListBox.Top = Val(text.Top) - Val(ListBox.Height) End If ListBox.Left = text.Left ListBox.Visible = True Dim TextoBuscar As String = text.Text sentencia = _ "select distinct " & nombreCampo & " from " & nombreTabla & _ " where " Select Case TipoBusqueda Case TipoBusqueda.Comienze sentencia &= _ nombreCampo & " like '" & TextoBuscar & "%' order by " & nombreCampo Case TipoBusqueda.Contenga sentencia &= _ nombreCampo & " like '%" & TextoBuscar & "%' order by " & nombreCampo Case TipoBusqueda.Igual sentencia &= _ nombreCampo & " = '" & TextoBuscar & "' order by " & nombreCampo Case TipoBusqueda.Termine sentencia &= _ nombreCampo & " like '%" & TextoBuscar & "' order by " & nombreCampo End Select Dim cn As New MySQLConnection(cadenaConexion) Dim CMD As New MySQLCommand(sentencia, cn) Dim DR As MySQLDataReader With CMD .Connection.Open() DR = .ExecuteReader While DR.Read

Página 139

Docente: Ing. Núñez Marinovich Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación ListBox.Items.Add(DR(nombreCampo)) End While .Connection.Close() End With If ListBox.Items.Count = 0 Then ListBox.Visible = False End Sub

Public Sub visualizarListaTexto(ByVal cadenaConexion As String, _ ByVal ListBox As ListBox, ByVal text As TextBox, _ ByVal sentenciaSQL As String, ByVal nombreCampoLlenar As String, _ Optional ByVal listBoxHaciaAbajo As Boolean = True, _ Optional ByVal altoListBox As Integer = 0) ' Este modulo sirve para visualizar una lista desplegable ' de acuerdo al nombre q se va ingresando ' Programarlo sobre el evento Change del TextBox ListBox.Items.Clear() If text.Text = "" Then ListBox.Visible = False Exit Sub End If ' asignamos el alto del ListBox si es q se ha ingresado If altoListBox <> 0 Then ListBox.Height = altoListBox ListBox.Width = text.Width If listBoxHaciaAbajo Then ListBox.Top = Val(text.Top) + Val(text.Height) Else ListBox.Top = Val(text.Top) - Val(ListBox.Height) End If ListBox.Left = text.Left ListBox.Visible = True Dim cn As New MySQLConnection(cadenaConexion) Dim CMD As New MySQLCommand(sentenciaSQL, cn) Dim DR As MySQLDataReader With CMD .Connection.Open() DR = .ExecuteReader While DR.Read ListBox.Items.Add(DR(nombreCampoLlenar)) End While .Connection.Close() End With If ListBox.Items.Count = 0 Then ListBox.Visible = False End Sub Public Sub visualizarListaTexto(ByVal cadenaConexion As String, _ ByVal text As TextBox, ByVal ListBox As ListBox, _ ByVal nombreTabla As String, ByVal nombreCampo As String, _ ByVal topListBox As Integer, ByVal leftListBox As Integer, _ Optional ByVal TipoBusqueda As TipoBusqueda = TipoBusqueda.Contenga, _ Optional ByVal altoListBox As Integer = 0) ' Este modulo sirve para visualizar una lista desplegable ' de acuerdo al nombre q se va ingresando ' Programarlo sobre el evento Change del TextBox Dim sentencia As String ListBox.Items.Clear() If text.Text = "" Then ListBox.Visible = False Exit Sub End If ' asignamos el alto del ListBox si es q se ha ingresado If altoListBox <> 0 Then ListBox.Height = altoListBox ListBox.Width = text.Width ListBox.Top = topListBox ListBox.Left = leftListBox

Página 140

Docente: Ing. Núñez Marinovich Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación ListBox.Visible = True Dim TextoBuscar As String = text.Text sentencia = _ "select distinct " & nombreCampo & " from " & nombreTabla & _ " where " Select Case TipoBusqueda Case TipoBusqueda.Comienze sentencia &= _ nombreCampo & " like '" & TextoBuscar & "%' order by " & nombreCampo Case TipoBusqueda.Contenga sentencia &= _ nombreCampo & " like '%" & TextoBuscar & "%' order by " & nombreCampo Case TipoBusqueda.Igual sentencia &= _ nombreCampo & " = '" & TextoBuscar & "' order by " & nombreCampo Case TipoBusqueda.Termine sentencia &= _ nombreCampo & " like '%" & TextoBuscar & "' order by " & nombreCampo End Select Dim cn As New MySQLConnection(cadenaConexion) Dim CMD As New MySQLCommand(sentencia, cn) Dim DR As MySQLDataReader With CMD .Connection.Open() DR = .ExecuteReader While DR.Read ListBox.Items.Add(DR(nombreCampo)) End While .Connection.Close() End With If ListBox.Items.Count = 0 Then ListBox.Visible = False End Sub

Public Sub visualizarListaTexto(ByVal cadenaConexion As String, _ ByVal ListBox As ListBox, ByVal text As TextBox, _ ByVal sentenciaSQL As String, ByVal nombreCampoLlenar As String, _ ByVal topListBox As Integer, ByVal leftListBox As Integer, _ Optional ByVal altoListBox As Integer = 0) ' Este modulo sirve para visualizar una lista desplegable ' de acuerdo al nombre q se va ingresando ' Programarlo sobre el evento Change del TextBox ListBox.Items.Clear() If text.Text = "" Then ListBox.Visible = False Exit Sub End If ' asignamos el alto del ListBox si es q se ha ingresado If altoListBox <> 0 Then ListBox.Height = altoListBox ListBox.Width = text.Width ListBox.Top = topListBox ListBox.Left = leftListBox ListBox.Visible = True Dim cn As New MySQLConnection(cadenaConexion) Dim CMD As New MySQLCommand(sentenciaSQL, cn) Dim DR As MySQLDataReader With CMD .Connection.Open() DR = .ExecuteReader While DR.Read ListBox.Items.Add(DR(nombreCampoLlenar)) End While

Página 141

Docente: Ing. Núñez Marinovich Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación .Connection.Close() End With If ListBox.Items.Count = 0 Then ListBox.Visible = False End Sub #End Region #Region "Verificar Existencia Base Datos, Tablas, Campos" Function verificarExistenciaBaseDatos(ByVal cadenaConexion As String, _ ByVal nombreBaseDatos_a_Buscar As String) Dim listaBD As String() listaBD = listarBasesDatos(cadenaConexion) Dim i As Integer Dim resultado As Boolean = False For i = 0 To listaBD.GetUpperBound(0) If nombreBaseDatos_a_Buscar.ToUpper = listaBD(i).ToUpper Then resultado = True Exit For End If Next Return resultado End Function Function verificarExistenciaTabla_enBaseDatos(ByVal cadenaConexion As String, _ ByVal nombreTabla_a_Buscar As String, _ ByVal nombreBaseDatos As String) Dim listaTablas As String() listaTablas = listarTablas(cadenaConexion, nombreBaseDatos) Dim i As Integer Dim resultado As Boolean = False For i = 0 To listaTablas.GetUpperBound(0) If nombreTabla_a_Buscar.ToUpper = listaTablas(i).ToUpper Then resultado = True Exit For End If Next Return resultado End Function

Function verificarExistenciaCampo_enTabla(ByVal cadenaConexion As String, _ ByVal nombreCampo_a_Buscar As String, ByVal nombreTabla As String) Dim listaCampos As String() listaCampos = listarCampos(cadenaConexion, nombreTabla) Dim i As Integer Dim resultado As Boolean = False For i = 0 To listaCampos.GetUpperBound(0) If nombreCampo_a_Buscar.ToUpper = listaCampos(i).ToUpper Then resultado = True Exit For End If Next Return resultado End Function #End Region

Página 142

Docente: Ing. Núñez Marinovich Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación #Region "Crear y Eliminar BD" Sub crearBaseDatos(ByVal nombreBaseDatos As String, _ Optional ByVal usuario As String = "root", Optional ByVal contraseña As String = "") Dim cadenaConexion As String cadenaConexion = _ "Provider=MySQLProv;" & _ ";User Id=" & usuario & _ "; Password=" & contraseña & ";" Dim sentencia As String sentencia = "CREATE DATABASE " & nombreBaseDatos & ";" ejecutarCommand(cadenaConexion, sentencia) End Sub Sub eliminarBaseDatos(ByVal nombreBaseDatos As String, _ Optional ByVal usuario As String = "root", Optional ByVal contraseña As String = "") Dim cadenaConexion As String cadenaConexion = _ "Provider=MySQLProv;" & _ ";User Id=" & usuario & _ "; Password=" & contraseña & ";" Dim sentencia As String sentencia = "DROP DATABASE IF EXISTS " & nombreBaseDatos & ";" ejecutarCommand(cadenaConexion, sentencia) End Sub #End Region #Region "Listar Bases de Datos, Tablas, Campos" Function listarBasesDatos(ByVal cadenaConexion As String) As String() Dim sentencia As String sentencia = "show databases;" Return Me.devolverColumna_ComoLista(cadenaConexion, sentencia) End Function Function listarTablas(ByVal cadenaConexion As String, ByVal BaseDatos As String) As String() Dim sentencia As String sentencia = "show tables;" Return Me.devolverColumna_ComoLista(cadenaConexion, sentencia) End Function

Function listarCampos(ByVal cadenaConexion As String, ByVal Tabla As String) As String() Dim sentencia As String sentencia = "describe " & Tabla & ";" Return Me.devolverColumna_ComoLista(cadenaConexion, sentencia) End Function #End Region #Region "Devolver Consulta como String - Archivo" Function devolverConsulta_ComoString( _ ByVal cadenaConexion As String, ByVal sentenciaSQL As String, _ Optional ByVal caracterSeparacionFilas As String = vbCrLf, _ Optional ByVal caracterSeparacionColumnas As String = " ", _ Optional ByVal incluirCabeceras As Boolean = False) As String Dim i, j As Integer Dim elemento, resultado As String resultado = "" Dim nroFilas, nroColumnas As Integer

Página 143

Docente: Ing. Núñez Marinovich Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación Dim DT As DataTable ' llenar el DataTable con la consulta DT = devolverDataTable(cadenaConexion, sentenciaSQL) nroFilas = DT.Rows.Count nroColumnas = DT.Columns.Count If incluirCabeceras Then ' incluimos las cabeceras For j = 0 To nroColumnas - 1 elemento = DT.Columns.Item(j).Caption resultado &= elemento If j <> nroColumnas - 1 Then resultado &= caracterSeparacionColumnas Next resultado &= caracterSeparacionFilas End If For i = 0 To nroFilas - 1 For j = 0 To nroColumnas - 1 'DT.Rows(i).Item(nroColumna).ToString() elemento = DT.Rows(i).Item(j).ToString 'DT.Item(j, i).Value.ToString resultado &= elemento 'si es que no es el ultimo elemento de la columna 'ya no le ponemos caracter de separacion If j <> nroColumnas - 1 Then resultado &= caracterSeparacionColumnas Next 'si es que no es el ultimo elemento de la fila 'ya no le ponemos caracter de separacion If i <> nroFilas - 1 Then resultado &= caracterSeparacionFilas Next Return resultado End Function Sub devolverConsulta_ComoArchivo( _ ByVal cadenaConexion As String, ByVal sentenciaSQL As String, _ Optional ByVal caracterSeparacionFilas As String = vbCrLf, _ Optional ByVal caracterSeparacionColumnas As String = " ", _ Optional ByVal incluirCabeceras As Boolean = False, _ Optional ByVal rutaArchivoGrabar As String = "", Optional ByVal abrirArchivo As Boolean = False) ' Crea un archivo de acuerdo al resultado de una consulta SQL. Dim textoGrabar As String ' el texto que se insertara en el archivo a crear textoGrabar = devolverConsulta_ComoString( _ cadenaConexion, sentenciaSQL, _ caracterSeparacionFilas, caracterSeparacionColumnas, incluirCabeceras) If rutaArchivoGrabar = "" Then 'IO.File.Exists(rutaArchivoGrabar) Mañuco.Archivo.crearArchivoTexto(textoGrabar, abrirArchivo) Else Mañuco.Archivo.crearArchivoTexto(textoGrabar, rutaArchivoGrabar, abrirArchivo) End If

End Sub #End Region End Class #End Region

Página 144

Docente: Ing. Núñez Marinovich Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación

Conexión ADO.NET a PostgreSQL Imports Npgsql ' Conexion PostgreSQL Referencia: Npgsql.dll, Mono.Security.dll #Region "Conexion a PostgreSQL" Public Class BD_PostgreSQL 'El conector de PostgreSQL con VS.NET 'http://pgfoundry.org/frs/?group_id=1000140 'Agregar Referencia: ' '

Npgsql. dll Mono.Security.dll

Shared Function devuelveDato(ByVal campo) If IsDBNull(campo) Then devuelveDato = "" Else devuelveDato = campo End If End Function #Region "Generar Cadena Conexion" Shared Function generarCadenaConexion(ByVal BaseDatos As String, _ Optional ByVal Servidor As String = "localhost", _ Optional ByVal Usuario As String = "postgres", Optional ByVal Contraseña As String = "", _ Optional ByVal nroPuerto As String = "5432", _ Optional ByVal parametrosAdicionales As String = "") 'Genera la cadena de conexion a PostgreSQL Dim cadenaConexion As String cadenaConexion = _ "Server=" & Servidor & _ "; Database=" & BaseDatos & _ "; User Id=" & Usuario & _ "; Password=" & Contraseña & _ "; Port=" & nroPuerto & _ "; " & parametrosAdicionales Return cadenaConexion 'http://www.connectionstrings.com/postgre-sql 'User ID=root;Password=myPassword;Host=localhost;Port=5432;Database=myDataBase; Pooling=true;Min Pool Size=0;Max Pool Size=100;Connection Lifetime=0; 'Server=127.0.0.1;Port=5432;Database=myDataBase;User Id=myUsername;Password=myPassword; 'Server=127.0.0.1;Port=5432;Database=myDataBase;Integrated Security=true; 'Server=127.0.0.1;Port=5432;Database=myDataBase;User Id=myUsername;Password=myPassword;CommandTimeout=20; 'Server=127.0.0.1;Port=5432;Database=myDataBase;User Id=myUsername;Password=myPassword;Timeout=15; 'Server=127.0.0.1;Port=5432;Database=myDataBase;User Id=myUsername;Password=myPassword;Protocol=3; End Function #End Region Function Optional Optional Optional Optional Optional

verificarConexionBD(ByVal BaseDatos As String, _ ByVal Servidor As String = "localhost", _ ByVal Usuario As String = "postgres", _ ByVal Password As String = "", _ ByVal Puerto As String = "5432", _ ByVal parametrosAdicionales As String = "") As Boolean

'Creamos un objeto de tipo Connection y configuramos los parámetros de la conexión

Página 145

Docente: Ing. Núñez Marinovich Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación Dim DBCon As Npgsql.NpgsqlConnection 'Los parámetros de la sobrecarga con más parámetros son: '1. Dirección IP o nombre de la máquina con el servidor de NpgsqlS '2. Nombre de la base de datos '3. Nombre de usuario con acceso a la base de datos señalada anteriormente '4. Contraseña para el nombre de usuario citado '5. Puerto por el que se acede al servidor. Típicamente 5432 Dim Cadena_Conexion As String 'Cadena_Conexion = "Server=127.0.0.1;Port=5432;Database=BDEjemplo;Integrated Security=true;" 'Cadena_Conexion = "Server=127.0.0.1;Port=5432;Database=BDEjemplo;User ID=postgres;Password=pni;" Cadena_Conexion = Me.generarCadenaConexion(BaseDatos, Servidor, Usuario, Password, Puerto, parametrosAdicionales) DBCon = New NpgsqlConnection(Cadena_Conexion) Dim resultado As Boolean Try 'Abrimos la conexión y comprobamos que no hay error DBCon.Open() resultado = True 'MsgBox("OK") DBCon.Close() Catch ex As NpgsqlException 'Si hubiese error en la conexión mostramos el texto de la descripción 'MsgBox(ex.Message.ToString) resultado = False End Try Return resultado End Function #Region "Devolver Mayor - Menor Valor de Campo" Function devolverMayorValorCampo(ByVal cadenaConexion As String, ByVal nombreTabla As String, ByVal nombreCampo As String) ' Funcion que retorna el mayor valor de un campo de una Tabla Dim sentenciaSQL As String sentenciaSQL = _ "select " & nombreCampo & " from " & nombreTabla & _ " order by " & nombreCampo & " desc limit 1 " Return devolverCelda(cadenaConexion, sentenciaSQL, nombreTabla, nombreCampo) 'Ejemplo 'MsgBox(Base_Datos.PostgreSQL.devolverMayorValorCampo(strcn, """Tabla1""", """Campo""")) End Function Function devolverMenorValorCampo(ByVal cadenaConexion As String, ByVal nombreTabla As String, ByVal nombreCampo As String) ' Funcion que retorna el menor valor de un campo de una Tabla Dim sentenciaSQL As String sentenciaSQL = _ "select " & nombreCampo & " from " & nombreTabla & _ " order by " & nombreCampo & " asc limit 1 " Return devolverCelda(cadenaConexion, sentenciaSQL, nombreTabla, nombreCampo) 'Ejemplo: 'MsgBox(Base_Datos.PostgreSQL.devolverMenorValorCampo(strcn, """Tabla1""", """Campo""")) End Function #End Region #Region "Funciones Booleanas" Public Function esTablaVacia(ByVal cadenaConexion As String, ByVal nombreTabla As String) As Boolean ' Funcion que devuelve Verdadero si la tabla es vacia, ' si la tabla tuviera datos, devuelve false Dim CN As New NpgsqlConnection(cadenaConexion)

Página 146

Docente: Ing. Núñez Marinovich Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación Dim DA As New NpgsqlDataAdapter("select * from " & nombreTabla, CN) Dim DT As New DataTable ' actua como un repositorio de la informacion consultada ' abre la conexion, ejecuta la consulta, llena el DT y cierra la conexion DA.Fill(DT) If DT.Rows.Count > 0 Then ' La tabla si tiene datos Return False Else ' La tabla no tiene Datos Return True End If 'Ejemplo: 'MsgBox(Base_Datos.PostgreSQL.esTablaVacia(strcn, """Tabla1""")) End Function Public Function esConsultaVacia(ByVal cadenaConexion As String, ByVal sentencia As String) As Boolean ' Funcion que devuelve Verdadero si la tabla es vacia, ' si la tabla tuviera datos, devuelve false Dim CN As New NpgsqlConnection(cadenaConexion) Dim DA As New NpgsqlDataAdapter(sentencia, CN) Dim DT As New DataTable ' actua como un repositorio de la informacion consultada ' abre la conexion, ejecuta la consulta, llena el DT y cierra la conexion DA.Fill(DT) If DT.Rows.Count > 0 Then ' La tabla si tiene datos Return False Else ' La tabla no tiene Datos Return True End If 'Ejemplo: 'sentencia = "select * from ""Tabla1"" where ""CampoChar""='Z'" 'MsgBox(Base_Datos.PostgreSQL.esConsultaVacia(strcn, sentencia)) End Function Public Function verificarExistenciaDato(ByVal cadenaConexion As String, ByVal nombreTabla As String, ByVal nombreCampo As String, ByVal dato_a_buscar As String) As Boolean 'Verifica si existe cierto dato en la BD, ingresando el nombre del campo y el dato a buscar Dim CN As New NpgsqlConnection(cadenaConexion) Dim sentencia As String Try sentencia = "select count(" & nombreCampo & ") from " & nombreTabla & " where " & _ nombreCampo & " = '" & dato_a_buscar & "'" Dim Cmd As New NpgsqlCommand(sentencia, CN) CN.Open() Dim n As Integer = Cmd.ExecuteScalar CN.Close() If n >= 1 Then ' existe algun elemento Return True Else ' no existe en la tabla del campo especificado dicho elemento Return False End If Catch ex As Exception MsgBox(ex.Message) CN.Close() Return False End Try 'Ejemplo: 'MsgBox(Base_Datos.PostgreSQL.verificarExistenciaDato(strcn, """Tabla1""", """CampoDouble""", 3.5)) End Function #End Region

Página 147

Docente: Ing. Núñez Marinovich Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación #Region "Devolver Total registros: Tabla, Consulta" Public Function totalRegistrosTabla(ByVal cadenaConexion As String, ByVal nombreTabla As String) ' Funcion que devuelve el numero de registros de una Tabla Dim sentencia As String = "select count(*) from " & nombreTabla ' retorna el numero de registros de una Tabla Return devolverEscalar(cadenaConexion, sentencia) 'Ejemplo: 'MsgBox(Base_Datos.PostgreSQL.totalRegistrosTabla(strcn, """Tabla1""")) End Function Public Function totalRegistrosConsulta(ByVal cadenaConexion As String, ByVal sentenciaSQL As String) ' Funcion que devuelve el numero de registros de una consulta Dim CN As New NpgsqlConnection(cadenaConexion) Dim DA As New NpgsqlDataAdapter(sentenciaSQL, CN) Dim DT As New DataTable ' actua como un repositorio de la informacion consultada ' abre la conexion, ejecuta la consulta, llena el DT y cierra la conexion DA.Fill(DT) ' retorna el numero de registros de una consulta Return DT.Rows.Count 'Ejemplo: 'sentencia = "select * from ""Tabla1"" where ""CampoChar""='e'" 'MsgBox(Base_Datos.PostgreSQL.totalRegistrosConsulta(strcn, sentencia)) End Function #End Region #Region "Devolver DataTable, DataRow, DataColumn,Celda,Escalar,Matriz Bidimensional" Function devolverDataTable(ByVal cadenaConexion As String, ByVal sentenciaSQL As String) ' Funcion que ejecuta una sentencia SQL y el resultado lo muestra en un dataGrid ' El procedimiento llena un DataTable mediante una consulta Dim CN As New NpgsqlConnection(cadenaConexion) Dim DA As New NpgsqlDataAdapter(sentenciaSQL, CN) Dim DT As New DataTable ' actua como un repositorio de la informacion consultada ' abre la conexion, ejecuta la consulta, llena el DT y cierra la conexion DA.Fill(DT) Return DT 'devolvemos el dataTable 'Ejemplo: 'sentencia = "select * from ""Tabla2"" " 'Dim dt As New DataTable 'dt = Base_Datos.PostgreSQL.devolverDataTable(strcn, sentencia) 'Me.DataGridView1.DataSource = dt End Function Function devolverDataRow(ByVal cadenaConexion As String, ByVal sentenciaSQL As String, Optional ByVal indice As Integer = 0) ' Funcion que devuelve un DataRow, es decir de una determinada consulta, devuelve los campos de ' una determinada fila(por defecto la primera). Dim CN As New NpgsqlConnection CN.ConnectionString = cadenaConexion ' Creamos el adaptador Dim DA As New NpgsqlDataAdapter(sentenciaSQL, CN) ' Creamos el DataSet Dim DS As New DataSet ' abrimos la conexion, llenamos el DataSet y cerramos la conexion CN.Open() DA.Fill(DS, "Tabla") CN.Close() Dim DR As DataRow DR = DS.Tables("Tabla").Rows(indice) Return DR

Página 148

Docente: Ing. Núñez Marinovich Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación 'Ejemplo: 'sentencia = "select * from ""Tabla1"" order by ""CampoInteger"" desc " 'Dim dr As DataRow 'dr = Base_Datos.PostgreSQL.devolverDataRow(strcn, sentencia) 'MsgBox(dr(0) & vbCrLf & dr(1) & vbCrLf & dr(2) & vbCrLf & dr(3)) End Function Function devolverDataColumn(ByVal cadenaConexion As String, ByVal sentenciaSQL As String, ByVal tabla As String, Optional ByVal indice As Integer = 0) ' Funcion que devuelve un DataColumn , es decir de una determinada consulta, devuelve los campos de ' una determinada columna (por defecto la primera). Dim CN As New NpgsqlConnection CN.ConnectionString = cadenaConexion ' Creamos el adaptador Dim DA As New NpgsqlDataAdapter(sentenciaSQL, CN) ' Creamos el DataSet Dim DS As New DataSet ' abrimos la conexion, llenamos el DataSet y cerramos la conexion CN.Open() DA.Fill(DS, tabla) CN.Close() Dim DC As DataColumn DC = DS.Tables(tabla).Columns(indice) Return DC End Function Function devolverCelda(ByVal cadenaConexion As String, ByVal sentenciaSQL As String, ByVal tabla As String, ByVal nombreCampo As String, Optional ByVal indice As Integer = 0) ' Funcion que devuelve una celda, es decir de una determinada consulta, devuelve ' el valor de un dterminado campo, de una determinada fila(por defecto la primera). Try Dim CN As New NpgsqlConnection CN.ConnectionString = cadenaConexion ' Creamos el adaptador Dim DA As New NpgsqlDataAdapter(sentenciaSQL, CN) ' Creamos el DataSet Dim DS As New DataSet ' Abrimos la conexion, llenamos el DataSet y cerramos la conexion CN.Open() DA.Fill(DS, tabla) CN.Close() Dim DR As DataRow DR = DS.Tables(tabla).Rows(indice) Return devuelveDato(DR.Item(nombreCampo.Replace("""", ""))) Catch ex As Exception Return ex.Message() End Try ' Uso: 'MsgBox(Base_Datos.PostgreSQL.devolverCelda(strcn, sentencias(1), """Tabla1""", "CampoText")) End Function

#Region "Devolver Escalar" Function devolverEscalar(ByVal cadenaConexion As String, ByVal sentenciaSQL As String) Dim CN As New NpgsqlConnection(cadenaConexion) Dim Cmd As New NpgsqlCommand(sentenciaSQL, CN) Try CN.Open() ' ejecuta la consulta y devolvemos la primera columna de la 'primera fila del conjunto de resultado devuelto por la consulta Return devuelveDato(Cmd.ExecuteScalar) CN.Close()

Página 149

Docente: Ing. Núñez Marinovich Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación Catch ex As NpgsqlException MsgBox(ex.Message) End Try 'Ejemplo: 'sentencia = "select ""CampoInteger"" from ""Tabla1"" where ""CampoChar""='e'" 'MsgBox(Base_Datos.PostgreSQL.devolverEscalar(strcn, sentencia)) End Function Function devolverEscalar(ByVal cadenaConexion As String, _ ByVal Tabla As String, ByVal campo_a_devolver As String, _ ByVal condicion As String) ' Funcion que deuelve el resultado de una consulta Dim sentenciaSQL As String sentenciaSQL = "select " & campo_a_devolver & " from " & Tabla & " where " & condicion Dim CN As New NpgsqlConnection(cadenaConexion) Dim Cmd As New NpgsqlCommand(sentenciaSQL, CN) Try CN.Open() ' ejecuta la consulta y devolvemos la primera columna de la 'primera fila del conjunto de resultado devuelto por la consulta Return devuelveDato(Cmd.ExecuteScalar) CN.Close() Catch ex As Npgsql.NpgsqlException MsgBox(ex.Message) End Try 'Ejemplo: 'MsgBox(Base_Datos.PostgreSQL.devolverEscalar(strcn, """Tabla1""", """CampoText""", """CampoChar""='e'")) End Function Function devolverEscalar(ByVal cadenaConexion As String, _ ByVal Tabla As String, ByVal campo_a_devolver As String, _ ByVal campoCondicion As String, ByVal valorCondicion As String) ' Funcion que deuelve el resultado de una consulta Dim sentenciaSQL As String sentenciaSQL = "select " & campo_a_devolver & " from " & Tabla & _ " where " & campoCondicion & "='" & valorCondicion & "'" Dim CN As New NpgsqlConnection(cadenaConexion) Dim Cmd As New NpgsqlCommand(sentenciaSQL, CN) Try CN.Open() ' ejecuta la consulta y devolvemos la primera columna de la 'primera fila del conjunto de resultado devuelto por la consulta Return devuelveDato(Cmd.ExecuteScalar) CN.Close() Catch ex As Npgsql.NpgsqlException MsgBox(ex.Message) End Try 'Ejemplo: 'MsgBox(Base_Datos.PostgreSQL.devolverEscalar(strcn, """Tabla1""", """CampoText""", """CampoChar""", "e")) End Function #End Region

Function devolverMatrizBidimensional(ByVal cadenaConexion As String, ByVal sentenciaSQL As String, _ Optional ByVal incluirCabecerasColumna As Boolean = False, _ Optional ByVal CabecerasColumna() As String = Nothing) ' Funcion que ejecuta una sentencia SQL y el resultado lo muestra en un dataGrid ' El procedimiento llena un DataTable mediante una consulta Dim CN As New NpgsqlConnection(cadenaConexion) Dim DA As New NpgsqlDataAdapter(sentenciaSQL, CN)

Página 150

Docente: Ing. Núñez Marinovich Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación Dim DT As New DataTable ' actua como un repositorio de la informacion consultada ' abre la conexion, ejecuta la consulta, llena el DT y cierra la conexion DA.Fill(DT) Return devolverMatrizBidimensional(DT, incluirCabecerasColumna, CabecerasColumna) 'Ejemplo: 'sentencia = "select * from ""Tabla2"" " 'Dim mm(,) As String 'mm = Base_Datos.PostgreSQL.devolverMatrizBidimensional(strcn, sentencia, ) 'mm = Base_Datos.PostgreSQL.devolverMatrizBidimensional(strcn, sentencia, True) End Function Function devolverMatrizBidimensional(ByVal DT As DataTable, _ Optional ByVal incluirCabecerasColumna As Boolean = False, _ Optional ByVal CabecerasColumna() As String = Nothing) ' Funcion que el contenido de un DataTable lo pasa a una matriz Dim i, j, nroColumnas, nroFilas As Integer nroColumnas = DT.Columns.Count nroFilas = DT.Rows.Count Dim matriz(,) As String If incluirCabecerasColumna Then ReDim matriz(nroFilas, nroColumnas - 1) If CabecerasColumna Is Nothing Then ' ponemos las cabeceras propias del DataTable For j = 0 To nroColumnas - 1 matriz(0, j) = DT.Columns(j).Caption Next For i = 0 To nroFilas - 1 For j = 0 To nroColumnas - 1 matriz(i + 1, j) = DT.Rows(i).Item(j).ToString() Next Next Else For j = 0 To nroColumnas - 1 matriz(0, j) = CabecerasColumna(j) Next For i = 0 To nroFilas - 1 For j = 0 To nroColumnas - 1 matriz(i + 1, j) = DT.Rows(i).Item(j).ToString() Next Next ' ponemos las cabeceras de columna ingresadas en el argumento End If Else ' no incluimos cabeceras de columna ReDim matriz(nroFilas - 1, nroColumnas - 1) For i = 0 To nroFilas - 1 For j = 0 To nroColumnas - 1 matriz(i, j) = DT.Rows(i).Item(j).ToString() Next Next End If Return matriz 'Ejemplo 'sentencia = "select * from ""Tabla2"" " 'Dim dt As DataTable 'Dim mm(,) As String 'dt = Base_Datos.PostgreSQL.devolverDataTable(strcn, sentencia) 'mm = Base_Datos.PostgreSQL.devolverMatrizBidimensional(dt, ) 'mm = Base_Datos.PostgreSQL.devolverMatrizBidimensional(dt, True) End Function Function devolverColumna_ComoLista _ (ByVal cadenaConexion As String, ByVal sentenciaSQL As String, _ Optional ByVal nroColumna As Integer = 0) Dim DT As New DataTable

Página 151

Docente: Ing. Núñez Marinovich Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación DT = devolverDataTable(cadenaConexion, sentenciaSQL) Dim i, nroFilas As Integer nroFilas = DT.Rows.Count Dim listaResultado(nroFilas - 1) As String For i = 0 To nroFilas - 1 listaResultado(i) = DT.Rows(i).Item(nroColumna).ToString Next Return listaResultado End Function Function devolverColumna_ComoString _ (ByVal cadenaConexion As String, ByVal sentenciaSQL As String, _ Optional ByVal nroColumna As Integer = 0) Dim DT As New DataTable DT = devolverDataTable(cadenaConexion, sentenciaSQL) Dim i, nroFilas As Integer nroFilas = DT.Rows.Count Dim cadenaResultado As String For i = 0 To nroFilas - 1 If i = nroFilas - 1 Then ' si es el ultimo q ya no ponga vbcrlf cadenaResultado &= DT.Rows(i).Item(nroColumna).ToString Else cadenaResultado &= DT.Rows(i).Item(nroColumna).ToString & vbCrLf End If Next Return cadenaResultado End Function #End Region #Region "Devolver al azar"

Function devolverEscalar_al_azar(ByVal cadenaConexion As String, _ ByVal Tabla As String, ByVal campo_a_devolver As String) ' Funcion que devuelve el resultado de una consulta Dim sentenciaSQL As String sentenciaSQL = "select " & campo_a_devolver & " from " & Tabla & " ORDER BY RANDOM() limit 1 " Dim CN As New NpgsqlConnection(cadenaConexion) Dim Cmd As New NpgsqlCommand(sentenciaSQL, CN) Try CN.Open() ' ejecuta la consulta y devolvemos la primera columna de la 'primera fila del conjunto de resultado devuelto por la consulta Return devuelveDato(Cmd.ExecuteScalar) CN.Close() Catch ex As Npgsql.NpgsqlException MsgBox(ex.Message) End Try 'Ejemplo: 'MsgBox(Base_Datos.PostgreSQL.devolverEscalar_al_azar(strcn, """Tabla1""", """CampoText""")) End Function #End Region #Region "DataGrid" Sub llenarDataGrid_DataSet(ByVal cadenaConexion As String, ByVal sentenciaSQL As String, ByVal dataGrid As DataGrid) ' Procedimiento que ejecuta una sentencia SQL y el resultado lo muestra en un dataGrid ' El procedimiento llena un DataTable mediante una consulta Dim CN As New NpgsqlConnection(cadenaConexion) Dim DA As New NpgsqlDataAdapter(sentenciaSQL, CN)

Página 152

Docente: Ing. Núñez Marinovich Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación Dim DS As New DataSet ' actua como un repositorio de la informacion consultada ' abre la conexion, ejecuta la consulta, llena el DT y cierra la conexion DA.Fill(DS, """Tabla""") dataGrid.DataSource = DS 'HAcemos el enlace del DataTable al datagrid (Databind) 'dt.Rows.Count ' numero de filas del DataTable dataGrid.DataMember = """Tabla""" End Sub Sub redimensionarDatagrid_DataSet(ByVal DG As DataGrid, ByVal arregloDimensiones() As Integer, Optional ByVal arregloCabecerasTexto() As String = Nothing) Dim TableStyle1 As New DataGridTableStyle Dim COLUMNA As New DataGridTextBoxColumn Dim DS As New DataSet Dim j As Integer DS = DG.DataSource DG.TableStyles.Clear() TableStyle1.MappingName = DS.Tables(0).TableName TableStyle1.AlternatingBackColor = DG.AlternatingBackColor TableStyle1.BackColor = DG.BackColor TableStyle1.HeaderBackColor = DG.HeaderBackColor TableStyle1.HeaderForeColor = DG.HeaderForeColor TableStyle1.ForeColor = DG.ForeColor TableStyle1.SelectionBackColor = DG.SelectionBackColor TableStyle1.GridLineColor = DG.GridLineColor If DS.Tables(0).Columns.Count = UBound(arregloDimensiones) + 1 Then For j = 0 To DS.Tables(0).Columns.Count - 1 COLUMNA = New DataGridTextBoxColumn COLUMNA.MappingName = DS.Tables(0).Columns(j).ToString If arregloCabecerasTexto Is Nothing Then COLUMNA.HeaderText = DS.Tables(0).Columns(j).ToString Else COLUMNA.HeaderText = arregloCabecerasTexto(j) End If COLUMNA.Width = arregloDimensiones(j) TableStyle1.GridColumnStyles.Add(COLUMNA) Next Else MsgBox("Ingrese dimensiones completas") End If DG.TableStyles.Add(TableStyle1) End Sub Sub llenarDataGrid(ByVal cadenaConexion As String, ByVal sentenciaSQL As String, ByVal dataGrid As DataGrid) ' Procedimiento que ejecuta una sentencia SQL y el resultado lo muestra en un dataGrid ' El procedimiento llena un DataTable mediante una consulta Dim CN As New NpgsqlConnection(cadenaConexion) Dim DA As New NpgsqlDataAdapter(sentenciaSQL, CN) Dim DT As New DataTable ' actua como un repositorio de la informacion consultada ' abre la conexion, ejecuta la consulta, llena el DT y cierra la conexion DA.Fill(DT) dataGrid.DataSource = DT 'HAcemos el enlace del DataTable al datagrid (Databind) 'dt.Rows.Count ' numero de filas del DataTable ' Ejemplo de uso: 'Dim strcn As String = _ 'Mañuco.Base_Datos.PostgreSQL.generarCadenaConexion("BDEjemplo", , , "Informatica1") 'Dim sentencia As String 'sentencia = "select * from " & Chr(34) & "Tabla1" & Chr(34) 'sentencia = "select * from ""Tabla1"" " 'Base_Datos.PostgreSQL.llenarDataGrid(strcn, sentencia, Me.DataGrid1) End Sub

Página 153

Docente: Ing. Núñez Marinovich Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación Sub redimensionarDatagrid(ByVal DG As DataGrid, ByVal arregloDimensiones() As Integer, Optional ByVal arregloCabecerasTexto() As String = Nothing) Dim TableStyle1 As New DataGridTableStyle Dim COLUMNA As New DataGridTextBoxColumn Dim DT As New DataTable Dim j As Integer DT = DG.DataSource DG.TableStyles.Clear() TableStyle1.MappingName = DT.TableName TableStyle1.AlternatingBackColor = DG.AlternatingBackColor TableStyle1.BackColor = DG.BackColor TableStyle1.HeaderBackColor = DG.HeaderBackColor TableStyle1.HeaderForeColor = DG.HeaderForeColor TableStyle1.ForeColor = DG.ForeColor TableStyle1.SelectionBackColor = DG.SelectionBackColor TableStyle1.GridLineColor = DG.GridLineColor

If DT.Columns.Count = UBound(arregloDimensiones) + 1 Then For j = 0 To DT.Columns.Count - 1 COLUMNA = New DataGridTextBoxColumn COLUMNA.MappingName = DT.Columns(j).ToString If arregloCabecerasTexto Is Nothing Then COLUMNA.HeaderText = DT.Columns(j).ToString Else COLUMNA.HeaderText = arregloCabecerasTexto(j) End If COLUMNA.Width = arregloDimensiones(j) TableStyle1.GridColumnStyles.Add(COLUMNA) Next Else MsgBox("Ingrese dimensiones completas.") End If DG.TableStyles.Add(TableStyle1) End Sub Sub llenarDataGridTablas(ByVal cadenaConexion As String, ByVal sentenciasSQL() As String, ByVal dataGrid As DataGrid, Optional ByVal nombreTablas() As String = Nothing) ' Procedimiento que muestra en un dataGrid varias tablas ' El procedimiento llena un DataTable mediante varias consultas ingresadas en un arreglo Dim i As Integer Dim CN As New NpgsqlConnection(cadenaConexion) Dim DA As NpgsqlDataAdapter Dim DS As New DataSet For i = 0 To sentenciasSQL.GetUpperBound(0) DA = New NpgsqlDataAdapter(sentenciasSQL(i), CN) If nombreTablas Is Nothing Then 'Si no se ingreso el nombre de las tablas DA.Fill(DS, """Tabla """ & i + 1) Else 'Si se ingreso el nombre de las tablas DA.Fill(DS, nombreTablas(i)) End If Next dataGrid.DataSource = DS End Sub #End Region #Region "ListView" Sub llenarListView_con_DataTable(ByVal DT As DataTable, ByVal LV As ListView, _ Optional ByVal cabeceras() As String = Nothing, Optional ByVal enumerarFilas As Boolean = False)

Página 154

Docente: Ing. Núñez Marinovich Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación ' Procedimiento que llena un dataTable en un ListView Dim i, j As Integer LV.Items.Clear() LV.View = View.Details LV.FullRowSelect = True ' permite la seleccion de toda una fila 'lv.GridLines = True ' muestra el listview una grilla LV.AllowColumnReorder = True ' permite cambiarle el orden de aparicion de las columnas If Not cabeceras Is Nothing Then LV.Columns.Clear() For i = 0 To cabeceras.GetUpperBound(0) LV.Columns.Add(cabeceras(i), 100, HorizontalAlignment.Center) Next End If Dim ls As ListViewItem If enumerarFilas Then ' enumeramos las filas en la primera columna del listview For i = 0 To DT.Rows.Count - 1 ls = LV.Items.Add(i + 1) For j = 0 To DT.Columns.Count - 1 ls.SubItems.Add(DT.Rows(i).Item(j).ToString) Next Next Else ' No enumeramos las filas For i = 0 To DT.Rows.Count - 1 ls = LV.Items.Add(DT.Rows(i).Item(0).ToString) For j = 1 To DT.Columns.Count - 1 ls.SubItems.Add(DT.Rows(i).Item(j).ToString) Next Next End If End Sub Sub llenarListView(ByVal cadenaConexion As String, ByVal sentenciaSQL As String, _ ByVal listaCampos() As String, ByVal ListView As ListView, _ Optional ByVal cabeceraColumna() As String = Nothing, _ Optional ByVal enumerarFilas As Boolean = False, _ Optional ByVal anchoColumna() As Integer = Nothing, _ Optional ByVal alineamientoColumna() As HorizontalAlignment = Nothing) ' Procedimiento que ejecuta una sentencia SQL ' y el resultado lo muestra en un listView Dim CN As New NpgsqlConnection(cadenaConexion) Dim CMD As New NpgsqlCommand(sentenciaSQL, CN) Dim DR As NpgsqlDataReader Dim ls As ListViewItem Dim i As Integer Try ' Configuramos el ListView ListView.View = View.Details ListView.FullRowSelect = True ' permite la seleccion de toda una fila 'ListView.GridLines = True ' muestra el listview una grilla ListView.AllowColumnReorder = True ' permite cambiarle el orden de aparicion de las columnas ' Limpiampos las columnas y los items dentro del ListView ListView.Columns.Clear() ListView.Items.Clear() If enumerarFilas Then ' Enumeramos las filas ' llenamos las cabeceras de columna del ListView ListView.Columns.Add("Nro", 40, HorizontalAlignment.Center) For i = 0 To listaCampos.GetUpperBound(0) ListView.Columns.Add(listaCampos(i), 100, HorizontalAlignment.Left) Next CN.Open()

Página 155

Docente: Ing. Núñez Marinovich Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación DR = CMD.ExecuteReader() ' llenamos el ListView con los datos del dataReader Dim reg As Integer = 0 While DR.Read 'ls = ListView.Items.Add(Trim(DR.Item(listaCampos(0)))) reg += 1 ls = ListView.Items.Add(reg) For i = 0 To listaCampos.GetUpperBound(0) ls.SubItems.Add(DR.Item(listaCampos(i).ToString).ToString) Next End While CN.Close() Else ' No enumeramos las filas ' llenamos las cabeceras de columna del ListView For i = 0 To listaCampos.GetUpperBound(0) ListView.Columns.Add(listaCampos(i), 100, HorizontalAlignment.Center) Next CN.Open() DR = CMD.ExecuteReader() ' llenamos el ListView con los datos del dataReader While DR.Read ls = ListView.Items.Add(DR.Item(listaCampos(0)).ToString) For i = 1 To listaCampos.GetUpperBound(0) ls.SubItems.Add(DR.Item(listaCampos(i)).ToString) Next End While CN.Close() End If If Not cabeceraColumna Is Nothing Then For i = 0 To listaCampos.GetUpperBound(0) ListView.Columns.Item(i).Text = cabeceraColumna(i).Trim Next End If If Not anchoColumna Is Nothing Then For i = 0 To listaCampos.GetUpperBound(0) ListView.Columns.Item(i).Width = anchoColumna(i) Next End If If Not alineamientoColumna Is Nothing Then For i = 0 To listaCampos.GetUpperBound(0) ListView.Columns.Item(i).TextAlign = alineamientoColumna(i) Next End If Catch ex As NpgsqlException MsgBox(ex.Message) End Try End Sub Sub llenarListView(ByVal cadenaConexion As String, ByVal sentenciaSQL As String, ByVal ListView As ListView, _ Optional ByVal cabeceras() As String = Nothing, Optional ByVal enumerarFilas As Boolean = False) ' Procedimiento que ejecuta una sentencia SQL y el resultado lo muestra en un ListView ' El procedimiento llena un ListView mediante una consulta Dim CN As New NpgsqlConnection(cadenaConexion) Dim DA As New NpgsqlDataAdapter(sentenciaSQL, CN) Dim DT As New DataTable ' actua como un repositorio de la informacion consultada ' abre la conexion, ejecuta la consulta, llena el DT y cierra la conexion DA.Fill(DT) llenarListView_con_DataTable(DT, ListView, cabeceras, enumerarFilas) End Sub #End Region #Region "TreeView"

Página 156

Docente: Ing. Núñez Marinovich Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación Sub llenarCamposTreeView(ByVal cadenaConexion As String, ByVal listaCampos() As String, ByVal sentenciasSQL() As String, ByVal TreeView As TreeView, Optional ByVal nombreNodosPadres() As String = Nothing) ' Procedimiento en la que se ingresa una lista de campos y sus respectivas sentencias SQL ' en las q se mostraran cada campo con sus respectivos datos en un Treeview ' Como nodo padre estara el nombre del campo, y sus hijos seran sus respectivos datos ' de acuerdo a la sentencia Dim cn As New NpgsqlConnection(cadenaConexion) Dim ParentNode As TreeNode Dim ChildNode As TreeNode Dim i As Integer TreeView.Nodes.Clear() For i = 0 To listaCampos.GetUpperBound(0) Dim CMD As New NpgsqlCommand(sentenciasSQL(i), cn) Dim DR As NpgsqlDataReader If nombreNodosPadres Is Nothing Then ParentNode = New TreeNode(Trim(listaCampos(i))) Else ' si es q hemos ingresado el nombre de los nodos padres ParentNode = New TreeNode(Trim(nombreNodosPadres(i))) End If TreeView.Nodes.Add(ParentNode) With CMD .Connection.Open() 'abrimos la conexion DR = .ExecuteReader While DR.Read ChildNode = ParentNode.Nodes.Add(Trim(DR(listaCampos(i)).ToString)) End While .Connection.Close() End With Next 'Ejemplo: 'Dim lc() As String 'lc = {"CampoChar", "CampoInteger"} 'Dim lS() As String 'lS = {"select * from ""Tabla1""", "select * from ""Tabla2"""} 'Base_Datos.PostgreSQL.llenarCamposTreeView(strcn, lc, lS, Me.TreeView1) End Sub

#End Region #Region "List Box" Sub llenarListBox_DataReader(ByVal cadenaConexion As String, ByVal ListBox As ListBox, ByVal tabla As String, ByVal campo As String, Optional ByVal ordenacion As TipoOrdenacion = TipoOrdenacion.Ninguna, Optional ByVal limpiarLista As Boolean = True) ' Funcion que ejecuta una sentencia SQL y el resultado lo muestra en un ListBox ' En este codigo usamos el objeto DataReader para el acceso rapido y optimo a la BD ' instancia el objeto y en el constructor le entrego a la cadena de conexion Dim sentenciaSQL As String = "select " & campo & " from " & tabla If ordenacion = TipoOrdenacion.Ascendente Then sentenciaSQL &= " order by " & campo & " asc" ElseIf ordenacion = TipoOrdenacion.Descendente Then sentenciaSQL &= " order by " & campo & " desc" End If Dim cn As New NpgsqlConnection(cadenaConexion) Dim CMD As New NpgsqlCommand(sentenciaSQL, cn) Dim DR As NpgsqlDataReader If limpiarLista Then ListBox.Items.Clear() With CMD .Connection.Open() 'abrimos la conexion DR = .ExecuteReader While DR.Read ListBox.Items.Add(DR(campo.Replace("""", ""))) End While .Connection.Close() End With

Página 157

Docente: Ing. Núñez Marinovich Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación End Sub Sub llenarListBox_DataReader(ByVal cadenaConexion As String, ByVal sentenciaSQL As String, ByVal campo As String, ByVal ListBox As ListBox, Optional ByVal limpiarLista As Boolean = True) ' Funcion que ejecuta una sentencia SQL y el resultado lo muestra en un ListBox ' En este codigo usamos el objeto DataReader para el acceso rapido y optimo a la BD ' instancia el objeto y en el constructor le entrego a la cadena de conexion Dim cn As New NpgsqlConnection(cadenaConexion) Dim CMD As New NpgsqlCommand(sentenciaSQL, cn) Dim DR As NpgsqlDataReader If limpiarLista Then ListBox.Items.Clear() With CMD .Connection.Open() 'abrimos la conexion DR = .ExecuteReader While DR.Read ListBox.Items.Add(DR(campo.Replace("""", ""))) End While .Connection.Close() End With End Sub #End Region #Region "Combo Box" Sub llenarComboBox_DataReader(ByVal cadenaConexion As String, ByVal ComboBox As ComboBox, ByVal tabla As String, ByVal campo As String, Optional ByVal ordenacion As TipoOrdenacion = TipoOrdenacion.Ninguna, Optional ByVal limpiarLista As Boolean = True) ' Funcion que ejecuta una sentencia SQL y el resultado lo muestra en un ListBox ' En este codigo usamos el objeto DataReader para el acceso rapido y optimo a la BD ' instancia el objeto y en el constructor le entrego a la cadena de conexion Dim sentenciaSQL As String = "select " & campo & " from " & tabla If ordenacion = TipoOrdenacion.Ascendente Then sentenciaSQL &= " order by " & campo & " asc" ElseIf ordenacion = TipoOrdenacion.Descendente Then sentenciaSQL &= " order by " & campo & " desc" End If Dim cn As New NpgsqlConnection(cadenaConexion) Dim CMD As New NpgsqlCommand(sentenciaSQL, cn) Dim DR As NpgsqlDataReader If limpiarLista Then ComboBox.Items.Clear() With CMD .Connection.Open() 'abrimos la conexion DR = .ExecuteReader While DR.Read ComboBox.Items.Add(DR(campo.Replace("""", ""))) End While .Connection.Close() End With End Sub Sub llenarComboBox_DataReader(ByVal cadenaConexion As String, ByVal sentenciaSQL As String, ByVal campo As String, ByVal ComboBox As ComboBox, Optional ByVal limpiarLista As Boolean = True) ' Funcion que ejecuta una sentencia SQL y el resultado lo muestra en un ComboBox ' En este codigo usamos el objeto DataReader para el acceso rapido y optimo a la BD ' instancia el objeto y en el constructor le entrego a la cadena de conexion Dim cn As New NpgsqlConnection(cadenaConexion) Dim CMD As New NpgsqlCommand(sentenciaSQL, cn) Dim DR As NpgsqlDataReader If limpiarLista Then ComboBox.Items.Clear() With CMD .Connection.Open() 'abrimos la conexion DR = .ExecuteReader While DR.Read ComboBox.Items.Add(DR(campo.Replace("""", ""))) End While .Connection.Close()

Página 158

Docente: Ing. Núñez Marinovich Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación End With End Sub Sub llenarComboBox_AñosCampoFecha(ByVal cadenaConexion As String, ByVal CBO As ComboBox, _ ByVal tabla As String, ByVal campo As String, Optional ByVal seleccionarPrimerElemento As Boolean = False) ' Muestra en un combobox, con los años existentes en un campo de tipo fecha Dim sentencia As String sentencia = _ "select distinct date_part('year'," & campo & ") AS ""anio"" from " & tabla & _ " order by date_part('year'," & campo & ") asc" llenarComboBox_DataReader(cadenaConexion, sentencia, """anio""", CBO) If seleccionarPrimerElemento Then CBO.SelectedIndex = CBO.Items.Count - 1 End Sub #End Region

Function ejecutarCommand(ByVal cadenaConexion As String, ByVal sentenciaSQL As String) ' Funcion que ejecuta una sentencia SQL (Insert , Delete, Update) ' Opcionalment devuelve el numero de filas afectadas Dim CN As New NpgsqlConnection(cadenaConexion) Dim Cmd As New NpgsqlCommand(sentenciaSQL, CN) Try CN.Open() ' ejecuta la consulta y devolvemos el numero de filas afectadas Return Cmd.ExecuteNonQuery CN.Close() Catch ex As NpgsqlException MsgBox(ex.Message) End Try End Function Function ejecutarCommand2(ByVal sentenciaSQL As String, _ Optional ByVal BaseDatos As String = "postgres", Optional ByVal Servidor As String = "localhost", _ Optional ByVal Usuario As String = "postgres", Optional ByVal Password As String = "") ' Funcion que ejecuta una sentencia SQL (Insert , Delete, Update) ' Opcionalment devuelve el numero de filas afectadas Dim cadenaConexion As String cadenaConexion = generarCadenaConexion(BaseDatos, Servidor, Usuario, Password) Dim CN As New NpgsqlConnection(cadenaConexion) Dim Cmd As New NpgsqlCommand(sentenciaSQL, CN) Try CN.Open() ' ejecuta la consulta y devolvemos el numero de filas afectadas Return Cmd.ExecuteNonQuery CN.Close() Catch ex As NpgsqlException MsgBox(ex.Message) End Try End Function End Class #End Region

Página 159

Docente: Ing. Núñez Marinovich Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación

JDBC (Java Database Connectivity), es un API conformada por un conjunto de interfaces y clases Java que nos permiten acceder de una forma genérica a las bases de datos independiente del proveedor.

Componentes del API JDBC Gestor de Drivers Conexión con la base de datos Ejecutar sentencias Manejo de resultado Sentencias con parámetros Procedimiento almacenado

Página 160

java.sql.DriverManager java.sql.Connection java.sql.Statement java.sql.ResultSet java.sql.PreparedStatement java.sql.CallableStatement

Docente: Ing. Núñez Marinovich Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación Conexión JDBC a MySQL package pruebas; import java.sql.Connection; import java.sql.DatabaseMetaData; import java.sql.DriverManager; import java.util.logging.Level; import java.util.logging.Logger; public class ConexionMySQL { public static void main(String[] args) { // Conexión con MySQL try { Class.forName("com.mysql.jdbc.Driver").newInstance(); System.out.println("Driver cargado correctamente."); String url = "jdbc:mysql://localhost:3306/eurekabank"; Connection cn = DriverManager.getConnection(url, "root", "mysql"); System.out.println("Conexión ok."); DatabaseMetaData dbmd = cn.getMetaData(); String dbms = dbmd.getDatabaseProductName(); String version = dbmd.getDatabaseProductVersion(); System.out.println("Database: " + dbms); System.out.println("Version: " + version); cn.close(); System.out.println("Conexión cerrada."); } catch (Exception ex) { Logger.getLogger(Prueba01.class.getName()).log(Level.SEVERE, null, ex); } } }

Conexión JDBC a Oracle package pruebas; // Conexión Oracle import java.sql.Connection; import java.sql.DatabaseMetaData; import java.sql.DriverManager; import java.util.logging.Level; import java.util.logging.Logger; public class ConexionOracle { public static void main(String[] args) { // Conexión con Oracle try { Class.forName("oracle.jdbc.OracleDriver").newInstance(); System.out.println("Driver cargado correctamente."); String url = "jdbc:oracle:thin:@localhost:1521:orcl"; Connection cn = DriverManager.getConnection(url, "eurekabank", "admin"); System.out.println("Conexión ok."); DatabaseMetaData dbmd = cn.getMetaData(); String dbms = dbmd.getDatabaseProductName(); String version = dbmd.getDatabaseProductVersion(); System.out.println("Database: " + dbms); System.out.println("Version: " + version); cn.close(); System.out.println("Conexión cerrada."); } catch (Exception ex) { Logger.getLogger(Prueba01.class.getName()).log(Level.SEVERE, null, ex); } } }

Página 161

Docente: Ing. Núñez Marinovich Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación Conexión JDBC a SQL Server package pruebas; import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.Statement; public class ConexionSQLServer {

}

public static void main(String[] args) { try { Class.forName("net.sourceforge.jtds.jdbc.Driver").newInstance(); Connection cn = DriverManager.getConnection("jdbc:jtds:sqlserver://localhost/edutec", "sa", "sql"); String query = "SELECT * from dbo.profesor"; Statement stm = cn.createStatement(); ResultSet rs = stm.executeQuery(query); while( rs.next() ){ System.out.println(rs.getString("idprofesor") + " " + rs.getString("nomprofesor")); } rs.close(); cn.close(); } catch (Exception e) { System.out.println(e.getMessage()); } }

Conexión JDBC a PostgreSQL package pruebas; import java.sql.Connection; import java.sql.DatabaseMetaData; import java.sql.DriverManager; public class ConexionPostgreSQL { public static void main(String[] args) { // Conexión con PostgreSQL, no olvidar agregar al libreria (PostgreSQL JDBC Driver) try { Class.forName("org.postgresql.Driver").newInstance(); System.out.println("Driver cargado correctamente."); String url = "jdbc:postgresql://localhost:5432/bdlibros"; Connection cn = DriverManager.getConnection(url, "postgres", "1"); System.out.println("Conexión ok."); DatabaseMetaData dbmd = cn.getMetaData(); String dbms = dbmd.getDatabaseProductName(); String version = dbmd.getDatabaseProductVersion(); System.out.println("Database: " + dbms); System.out.println("Version: " + version); cn.close(); System.out.println("Conexión cerrada."); } catch (Exception ex) { System.out.println("Error: " + ex.getMessage()); } } }

Página 162

Docente: Ing. Núñez Marinovich Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación Acceso a una Instancia Única del Objeto Connection

public class AccesoDB { private static Connection cn = null; public static Connection getConnection() throws Exception { if(cn == null){ try { Class.forName("com.mysql.jdbc.Driver").newInstance(); String url = "jdbc:mysql://localhost:3306/eurekabank"; cn = DriverManager.getConnection(url, "root", "admin"); } catch (Exception e) { throw e; } } return cn; } }

Ejemplo con Objeto PreparedStatement – Insertar Registro public void agregaProducto(String nombreProducto, Integer stock, Double precioVenta, String rutaImagen, String descripcion) throws Exception { Connection cn = null; try { cn = AccesoDB.getConnection(); cn.setAutoCommit(false); String query = "insert producto(nombreProducto,stock,precioVenta,rutaImagen,descripcion)" + "values(?,?,?,?,?)"; PreparedStatement pstm = cn.prepareStatement(query); pstm.setString(1, nombreProducto); pstm.setInt(2, stock); pstm.setDouble(3, precioVenta); pstm.setString(4, rutaImagen); pstm.setString(5, descripcion); pstm.executeUpdate(); // Confirmar Tx cn.commit(); } catch (Exception e) { try { cn.rollback(); } catch (Exception e1) { } throw e; } finally { try { cn.close(); // Devuelves la conexión al pool cn=null; } catch (Exception e) { } } }

Página 163

Docente: Ing. Núñez Marinovich Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación Ejemplo con Objeto Statement y ResultSet – Verificar existencia usuario public class LoginModel { public void validar(Map<String, String> emp) throws Exception { try { Connection cn = AccesoDB.getConnection(); // Acceso al objeto connection String query = "SELECT * from empleado where vch_emplusuario = ?"; PreparedStatement pstm = cn.prepareStatement(query); pstm.setString(1, emp.get("usuario")); ResultSet rs = pstm.executeQuery(); if (!rs.next()) { throw new Exception("Datos incorrectos."); } String clave = rs.getString("vch_emplclave"); if (!emp.get("clave").equals(clave)) { throw new Exception("Datos incorrectos."); } emp.put("codigo", rs.getString("chr_emplcodigo")); emp.put("nombre", rs.getString("vch_emplnombre")); emp.put("apellido", rs.getString("vch_emplpaterno") + " " + rs.getString("vch_emplmaterno")); } catch (Exception e) { throw e; } } } Ejemplo con Objeto Statement y ResultSet – Devolver Conjunto de resultados public Map<String, String> traerComboClientes() throws Exception { Connection cn = AccesoDB.getConnection(); String query = "SELECT chr_cliecodigo as codigo, " + "concat(vch_cliepaterno,' ',vch_cliematerno," + "', ',vch_clienombre) as nombre from cliente"; Statement stm = cn.createStatement(); ResultSet rs = stm.executeQuery(query); Map<String,String> lista = new HashMap<String, String>(); while( rs.next() ){ lista.put(rs.getString("codigo"), rs.getString("nombre")); } rs.close(); return lista; }

Página 164

Docente: Ing. Núñez Marinovich Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación Ejemplo con Objeto PreparedStatement y ResultSet – Devolver Conjunto de resultados public List<Map<String,String>> consultarCuenta( String cuenta) throws Exception { List<Map<String,String>> lista = new ArrayList<Map<String, String>>(); Connection cn = AccesoDB.getConnection(); String query = "SELECT * FROM cuenta WHERE chr_cuencodigo = ?"; PreparedStatement pstm = cn.prepareStatement(query); pstm.setString(1, cuenta); ResultSet rs = pstm.executeQuery(); while(rs.next()){ Map<String,String> rec = new HashMap<String, String>(); rec.put("codigo", String.valueOf(rs.getString("chr_monecodigo"))); rec.put("sucursal", rs.getString("chr_sucucodigo").toString()); rec.put("fecha", rs.getString("dtt_cuenfechacreacion")); rec.put("estado", String.valueOf(rs.getString("vch_cuenestado"))); lista.add(rec); } rs.close(); return lista; } Ejemplo con Objeto CallableStatement public void registrarDeposito(String cuenta, Double importe, String empleado) throws Exception { Connection cn = AccesoDB.getConnection(); cn.setAutoCommit(true); String query = "{call usp_deposito(?,?,?,?)}"; CallableStatement cstm = cn.prepareCall(query); cstm.registerOutParameter(1, Types.VARCHAR,50); cstm.setString(2, cuenta); cstm.setDouble(3, importe); cstm.setString(4, empleado); cstm.executeUpdate(); String estado = cstm.getString(1); if( ! estado.equals("ok") ){ throw new Exception(estado); } }

Página 165

Docente: Ing. Núñez Marinovich Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación

PHP (acrónimo recursivo que significa PHP Hypertext Pre-processor) es un lenguaje de programación interpretado, diseñado originalmente para la creación de páginas web dinámicas. Se usa principalmente para la interpretación del lado del servidor (server-side scripting).

Funciones PHP para MySQL: Función mysql_affected_rows mysql_change_user mysql_client_encoding mysql_close mysql_connect mysql_create_db mysql_data_seek mysql_db_name mysql_db_query mysql_drop_db mysql_errno mysql_error mysql_escape_string mysql_fetch_array mysql_fetch_assoc mysql_fetch_field mysql_fetch_lengths mysql_fetch_object mysql_fetch_row mysql_field_flags mysql_field_len mysql_field_name mysql_field_seek mysql_field_table mysql_field_type mysql_free_result mysql_get_client_info mysql_get_host_info mysql_get_proto_info mysql_get_server_info mysql_info mysql_insert_id mysql_list_dbs mysql_list_fields mysql_list_processes mysql_list_tables mysql_num_fields mysql_num_rows mysql_pconnect

Página 166

Descripción Devuelve el número de filas afectadas de la última operación MySQL Cambia el usuario conectado en la conexión activa Devuelve el nombre del juego de caracteres cierra el enlace con MySQL Abre una conexión a un servidor MySQL Crea una base MySQL Mueve el puntero interno Obtener datos de resultado Envia una sentencia MySQL al servidor Borra una base de datos MySQL Deuelve el número del mensaje de error de la última operación MySQL Devuelve el texto del mensaje de error de la última operación MySQL Escapa una cadena para su uso en mysql_query Extrae la fila de resultado como una matriz asociativa, una matriz numérica o ambas Recupera una fila de resultado como una matriz asociativa Extrae la información de una columna y la devuelve como un objeto. Devuelve la longitud de cada salida en un resultado Extrae una fila de resultado como un objeto Devuelve una fila de resultado como matriz Devuelve las banderas asociados con el campo específicado en un resultado Devuelve la longitud del campo específicado Devuelve el nombre del campo específicado en un resultado Asigna el puntero del resultado al offset del campo específicado Devuelve el nombre de la tabla donde está el campo específicado Devuelve el tipo del campo específicado en un resultado Libera la memoria del resultado Obtener información del cliente MySQL Obtener información de la máquina anfitriona MySQL Obtener información del protocolo MySQL Obtener información del servidor MySQL Obtiene información sobre la consulta más reciente Devuelve el identificador generado en la última llamada a INSERT Lista las bases de datos disponibles en el servidor MySQL Lista los campos del resultado de MySQL Lista los procesos MySQL Lista las tablas en una base de datos MySQL Devuelve el número de campos de un resultado Devuelve el número de filas de un resultado Abre una conexión persistente al servidor MySQL Docente: Ing. Núñez Marinovich Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación mysql_ping mysql_query mysql_real_escape_string mysql_result mysql_select_db mysql_stat mysql_tablename mysql_thread_id mysql_unbuffered_query

Efectuar un chequeo de respuesta (ping) sobre una conexión de servidor o reconectarse si no hay conexión Envía una consulta de MySQL Escapa caracteres especiales de una cadena para su uso en una sentencia SQL Devuelve datos de un resultado Selecciona un base de datos MySQL Obtener el status actual del sistema Devuelve el nombre de la tabla de un campo Devuelve el ID del hilo actual Envía una consulta SQL a MySQL, sin recuperar ni colocar en búfer las filas de resultado

Conexión PHP a MySQL Mantemimiento de una Tabla en MySQL Insertar, Actualizar, Eliminar registros, Busqueda, Paginación. Uso de JS, CSS, jQuery Fuente: http://www.ribosomatic.com/articulos/tutorial-aplicacion-web-con-jquery-php-mysql-mantenimiento-de-datos/ Se agrego nuevas funcionalidades al ejemplo original de la página, como búsqueda, paginación y más funcionalidades de jquery.

Estructura de archivos:

Script BD mysql CREATE TABLE IF NOT EXISTS `cliente` ( `id` tinyint(7) NOT NULL auto_increment, `nombres` varchar(50) NOT NULL, `ciudad` varchar(50) NOT NULL, `sexo` char(1) NOT NULL, `telefono` varchar(10) NOT NULL, `fecha_nacimiento` datetime NOT NULL, KEY `id` (`id`) ) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;

Página 167

Docente: Ing. Núñez Marinovich Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación conexión.class.php <?php class BDMySQL{ var $conect; var var var var

$BaseDatos; $Servidor; $Usuario; $Clave;

function BDMySQL(){ $this->BaseDatos = "bdpersonas"; $this->Servidor = "localhost"; $this->Usuario = "root"; $this->Clave = "mysql"; } function conectar() { if(!($con=@mysql_connect($this->Servidor,$this->Usuario,$this->Clave))){ echo"<h1> Error al conectar a la base de datos</h1>"; exit(); } if (!@mysql_select_db($this->BaseDatos,$con)){ echo "<h1> Error al seleccionar la base de datos</h1>"; exit(); } $this->conect=$con; return true; }

/****************************************************************************** --------------------------------------------------- Funciones de Base de Datos ******************************************************************************/ function devolverEscalar($sentencia) { $resultado=@mysql_query($sentencia, $this->conect) or die("<h2>No se pudo ejecutar la consulta $sentencia.</h2>"); $fila=mysql_fetch_array($resultado); return $fila[0]; } function devolverNroRegistrosConsulta($sentencia) { $tabla=@mysql_query($sentencia, $this->conect) or die ("<h2>Error en la consulta</h2>"); /***********Nro de registros ********/ $totalreg=mysql_num_rows($tabla); return $totalreg; }

function devolverNroRegistrosTabla($tabla) { $sentencia = "select count(*) from $tabla "; return $this->devolverEscalar($sentencia); }

function esConsultaVacia($sentencia) { $tabla=@mysql_query($sentencia, $this->conect) or die ("<h2>Error en la consulta</h2>");

Página 168

Docente: Ing. Núñez Marinovich Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación $totalreg=mysql_num_rows($tabla); if ($totalreg>0) // Si es mayor q cero entonces no esta vacia // y asignamos a resultado el valor de 0 $resultado=0; else // Si NO es mayor q cero entonces esta vacia // y asignamos a resultado el valor de 1, indicando q esta vacia $resultado=1; return $resultado; } function entraConsultaBD_saleColumna($sentencia,$nroColumna=0) { /* Funcion que devuelve en un array los elementos de una determinada columna de una consulta extraida de la BD. */ $tabla=@mysql_query($sentencia, $this->conect) or die ("<h2>Error en la consulta</h2>"); $resultado=array(); while($fila=mysql_fetch_array($tabla)) { //agregamos los elementos al array array_push($resultado,$fila[$nroColumna]); } return $resultado; } function llenarLista($sentencia,$nombreControl, $nroColumnaValue=0, $nroColumnaVisualizar=0, $controlSize=15) { /* Procedimiento que llena en una lista el resultado de una determinada consulta */ $tabla=@mysql_query($sentencia, $this->conect) or die ("<h2>Error en la consulta</h2>"); echo"<SELECT NAME='$nombreControl' SIZE=$controlSize>"; while($fila=mysql_fetch_array($tabla)) echo"<OPTION VALUE=$fila[$nroColumnaValue]>".$fila[$nroColumnaVisualizar]; echo"</SELECT>"; } } ?>

Cliente.class.php <?php include_once("conexion.class.php"); class Cliente{ //constructor var $con; function Cliente(){ $this->con=new BDMySQL; }

Página 169

Docente: Ing. Núñez Marinovich Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación function insertar($campos){ if($this->con->conectar()==true){ //print_r($campos); //echo "INSERT INTO cliente (nombres, ciudad, sexo, telefono, fecha_nacimiento) VALUES ('".$campos[0]."', '".$campos[1]."','".$campos[2]."','".$campos[3]."','".$campos[4]."')"; return mysql_query("INSERT INTO cliente (nombres, ciudad, sexo, telefono, fecha_nacimiento) VALUES ('".$campos[0]."', '".$campos[1]. "','".$campos[2]. "','".$campos[3]. "','".$campos[4]."')"); } } function actualizar($campos,$id){ if($this->con->conectar()==true){ //print_r($campos); return mysql_query("UPDATE cliente SET nombres = '".$campos[0]."', ciudad = '".$campos[1]."', sexo = '".$campos[2]."', telefono = '".$campos[3]."', fecha_nacimiento = '".$campos[4]."' WHERE id = ".$id); } } function mostrar_cliente($id){ if($this->con->conectar()==true){ return mysql_query("SELECT * FROM cliente WHERE id=".$id); } } function mostrar_clientes(){ if($this->con->conectar()==true){ return mysql_query("SELECT * FROM cliente ORDER BY id DESC"); } } function mostrar_clientes2($inicio, $total, $busqueda=""){ if($this->con->conectar()==true){ return mysql_query("SELECT * FROM cliente WHERE nombres LIKE '%".$busqueda."%' OR ciudad LIKE '%".$busqueda."%' OR telefono LIKE '%".$busqueda."%' ORDER BY nombres LIMIT ".$inicio.",".$total); } } function eliminar($id){ if($this->con->conectar()==true){ return mysql_query("DELETE FROM cliente WHERE id=".$id); } } function totalClientes(){ if($this->con->conectar()==true){ //----Primera forma: //$tabla=$this->mostrar_clientes(); //return mysql_num_rows($tabla); //----Segunda forma: //return $this->con->devolverEscalar("select count(*) from cliente"); //----Tercera forma: //return $this->con->devolverNroRegistrosConsulta("select * from cliente"); //----Cuarta forma: return $this->con->devolverNroRegistrosTabla("cliente"); } } } ?>

Página 170

Docente: Ing. Núñez Marinovich Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación index.php <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>Mantenimiento de Clientes</title> <script src="jquery/jquery-1.5.min.js" type="text/javascript"></script> <script type="text/javascript" src="jquery/jquery-ui-1.8.9.custom.min.js"></script> <script src="js/jquery.functions.js" type="text/javascript"></script> <link rel="stylesheet" type="text/css" href="jquery/smoothness/jquery-ui-1.8.9.custom.css"> <link type="text/css" rel="stylesheet" href="css/estilo.css" /> </head> <body> <div id="contenedor"> <div id="formulario" style="display:none;"> </div>

<div id="tabla"> <?php include('consulta.php') ?> </div> </div> </body> </html>

Consulta.php <?php require('clases/cliente.class.php'); $objCliente=new Cliente; //Obtener nro $nro = $_GET[nro]; if(!isset($nro)) $nro=0; //Obtener palabra de busqueda $palabraBusqueda = $_GET[busqueda]; if(!isset($palabraBusqueda)) $palabraBusqueda="";

$regxpag= 10; //$consulta=$objCliente->mostrar_clientes(); $consulta=$objCliente->mostrar_clientes2($nro,$regxpag,$palabraBusqueda); ?> <script type="text/javascript"> $(document).ready(function () { // mostrar formulario de actualizar datos $("table tr .modi a").click(function () { //$('#tabla').hide(); $("#formulario").show("slow"); $.ajax({ url: this.href, type: "GET", success: function (datos) { $("#formulario").html(datos); } }); $("#formulario").dialog({

Página 171

Docente: Ing. Núñez Marinovich Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación autoOpen: false, show: 'slide', modal: true, width: 580, height: 300, title: "Actualizar" }); $("#formulario").dialog("open"); return false; }); // llamar a formulario nuevo $("#nuevo a").click(function () { $("#formulario").show("slow"); //$("#formulario").toggle("slow"); //$("#tabla").hide(); $.ajax({ type: "GET", url: 'nuevo.php', success: function (datos) { $("#formulario").html(datos); } }); $("#formulario").dialog({ autoOpen: false, show: 'slide', modal: true, width: 580, height: 300, title: "Agregar" }); $("#formulario").dialog("open"); return false; }); // numeros de la paginacion $("#paginacion a").click(function () { // $("#tabla").load(this.href); //$("#formulario").show("slow"); $("#tabla").hide(); //$("#tabla").show("slow"); $("#tabla").fadeIn(1000); $.ajax({ type: "GET", url: this.href, success: function (datos) { $("#tabla").html(datos); } }); return false; }); // busqueda $("#buscar a").click(function () { var valorBusqueda = $("#txtBusqueda").val(); $("#tabla").hide(); //$("#tabla").show("slow"); $("#tabla").fadeIn(1000); $.ajax({ type: "GET", url: "consulta.php?busqueda=" + valorBusqueda, success: function (datos) { $("#tabla").html(datos); }

Página 172

Docente: Ing. Núñez Marinovich Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación }); return false; }); });

</script> <br/> <table border="0"> <tr><td width="40"> <span id="nuevo"><a href="nuevo.php"><img /></a></span> </td>

src="img/add.png" alt="Agregar"

<td width="70">Busqueda</td> <td> <span id="buscar"> <input type="text" size="20" maxlength="20" id="txtBusqueda" name="txtBusqueda"/> <a href="#"> <img src="img/buscar.gif" alt="Buscar" width="20" height="20" border="0"/></a></span>

</td></tr> </table> <table> <tr> <th>Nombres</th> <th>Ciudad</th> <th>Sexo</th> <th>Telefono</th> <th>Fecha Nacimiento</th> <th></th> <th></th> </tr> <?php if($consulta) { while( $cliente = mysql_fetch_array($consulta) ){ ?> <tr id="fila-<?php echo $cliente['id'] ?>"> <td><?php echo $cliente['nombres'] ?></td> <td><?php echo $cliente['ciudad'] ?></td> <td align="center"><?php echo $cliente['sexo'] ?></td> <td align="center"><?php echo $cliente['telefono'] ?></td> <td align="center"><?php echo $cliente['fecha_nacimiento'] ?></td> <td><span class="modi"><a href="actualizar.php?id=<?php echo $cliente['id'] ?>"><img src="img/database_edit.png" title="Editar" alt="Editar" /></a></span></td> <td><span class="dele"><a onClick="EliminarDato(<?php echo $cliente['id'] ?>); return false" href="eliminar.php?id=<?php echo $cliente['id'] ?>"><img src="img/delete.png" title="Eliminar" alt="Eliminar" /></a></span></td> </tr> <?php } } ?> </table> <span id="paginacion" align="center"> <?php $totalreg=$objCliente->totalClientes();

/***********calculando el nro de paginas ********/ $nropags=$totalreg/$regxpag;

Página 173

Docente: Ing. Núñez Marinovich Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación /*********** imprimiendo el nro de paginas ******/ echo "<center>"; for($j=0; $j<=$nropags; $j++) {$inicio=$j*$regxpag; if($nro==$inicio) echo "<a href='consulta.php?nro=$inicio'> <font face='verdana' size='3' color='#3399FF'><b>[$j]</b></font></a>"; else echo "<a href='consulta.php?nro=$inicio'><font face='verdana' size='2'>[$j]</font></a>"; } echo "</center>"; /***********fin de la paginacion********/ echo "<p align='center'><br>Total: ".$totalreg ."</p>'"; ?> </span>

Nuevo.php <?php require('functions.php'); if(isset($_POST['submit'])){ require('clases/cliente.class.php'); $nombres = htmlspecialchars(trim($_POST['nombres'])); $ciudad = htmlspecialchars(trim($_POST['ciudad'])); $sexo = htmlspecialchars(trim($_POST['alternativas'])); $telefono = htmlspecialchars(trim($_POST['telefono'])); $fecha_nacimiento = htmlspecialchars(trim($_POST['fecha_nacimiento'])); $objCliente=new Cliente; if ( $objCliente->insertar(array($nombres,$ciudad,$sexo,$telefono,$fecha_nacimiento)) == true){ echo 'Datos guardados'; }else{ echo 'Se produjo un error. Intente nuevamente'; } }else{ ?> <form id="frmClienteNuevo" name="frmClienteNuevo" method="post" action="nuevo.php" onsubmit="GrabarDatos(); return false"> <p><label>Nombres<br /> <input class="text" type="text" name="nombres" id="nombres" /> </label> </p> <p> <label>Ciudad<br /> <input class="text" type="text" name="ciudad" id="ciudad" /> </label> </p> <p> <label> <input type="radio" name="alternativas" id="masculino" value="M" /> Masculino</label> <label> <input type="radio" name="alternativas" id="femenino" value="F" /> Femenino</label> </p> <p> <label>Telefono<br /> <input class="text" type="text" name="telefono" id="telefono" /> </label> </p> <p> <label>Fecha Nacimiento <a onclick="show_calendar()" style="cursor: pointer;"> <small>(calendario)</small>

Página 174

Docente: Ing. Núñez Marinovich Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación </a><br /> <input readonly="readonly" class="text" type="text" name="fecha_nacimiento" id="fecha_nacimiento" value="<?php echo date("Y-m-j")?>" /> <div id="calendario" style="display:none;"><?php calendar_html() ?></div> </label> </p> <p> <input type="submit" name="submit" id="button" value="Grabar" /> <label></label> <!-<input type="button" class="cancelar" name="cancelar" id="cancelar" value="Cancelar" onclick="Cancelar()" /> --> </p> </form> <?php } ?>

Actualizar.php <?php require('functions.php'); if(isset($_POST['submit'])){ require('clases/cliente.class.php'); $objCliente=new Cliente; $cliente_id = htmlspecialchars(trim($_POST['cliente_id'])); $nombres = htmlspecialchars(trim($_POST['nombres'])); $ciudad = htmlspecialchars(trim($_POST['ciudad'])); $sexo = htmlspecialchars(trim($_POST['alternativas'])); $telefono = htmlspecialchars(trim($_POST['telefono'])); $fecha_nacimiento = htmlspecialchars(trim($_POST['fecha_nacimiento'])); if ( $objCliente>actualizar(array($nombres,$ciudad,$sexo,$telefono,$fecha_nacimiento),$cliente_id) == true){ echo 'Datos guardados'; }else{ echo 'Se produjo un error. Intente nuevamente'; } }else{ if(isset($_GET['id'])){ require('clases/cliente.class.php'); $objCliente=new Cliente; $consulta = $objCliente->mostrar_cliente($_GET['id']); $cliente = mysql_fetch_array($consulta); ?> <form id="frmClienteActualizar" name="frmClienteActualizar" method="post" action="actualizar.php" onsubmit="ActualizarDatos(); return false"> <input type="hidden" name="cliente_id" id="cliente_id" value="<?php echo $cliente['id']?>" /> <p> <label>Nombres<br /> <input class="text" type="text" name="nombres" id="nombres" value="<?php echo $cliente['nombres']?>" /> </label> </p> <p> <label>Ciudad<br /> <input class="text" type="text" name="ciudad" id="ciudad" value="<?php echo $cliente['ciudad']?>" /> </label> </p> <p> <label> <input type="radio" name="alternativas" id="masculino" value="M" <?php

Página 175

Docente: Ing. Núñez Marinovich Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación if($cliente['sexo']=="M") echo "checked=\"checked\""?> /> Masculino</label> <label> <input type="radio" name="alternativas" id="femenino" value="F" <?php if($cliente['sexo']=="F") echo "checked=\"checked\""?> /> Femenino</label> </p> <p> <label>Telefono<br /> <input class="text" type="text" name="telefono" id="telefono" value="<?php echo $cliente['telefono']?>" /> </label> </p> <p> <label>Fecha Nacimiento <a onclick="show_calendar()" style="cursor: pointer;"><small>(calendario)</small></a><br /> <input readonly="readonly" class="text" type="text" name="fecha_nacimiento" id="fecha_nacimiento" value="<?php echo $cliente['fecha_nacimiento'] ?>" /> <div id="calendario" style="display:none;"><?php calendar_html() ?></div> </label> </p> <p> <input type="submit" name="submit" id="button" value="Grabar" /> <label></label> <!-<input type="button" name="cancelar" id="cancelar" value="Cancelar" onclick="Cancelar()" /> --> </p> </form> <?php } } ?>

Eliminar.php <?php require('clases/cliente.class.php'); $cliente_id=$_GET['id']; $objCliente=new Cliente; if( $objCliente->eliminar($cliente_id) == true){ echo "Registro eliminado correctamente"; }else{ echo "Ocurrio un error"; } ?>

Functions.php <?php function ultimoDia($mes,$ano){ $ultimo_dia=28; while (checkdate($mes,$ultimo_dia + 1,$ano)){ $ultimo_dia++; } return $ultimo_dia; } function calendar_html(){ $meses= array('Enero','Febrero','Marzo','Abril','Mayo','Junio','Julio','Agosto','Septiembre','Octubre','Novi embre','Diciembre'); //$fecha_fin=date('d-m-Y',time());

Página 176

Docente: Ing. Núñez Marinovich Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación $mes=date('m',time()); $anio=date('Y',time()); ?> <table style="width:200px;text-align:center;border:1px solid #808080;border-bottom:0px;" cellpadding="0" cellspacing="0"> <tr> <td colspan="4"> <select id="calendar_mes" onchange="update_calendar()"> <?php $mes_numero=1; while($mes_numero<=12){ if($mes_numero==$mes){ echo "<option value=".$mes_numero." selected=\"selected\">".$meses[$mes_numero-1]."</option> \n"; }else{ echo "<option value=".$mes_numero.">".$meses[$mes_numero-1]."</option> \n"; } $mes_numero++; } ?> </select> </td> <td colspan="3"> <select style="width:70px;" id="calendar_anio" onchange="update_calendar()"> <?php // años a mostrar $anio_min=$anio-30; //hace 30 años $anio_max=$anio; //año actual while($anio_min<=$anio_max){ echo "<option value=".$anio_min.">".$anio_min."</option> \n"; $anio_min++; } ?> </select> </td> </tr> </table> <div id="calendario_dias"> <?php calendar($mes,$anio) ?> </div> <?php } function calendar($mes,$anio){ $dia=1; if(strlen($mes)==1) $mes='0'.$mes; ?> <table style="width:200px;text-align:center;border:1px solid #808080;border-top:0px;" cellpadding="0" cellspacing="0"> <tr style="background-color:#CCCCCC;"> <td>D</td> <td>L</td> <td>M</td> <td>M</td> <td>J</td> <td>V</td> <td>S</td> </tr> <?php //echo $mes.$dia.$anio; $numero_primer_dia = date('w', mktime(0,0,0,$mes,$dia,$anio)); $ultimo_dia=ultimoDia($mes,$anio); $total_dias=$numero_primer_dia+$ultimo_dia; $diames=1; //$j dias totales (dias que empieza a contarse el 1º + los dias del mes)

Página 177

Docente: Ing. Núñez Marinovich Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación $j=1; while($j<$total_dias){ echo "<tr> \n"; //$i contador dias por semana $i=0; while($i<7){ if($j<=$numero_primer_dia){ echo " <td></td> \n"; }elseif($diames>$ultimo_dia){ echo " <td></td> \n"; }else{ if($diames<10) $diames_con_cero='0'.$diames; else $diames_con_cero=$diames; //echo " <td><a style=\"display:block;cursor:pointer;\" onclick=\"set_date('".$diames_con_cero."-".$mes."-".$anio."')\">".$diames."</a></td> \n"; echo " <td><a style=\"display:block;cursor:pointer;\" onclick=\"set_date('".$anio."-".$mes."-".$diames_con_cero."')\">".$diames."</a></td> \n"; $diames++; } $i++; $j++; } echo "</tr> \n"; } ?> </table> <?php } ?>

Calendario.php <?php require('functions.php'); $mes=$_GET['month']; $anio=$_GET['year']; $dia=1; //primer dia del mes calendar($mes,$anio); ?>

jquery.functions.js function ActualizarDatos(){ var cliente_id = $('#cliente_id').attr('value'); var nombres = $('#nombres').attr('value'); var ciudad = $('#ciudad').attr('value'); var alternativas = $("input[@name='alternativas']:checked").attr("value"); var telefono = $("#telefono").attr("value"); var fecha_nacimiento = $("#fecha_nacimiento").attr("value"); $.ajax({ url: 'actualizar.php', type: "POST", data: "submit=&nombres="+nombres+"&ciudad="+ciudad+"&alternativas="+alternativas+"&telefono="+telefono+"&f echa_nacimiento="+fecha_nacimiento+"&cliente_id="+cliente_id, success: function(datos){ alert(datos); ConsultaDatos(); $("#formulario").hide(); $("#formulario").dialog("close"); $("#tabla").show(); } }); return false; }

Página 178

Docente: Ing. Núñez Marinovich Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación function ConsultaDatos(){ $.ajax({ url: 'consulta.php', cache: false, type: "GET", success: function(datos){ $("#tabla").html(datos); } }); } function EliminarDato(cliente_id){ var msg = confirm("Desea eliminar este dato?") if ( msg ) { $.ajax({ url: 'eliminar.php', type: "GET", data: "id="+cliente_id, success: function(datos){ alert(datos); $("#fila-"+cliente_id).remove(); } }); } return false; } function GrabarDatos(){ var nombres = $('#nombres').attr('value'); var ciudad = $('#ciudad').attr('value'); var alternativas = $("input[@name='alternativas']:checked").attr("value"); var telefono = $("#telefono").attr("value"); var fecha_nacimiento = $("#fecha_nacimiento").attr("value"); $.ajax({ url: 'nuevo.php', type: "POST", data: "submit=&nombres="+nombres+"&ciudad="+ciudad+"&alternativas="+alternativas+"&telefono="+telefono+"&f echa_nacimiento="+fecha_nacimiento, success: function(datos){ ConsultaDatos(); alert(datos); $("#formulario").hide(); $("#formulario").dialog("close"); $("#tabla").show(); } }); return false; } function Cancelar(){ $("#formulario").hide(); $("#tabla").show(); return false; } // funciones del calendario function update_calendar(){ var month = $('#calendar_mes').attr('value'); var year = $('#calendar_anio').attr('value'); var valores='month='+month+'&year='+year; $.ajax({ url: 'calendario.php', type: "GET",

Página 179

Docente: Ing. Núñez Marinovich Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación data: valores, success: function(datos){ $("#calendario_dias").html(datos); } }); } function set_date(date){ $('#fecha_nacimiento').attr('value',date); show_calendar(); } function show_calendar(){ $('#calendario').toggle(); }

Estilos.css @charset "utf-8"; *{ font-family:Verdana, Arial, Helvetica, sans-serif; font-size:11px; padding:0; margin:0; text-transform:uppercase; } a{ text-decoration:none; } img{ border:none; } #contenedor{ width:800px; margin:auto; margin-top:20px; border:2px solid #C0C0C0; background-color:#F2F2F2; padding-bottom:20px; } small{ font-size:9px; }

form p{ margin:auto; width:450px; margin-top:5px; margin-bottom:3px; } form input{ border:1px solid #CCCCCC; padding:3px; } form .text{ width:400px; }

table{ width:700px; margin:auto; } td{ border-bottom:1px solid #D3D3D3; padding:5px 0px 5px; } th{ background-color:#CDCDCD; padding:5px 0px 5px; } form{ border:2px solid #C0C0C0; background-color:#F2F2F2; width:500px; margin:auto; margin-bottom:20px; }

Página 180

Docente: Ing. Núñez Marinovich Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Interfaces de usuario:


Aromas de Bases de Datos y otras fragancias de Programación

Conexión PHP a SQL Server Editar el archivo php.ini con el Notepad. Buscar la línea ";extension=php_mssql.dll" y modifícala quitándole el ";" del principio. Graba el fichero PHP.ini y reiniciar el servidor (Apache). Base de datos: Northwind Ejemplo 1: Listar el nombre de los productos y su precio de la tabla “products” <?php $conectID = mssql_connect("192.168.40.2","sa","1"); mssql_select_db("Northwind"); $result=mssql_query("select * from products order by productName"); echo "<table border=1><tr bgcolor='#0099FF'><td>Nro</td><td>Producto</td><td>Precio</td></tr>"; while ($row=mssql_fetch_array($result)) { $contador++; $nombreProducto=$row["ProductName"]; $precio=$row["UnitPrice"]; echo ("<tr bgcolor='#CCFF99'><td>$ contador </td> <td>$nombreProducto</td> <td align='right'> $precio</td></tr>"); } echo "</table>"; mssql_close($conectID); ?>

Ejemplo 2: Realizar Insert en una tabla. Puede usarse también con las intrucciones Update, Delete <?php $conectID = mssql_connect("(local)","sa","1"); mssql_select_db("Northwind"); $sentencia="insert into Categories(CategoryName, Description) values ('Computo','Equipos electronicos')"; //$sentencia="update Categories set Description='Equipos para PC' where CategoryID=@@identity"; //$sentencia="delete Categories where CategoryID=@@identity"; $result=mssql_query($sentencia); echo "$result fila(s) afectada(s)."; mssql_close($conectID); ?>

Ejemplo 3: Devolver un escalar: Mostrar el total de ciudades e los empelados. Uso tabla employees <?php $conectID = mssql_connect("(local)","sa","1"); mssql_select_db("Northwind"); $sentencia="SELECT count(distinct city)from employees"; $result=mssql_query($sentencia); $fila=mssql_fetch_array($result); echo "Total de ciudades de los empleados: $fila[0]"; mssql_close($conectID); ?>

Ejemplo 4: Mostrar el número de registros de una determinada consulta. <?php $conectID = mssql_connect("(local)","sa","1"); mssql_select_db("Northwind"); $sentencia="select * from Products where UnitPrice >20"; $result=mssql_query($sentencia); $totalRegistros=mssql_num_rows($result); echo "Total de registros de la consulta: $totalRegistros"; mssql_close($conectID); ?>

Página 182

Docente: Ing. Núñez Marinovich Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación

Conexión PHP a Oracle Editar el archivo php.ini con el Notepad. Buscar la línea "; extension=php_oci8.dll" y modifícala quitándole el ";" del principio. Modificar también el date.timezone, colocar: date.timezone = America/Lima Graba el fichero PHP.ini y reiniciar el servidor (Apache). Los ejemplos se trabajarán con la base de datos usada en el capitulo que se desarrollo Oracle. Ejemplo 1: Listar el nombre de los productos y su precio de la tabla “producto” <?php $user='MarketPERU'; $password='mercado'; //host puede ser este: $host='(DESCRIPTION =(ADDRESS_LIST=(ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.40.205)(PORT = 1521)))(CONNECT_DATA =(SERVER = DEDICATED) (SERVICE_NAME = dbodpe)))'; //o tambien este de acuerdo al tnsnames $host='DBODPEflor'; $conexion = ocilogon($user,$password,$host); // conexión a la base de datos $query = 'select nombre, precioUnitario from producto'; $sentencia = ociparse($conexion, $query ); // se crea una sentencia ociexecute($sentencia); // se ejecuta la sentencia echo "<table border=1><tr bgcolor='#0099FF'><td>Nro</td><td>Producto</td><td>Precio</td></tr>"; while (ocifetchinto($sentencia,&$fila)) { // devuelve la siguiente tupla en el array fila //print_r($fila);//despliega información sobre la variable $counter++; $nombreProducto=$fila[0]; $precio=$fila[1]; echo ("<tr bgcolor='#CCFF99'><td>$counter</td> <td>$nombreProducto</td> <td align='right'>$precio</td></tr>"); } echo "</table>"; ocifreestatement($sentencia); // se libera el resultado de la sentencia ocilogoff($conexion); // desconexión de la base de datos ?>

Ejemplo 2: Realizar Insert en una tabla. Puede usarse también con las intrucciones Update, Delete <?php $user='MarketPERU'; $password='mercado'; //host puede ser este: $host='(DESCRIPTION =(ADDRESS_LIST=(ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.40.205)(PORT = 1521)))(CONNECT_DATA =(SERVER = DEDICATED) (SERVICE_NAME = dbodpe)))'; //o tambien este de acuerdo al tnsnames //$host='DBODPEflor'; $conexion = ocilogon($user,$password,$host); // conexión a la base de datos $query = "insert into Categoria values (7,'Computo','Equipos electronicos')"; //$query = "update Categoria set categoria='Equipos para PC' where IDCATEGORIA=7"; //$query = "delete Categoria where IDCATEGORIA=7"; $sentencia = ociparse($conexion, $query ); // se crea una sentencia ociexecute($sentencia); // se ejecuta la sentencia ocicommit($conexion); //ocirollback($conexion); echo "Sentencia realizada con exito"; ocifreestatement($sentencia); // se libera el resultado de la sentencia ocilogoff($conexion); // desconexión de la base de datos ?>

Página 183

Docente: Ing. Núñez Marinovich Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación Ejemplo 3: Devolver un escalar. <?php $user='MarketPERU'; $password='mercado'; //host puede ser este: $host='(DESCRIPTION =(ADDRESS_LIST=(ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.40.205)(PORT = 1521)))(CONNECT_DATA =(SERVER = DEDICATED) (SERVICE_NAME = dbodpe)))'; //o tambien este de acuerdo al tnsnames //$host='DBODPEflor'; $conexion = ocilogon($user,$password,$host); // conexión a la base de datos $query = 'select count(*) from producto'; $sentencia = ociparse($conexion, $query ); // se crea una sentencia ociexecute($sentencia); // se ejecuta la sentencia ocifetchinto($sentencia,&$fila); // devuelve la siguiente tupla en el array fila echo ("Total de productos: $fila[0]");// mostramos el total de productos ocifreestatement($sentencia); // se libera el resultado de lasentencia ocilogoff($conexion); // desconexión de la base de datos ?>

Página 184

Docente: Ing. Núñez Marinovich Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación

Conexión PHP a PostgreSQL Editar el archivo php.ini con el Notepad. Buscar la línea ";extension=php_pgsql.dll" y modifícala quitándole el ";" del principio. Graba el fichero PHP.ini y reiniciar el servidor (Apache). Los ejemplos se trabajarán con la base de datos usada en el capitulo que se desarrollo PostgreSQL. Ejemplo 1: Listar los títulos de los libros con sus autores. <?php $conn = pg_connect("host=localhost port=5432 password=1 user=postgres dbname=bdlibros"); if (!$conn) { echo "Error en la conexion.\n"; exit; } echo "Conexion OK"; $query="select titulo, autor from libro order by 1"; $result=pg_query($query); echo "<table border=1><tr bgcolor='#0099FF'><td>Nro</td><td>Titulo</td><td>Autor</td></tr>"; while ($row=pg_fetch_array($result)) { $contador++; $titulo=$row["titulo"]; $autor=$row[1]; echo ("<tr bgcolor='#CCFF99'><td>$contador </td> <td>$titulo</td> <td align='right'>$autor</td></tr>"); } echo "</table>"; pg_close($conn); ?>

Ejemplo 2: Realizar Insert en una tabla. Puede usarse también con las intrucciones Update, Delete <?php $conn = pg_connect("host=localhost port=5432 password=1 user=postgres dbname=bdlibros"); $sentencia="insert into Editorial(nombreEditorial) values('Coquito');"; //$sentencia="update Editorial set nombreEditorial='Juanito' where idEditorial=2"; //$sentencia="delete from Editorial where idEditorial=2"; $result=pg_query($sentencia); echo "$result fila(s) afectada(s)."; pg_close($conn); ?>

Ejemplo 3: Devolver un escalar: Mostrar el total de autores <?php $conn = pg_connect("host=localhost port=5432 password=1 user=postgres dbname=bdlibros"); $sentencia="SELECT count(distinct autor)from libro"; $result=pg_query($sentencia); $fila=pg_fetch_array($result); echo "Total de autores: $fila[0]"; pg_close($conn); ?>

Ejemplo 4: Mostrar el número de registros de una determinada consulta. <?php $conn = pg_connect("host=localhost port=5432 password=1 user=postgres dbname=bdlibros"); $sentencia="SELECT * from libro where precio>40"; $result=pg_query($sentencia); $totalRegistros=pg_num_rows($result); echo "Total de registros de la consulta: $totalRegistros"; pg_close($conn); ?>

Página 185

Docente: Ing. Núñez Marinovich Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación

Contenido: ♦ Script Base de Datos Computienda en SQL Server ♦ Script Base de Datos Computienda en MySQL ♦ Mantenimiento con Visual Basic .NET con SQL Server • • • • • • •

Función que devuelve la cadena de conexión Procedimiento que muestra el resultado de una consulta de un Stored Procedure con parámetro de entrada. Procedimiento que ejecuta un Stored Procedure de Registrar un Pedido, el cual se realiza con transacciones, parámetros de entrada y salida. Procedimiento muestra el resultado de una función Escalar Procedimiento muestra el resultado de una procedimiento almacenado con instrucción RETURN Procedimiento muestra el resultado de una Función en Linea Procedimiento muestra el resultado de una Función Multisentencia

♦ Mantenimiento con Java con MySQL ♦ Mantenimiento con PHP con MySQL Base de Datos Tablas: Cliente: idCliente, nombre, dirección, teléfono, email. Producto: idProducto, nombreProducto, stock, precioVenta, rutaImagen, descripción. Pedido: idPedido, idCliente, fecha, monto, despachado. DetallePedido: idPedido, idProducto, cantidad, precio. Usuario: idUsuario, nombreUsuario, password. Procedimientos Almacenados:ups_registrarPedido, usp_mostrarPedidos, usp_reporteTotales, ups_devolverMonto Funciones: dbo.fn_devolverMes, dbo.fn_DevolverDetallePedido, dbo.fn_CategoriaClientes

Página 186

Docente: Ing. Núñez Marinovich Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación Diagrama de la Base de Datos CompuTienda

Página 187

Docente: Ing. Núñez Marinovich Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación

BASE DE DE DATOS COMPUTIENDA EN SQL SERVER Creamos la Base de Datos --Creamos la BD bdcomputienda CREATE DATABASE bdcomputienda GO USE bdcomputienda

Creamos las Tablas --Creamos las tablas CREATE TABLE cliente( idCliente int not null identity primary key, nombre VARCHAR(80)NOT NULL, direccion VARCHAR(50) DEFAULT NULL, telefono VARCHAR(20) DEFAULT NULL, email VARCHAR(50)DEFAULT NULL, ); CREATE TABLE producto( idProducto int not null identity primary key, nombreProducto VARCHAR(100)NOT NULL, stock int DEFAULT NULL, precioVenta DECIMAL(10,2)DEFAULT NULL, rutaImagen VARCHAR(150)DEFAULT NULL, descripcion VARCHAR(200)DEFAULT NULL, ); CREATE TABLE pedido( idPedido int not null identity primary key, idCliente INT FOREIGN KEY REFERENCES cliente(idCliente), fecha DATE DEFAULT NULL, monto DECIMAL(10,0)DEFAULT NULL, despachado BIT DEFAULT NULL, ); CREATE TABLE detallepedido( idPedido INT FOREIGN KEY REFERENCES Pedido(idPedido), idProducto INT FOREIGN KEY REFERENCES Producto(idProducto), cantidad INT DEFAULT NULL, precio DECIMAL(10,2)DEFAULT NULL, ); CREATE TABLE usuario( idUsuario int not null identity primary key, nombreUsuario VARCHAR(50)DEFAULT NULL, password VARCHAR(50)DEFAULT NULL, ); --Eliminamos y reiniciamos el id a 0 en caso se haya trabajado anteriormente con las tablas DELETE FROM detallepedido; DELETE FROM pedido DBCC CHECKIDENT('pedido', RESEED,0); DELETE FROM cliente DBCC CHECKIDENT('cliente', RESEED,0); DELETE FROM producto DBCC CHECKIDENT('producto', RESEED,0); DELETE FROM usuario DBCC CHECKIDENT('usuario', RESEED,0);

Página 188

Docente: Ing. Núñez Marinovich Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación Realizamos la inserción de datos. --Realizamos los Inserts INSERT INTO cliente( nombre, direccion, telefono, email)VALUES('Carlos Romero','Las Flores','291006','romero@latinmail.com') ; INSERT INTO cliente( nombre, direccion, telefono, email)VALUES('Condorito','Los Paujiles 773','256301','condorito@yahoo.com'); INSERT INTO cliente( nombre, direccion, telefono, email)VALUES('Mendoza Castañeda','Av Los Incas 778','210123','conchudo@gmail.com'); INSERT INTO cliente( nombre, direccion, telefono, email)VALUES('Asto Pajares','Mochica 210','285269','pajares@hotmail.com'); INSERT INTO cliente( nombre, direccion, telefono, email)VALUES('TROLONCHE','Las torres 234','2334455','tr@hotmail.com'); INSERT INTO cliente( nombre, direccion, telefono, email)VALUES('Miguel Camacho','Las Palmeras 256','3256211','camayus@hotmail.com'); INSERT INTO cliente( nombre, direccion, telefono, email)VALUES('Pepe Botellas','Los pinos 234','259888','pepebotellas@hotmail.com' ); INSERT INTO cliente( nombre, direccion, telefono, email)VALUES('Rosita Copas','ONPE','2896544','rositacopa@yaho o.es'); INSERT INTO cliente( nombre, direccion, telefono, email)VALUES('Pamela Chu','Av. Las Pildoras 250','2541360','pamelachu@gmail.com'); INSERT INTO cliente( nombre, direccion, telefono, email)VALUES('Napoleon Bonaparte','Av. France 256','2411001','don_napo@hotmail.com'); INSERT INTO cliente( nombre, direccion, telefono, email)VALUES('Pastruli','Av. Washington 1879','2563114','pastruli@yahoo.com'); INSERT INTO cliente( nombre, direccion, telefono, email)VALUES('Magdalena Chu','ONPE','5456516','magda@onpe.gob.pe '); INSERT INTO cliente( nombre, direccion, telefono, email)VALUES('Adolfo Hitler','Av. Los geranios 243','5411162','adolf@yahoo.gr'); INSERT INTO cliente( nombre, direccion, telefono, email)VALUES('Paulin Paletazo','ONPE','255555','paleta@hotmai l.com'); --SELECT * from cliente

INSERT INTO producto VALUES('Disco Duro 160 G', 90,'220.00','Galeria Equipos/disco duro.jpg','Hard Disk.'); INSERT INTO producto VALUES('Teclado Multimedia', 50,'30.00','Galeria Equipos/teclado.jpg','Teclado Universal.'); INSERT INTO producto VALUES('Mouse Optico', 100,'15.00','Galeria Equipos/mouse_cyberlink.jpg','Logitech.' ); INSERT INTO producto VALUES('Grabadora CD/DVD', 50,'90.00','Galeria Equipos/grabadora.jpg','LG'); INSERT INTO producto VALUES('Fuentes ATX', 25,'50.00','Galeria Equipos/fuentes atx.bmp',''); INSERT INTO producto VALUES('Estabilizador Hibrido', 35,'70.00','Galeria Equipos/estabilizador hibrido.bmp',''); INSERT INTO producto VALUES('Case CPU Atlon', 80,'70.00','Galeria Equipos/CASE CPU ATLON.jpg',''); INSERT INTO producto VALUES('Web CAM', 15,'50.00','Galeria Equipos/web cam.bmp',''); INSERT INTO producto VALUES('Monitor LCD', 35,'300.00','Galeria Equipos/monitor.jpg',''); INSERT INTO producto VALUES('Router', 23,'120.00','Galeria Equipos/router.bmp',''); INSERT INTO producto VALUES('Disqueteras', 2,'10.00','Galeria Equipos/disqueteras.bmp',''); INSERT INTO producto VALUES('Laptop HP Pavilium 3770', 20,'3200.00','Galeria Equipos/laptop hp pavilium.bmp',''); INSERT INTO producto VALUES('Memorias US', 25,'80.00','Galeria Equipos/memoria usb.bmp','Memorias USB Kingston'); INSERT INTO producto VALUES('Impresora', 200,'100.00','Galeria Equipos/impresora.jpg','Impresora Laser'); INSERT INTO producto VALUES('Scanner', 600,'75.00','Galeria Equipos/scanner.bmp',''); INSERT INTO producto VALUES('Joystick', 25,'35.00','Galeria Equipos/joystick.jpg',NULL); INSERT INTO producto VALUES('Plotter', 70,'1200.00','Galeria Equipos/plotter.jpg',NULL); INSERT INTO producto VALUES('Lectora de codigo de barras', 6,'80.00','Galeria Equipos/lectora de codigo de barras.jpg','Lectora de codigo de barras'); --SELECT * from producto

INSERT INTO producto VALUES('Memoria RAM DDR2 1 G', 300,'150.00','Galeria INSERT INTO pedido VALUES( 1,'2008-06Equipos/memoria_ram_notebook_sodimm.jpg' 04','1270','1'); ,'Memoria DDR2.'); Docente: Ing. Núñez Marinovich Manuel URL: http://manhiuco.es.tl Página 189 Ingeniero Informático Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación INSERT INTO pedido VALUES( 04','610','1'); INSERT INTO pedido VALUES( 22','210','1'); INSERT INTO pedido VALUES( 15','1820','1'); INSERT INTO pedido VALUES( 07','1510','1'); INSERT INTO pedido VALUES( 12','2940','1'); INSERT INTO pedido VALUES( 02','9375','1'); INSERT INTO pedido VALUES( 15','2235','1'); INSERT INTO pedido VALUES( 25','3395','1'); INSERT INTO pedido VALUES( 04','11295','1'); INSERT INTO pedido VALUES( 17','500','1'); INSERT INTO pedido VALUES( 22','800','1'); INSERT INTO pedido VALUES( 25','1810','1'); INSERT INTO pedido VALUES( 26','850','1'); INSERT INTO pedido VALUES( 28','2160','1'); --SELECT * from pedido

2,'2008-07-

INSERT INTO detallepedido(idPedido, idProducto, cantidad, precio)VALUES(5, 6,'2009-029, 5,'70.00'); INSERT INTO detallepedido(idPedido, 7,'2009-03idProducto, cantidad, precio)VALUES(5, 2, 5,'220.00'); 8,'2010-01INSERT INTO detallepedido(idPedido, idProducto, cantidad, precio)VALUES(5, 5,'2010-0213, 6,'10.00'); INSERT INTO detallepedido(idPedido, 9,'2010-05idProducto, cantidad, precio)VALUES(6, 9, 10,'70.00'); 10,'2010-05INSERT INTO detallepedido(idPedido, idProducto, cantidad, precio)VALUES(6, 11,'2010-052, 5,'220.00'); INSERT INTO detallepedido(idPedido, 2,'2010-06idProducto, cantidad, precio)VALUES(6, 13, 6,'10.00'); 2,'2010-06INSERT INTO detallepedido(idPedido, idProducto, cantidad, precio)VALUES(6, 10,'2010-068, 5,'70.00'); INSERT INTO detallepedido(idPedido, 12,'2011-03idProducto, cantidad, precio)VALUES(6, 10, 5,'50.00'); 13,'2011-03INSERT INTO detallepedido(idPedido, idProducto, cantidad, precio)VALUES(6, 12, 4,'120.00'); 14,'2011-03INSERT INTO detallepedido(idPedido, idProducto, cantidad, precio)VALUES(6, 17, 5,'75.00'); INSERT INTO detallepedido(idPedido, INSERT INTO detallepedido(idPedido, idProducto, cantidad, precio)VALUES(1, idProducto, cantidad, precio)VALUES(7, 1, 150,'2.00'); 19, 7,'1200.00'); INSERT INTO detallepedido(idPedido, INSERT INTO detallepedido(idPedido, idProducto, cantidad, precio)VALUES(1, idProducto, cantidad, precio)VALUES(7, 2, 220,'4.00'); 4, 22,'15.00'); INSERT INTO detallepedido(idPedido, INSERT INTO detallepedido(idPedido, idProducto, cantidad, precio)VALUES(1, idProducto, cantidad, precio)VALUES(7, 3, 15,'6.00'); 5, 3,'90.00'); INSERT INTO detallepedido(idPedido, INSERT INTO detallepedido(idPedido, idProducto, cantidad, precio)VALUES(2, idProducto, cantidad, precio)VALUES(8, 4, 70,'3.00'); 18, 7,'35.00'); INSERT INTO detallepedido(idPedido, INSERT INTO detallepedido(idPedido, idProducto, cantidad, precio)VALUES(2, idProducto, cantidad, precio)VALUES(8, 5, 80,'5.00'); 16, 13,'100.00'); INSERT INTO detallepedido(idPedido, INSERT INTO detallepedido(idPedido, idProducto, cantidad, precio)VALUES(3, idProducto, cantidad, precio)VALUES(8, 9, 3,'70.00'); 4, 6,'15.00'); INSERT INTO detallepedido(idPedido, INSERT INTO detallepedido(idPedido, idProducto, cantidad, precio)VALUES(4, idProducto, cantidad, precio)VALUES(8, 9, 4,'70.00'); 17, 8,'75.00'); INSERT INTO detallepedido(idPedido, INSERT INTO detallepedido(idPedido, idProducto, cantidad, precio)VALUES(4, idProducto, cantidad, precio)VALUES(9, 2, 2,'220.00'); 18, 7,'35.00'); INSERT INTO detallepedido(idPedido, INSERT INTO detallepedido(idPedido, idProducto, cantidad, precio)VALUES(4, idProducto, cantidad, precio)VALUES(9, 13, 3,'10.00'); 16, 13,'100.00'); INSERT INTO detallepedido(idPedido, INSERT INTO detallepedido(idPedido, idProducto, cantidad, precio)VALUES(4, idProducto, cantidad, precio)VALUES(9, 8, 4,'70.00'); 4, 6,'15.00'); INSERT INTO detallepedido(idPedido, INSERT INTO detallepedido(idPedido, idProducto, cantidad, precio)VALUES(4, idProducto, cantidad, precio)VALUES(9, 7, 5,'50.00'); 17, 8,'75.00'); INSERT INTO detallepedido(idPedido, INSERT INTO detallepedido(idPedido, idProducto, cantidad, precio)VALUES(4, idProducto, cantidad, precio)VALUES(9, 5, 6,'90.00'); 15, 6,'80.00'); Docente: Ing. Núñez Marinovich Manuel URL: http://manhiuco.es.tl Página 190 Ingeniero Informático Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación INSERT INTO detallepedido(idPedido, idProducto, cantidad, precio)VALUES(9, 2, 3,'220.00'); INSERT INTO detallepedido(idPedido, idProducto, cantidad, precio)VALUES(9, 13, 2,'10.00'); INSERT INTO detallepedido(idPedido, idProducto, cantidad, precio)VALUES(10, 18, 7,'35.00'); INSERT INTO detallepedido(idPedido, idProducto, cantidad, precio)VALUES(10, 16, 13,'100.00'); INSERT INTO detallepedido(idPedido, idProducto, cantidad, precio)VALUES(10, 4, 6,'15.00'); INSERT INTO detallepedido(idPedido, idProducto, cantidad, precio)VALUES(10, 17, 8,'75.00'); INSERT INTO detallepedido(idPedido, idProducto, cantidad, precio)VALUES(10, 15, 6,'80.00'); INSERT INTO detallepedido(idPedido, idProducto, cantidad, precio)VALUES(10, 2, 3,'220.00'); INSERT INTO detallepedido(idPedido, idProducto, cantidad, precio)VALUES(10, 13, 2,'10.00'); INSERT INTO detallepedido(idPedido, idProducto, cantidad, precio)VALUES(10, 14, 2,'3200.00'); INSERT INTO detallepedido(idPedido, idProducto, cantidad, precio)VALUES(10, 11, 5,'300.00'); INSERT INTO detallepedido(idPedido, idProducto, cantidad, precio)VALUES(11, 15, 5,'80.00'); INSERT INTO detallepedido(idPedido, idProducto, cantidad, precio)VALUES(11, 7, 2,'50.00'); INSERT INTO detallepedido(idPedido, idProducto, cantidad, precio)VALUES(12, 15, 5,'80.00');

Página 191

INSERT INTO detallepedido(idPedido, idProducto, cantidad, precio)VALUES(12, 7, 2,'50.00'); INSERT INTO detallepedido(idPedido, idProducto, cantidad, precio)VALUES(12, 17, 2,'75.00'); INSERT INTO detallepedido(idPedido, idProducto, cantidad, precio)VALUES(12, 1, 1,'150.00'); INSERT INTO detallepedido(idPedido, idProducto, cantidad, precio)VALUES(13, 9, 7,'70.00'); INSERT INTO detallepedido(idPedido, idProducto, cantidad, precio)VALUES(13, 2, 6,'220.00'); INSERT INTO detallepedido(idPedido, idProducto, cantidad, precio)VALUES(13, 9, 2,'70.00'); INSERT INTO detallepedido(idPedido, idProducto, cantidad, precio)VALUES(14, 8, 3,'70.00'); INSERT INTO detallepedido(idPedido, idProducto, cantidad, precio)VALUES(14, 16, 5,'100.00'); INSERT INTO detallepedido(idPedido, idProducto, cantidad, precio)VALUES(14, 9, 5,'70.00'); INSERT INTO detallepedido(idPedido, idProducto, cantidad, precio)VALUES(15, 2, 6,'220.00'); INSERT INTO detallepedido(idPedido, idProducto, cantidad, precio)VALUES(15, 13, 4,'10.00'); INSERT INTO detallepedido(idPedido, idProducto, cantidad, precio)VALUES(15, 5, 5,'90.00'); INSERT INTO usuario VALUES('Administrador','1');

Docente: Ing. Núñez Marinovich Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación Procedimiento Almacenado 1. Realizar Transaccion: Registrar Pedido ALTER PROCEDURE ups_registrarPedido( @p_estado as VARCHAR(500)OUTPUT,-- Parámetro de salida @in_nombre as VARCHAR(100), @in_direccion as VARCHAR(100), @in_telefono as VARCHAR(50),@in_email as VARCHAR(100), @in_monto as DECIMAL(12,2), @listaCantidad as VARCHAR(1000),@listaProducto as VARCHAR(1000),@listaPrecio as VARCHAR(1000)) AS declare @idCliente int declare @idPedido int declare @idProducto int declare @var_producto varchar(200) declare @var_cantidad varchar(200) declare @var_precio varchar(200) declare @indiceB int--Indice de busqueda declare

@ErrMsg varchar(1000),@ErrSeverity int

begintry BEGIN TRAN saction--Iniciamos la Transaccion /*1. Insertamos el Cliente*/ -1.1 Insertamos Cliente si existe If not exists(SELECT idCliente from dbo.cliente where nombre=@in_nombre) INSERT INTO Cliente(nombre,direccion,telefono,email) VALUES(@in_nombre,@in_direccion,@in_telefono,@in_email); -- 1.2 Devolvemos en el idCliente SELECT @idCliente=idCliente from cliente where nombre=@in_nombre /*2. Insertamos en la tabla Pedido*/ INSERT INTO Pedido(idCliente,fecha,monto,despachado) VALUES(@idCliente,GETDATE(),@in_monto,0); /*2.1 extraemos idPedido*/ SELECT @idPedido = idPedido FROM Pedido WHERE idCliente=@idCliente AND convert(date,fecha,103)=convert(date,GETDATE(),103) AND monto=@in_monto AND despachado=0; /*3. Insertamos en DetallePedido*/ set @indiceB=1; WHILE (@indiceB!=0) begin /* 3.1 extraemos el producto */ SET @indiceB =CHARINDEX('|',@listaProducto,1); if @indiceB>0 begin SET @var_producto=SUBSTRING(@listaProducto,1,@indiceB -1); SET @listaProducto=SUBSTRING(@listaProducto, @indiceB + 1,LEN(@listaProducto)-@indiceB); end else begin--es el ultimo elemento SET @var_producto=@listaProducto; end print @indiceB; Docente: Ing. Núñez Marinovich Manuel Página 192 Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación print'Producto:'+ @var_producto; print'Lista: '+ @listaProducto; -------------------------------------------------------------------------------------/* 3.2 extraemos la cantidad */ SET @indiceB =CHARINDEX('|',@listaCantidad,1); if @indiceB>0 begin SET @var_cantidad=SUBSTRING(@listaCantidad,1,@indiceB -1); SET @listaCantidad=SUBSTRING(@listaCantidad, @indiceB + 1,LEN(@listaCantidad)-@indiceB); end else begin--es el ultimo elemento SET @var_cantidad=@listaCantidad; end print'Cantidad:'+ @var_Cantidad; print'Lista: '+ @listaCantidad; --------------------------------------------------------------------------------------/* 3.3 extraemos el precio */ SET @indiceB =CHARINDEX('|',@listaPrecio,1); if @indiceB>0 begin SET @var_precio=SUBSTRING(@listaPrecio,1,@indiceB -1); SET @listaPrecio=SUBSTRING(@listaPrecio, @indiceB + 1,LEN(@listaPrecio)-@indiceB); end else begin--es el ultimo elemento SET @var_precio=@listaPrecio; end print'Precio:'+ @var_Precio; print'Lista: '+ @listaPrecio; /*3.4 extraemos idProducto*/ SELECT @idProducto=idProducto FROM Producto WHERE nombreProducto=@var_producto; INSERT INTO DetallePedido(idPedido,idProducto,cantidad,precio) VALUES(@idPedido,@idProducto,@var_cantidad,@var_precio); END--fin del while commit transaction--aceptamos la transaccion set @p_estado='OK' PRINT @p_estado End Try begin catch rollback transaction SELECT @ErrMsg =ERROR_MESSAGE(), @ErrSeverity =ERROR_SEVERITY(); PRINT'Error: '+ERROR_MESSAGE() raiserror(@ErrMsg,@ErrSeverity,1) endcatch --Ejemplo de uso: declare @estado varchar(500) exec ups_registrarPedido@estado output,'Pepito','Las Golondrinas 328','234433','pp@hotmail.com', 500.00,'1|2|3','Joystick|Impresora|Router','10|20|30' print @estado

Página 193

Docente: Ing. Núñez Marinovich Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación Procedimiento Almacenado 2. Devolver consulta: Reporte de Pedidos CREATE PROCEDURE ups_mostrarPedidos as SELECT P.idPedido, C.nombre AS Cliente, P.Fecha, P.Monto, CASE P.Despachado WHEN 1 THEN'ENTREGADO'ELSE'PENDIENTE'END AS Despachado FROM Cliente C INNER JOIN Pedido P ON C.idCliente=P.idCliente ORDER BY P.Fecha DESC GO

Procedimiento Almacenado 3. Devolver consulta: Devolver montos totales según parametro por año, trimestre, meses, dias. CREATE PROCEDURE usp_reporteTotales @resumenTiempo VARCHAR(20) as SET @resumenTiempo=UPPER(@resumenTiempo) IF(@resumenTiempo='AÑO') SELECT SUM(P.monto)AS Monto,YEAR(P.Fecha)AS Tiempo FROM Pedido P GROUP BY YEAR(P.Fecha) ORDER BY Tiempo ELSEIF(@resumenTiempo='MES') SELECT SUM(P.monto)AS Monto, cast(YEAR(P.Fecha)as char(4))+' - '+cast(MONTH(P.Fecha) as char(2))AS Tiempo FROM Pedido P GROUP BY cast(YEAR(P.Fecha) as char(4))+' - '+cast(MONTH(P.Fecha)as char(2)) ORDER BY Tiempo ELSEIF(@resumenTiempo='TRIMESTRE') SELECT SUM(P.monto)AS Monto, cast(YEAR(P.Fecha) as char(4))+'-'+cast(datepart(QUARTER,P.Fecha)as CHAR(1))AS Tiempo FROM Pedido P GROUP BY cast(YEAR(P.Fecha) as char(4))+'-'+cast(datepart(QUARTER,P.Fecha) as char(1)) ORDER BY Tiempo ELSEIF(@resumenTiempo='DIA') SELECT SUM(P.monto)AS Monto, fecha FROM Pedido P GROUP BY fecha ORDER BY Tiempo

AS Tiempo

GO

Página 194

Docente: Ing. Núñez Marinovich Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación

Procedimiento Almacenado 4. Devolver Escalar: Devolver monto de pedidos entre 2 fechas CREATE PROCEDURE ups_devolverMonto@fechaI datetime, @fechaF datetime as declare @resultado real SELECT @resultado=sum(monto) from pedido whereconvert(datetime,fecha,103)betweenconvert(datetime,@fechaI,103)andconvert(datetime ,@fechaF,103) --where fecha between @fechai and @fechaf and despachado=1 return (@resultado) --Prueba declare @total float exec @total =ups_devolverMonto'04/04/2011','16/04/2011' print @total

Función 1. Función escalar: Devolver nombre del mes ingresando número del mes. Usado en usp_reporteTotales CREATE FUNCTION fn_devolverMes(@mes int) Returns varchar(20) as begin declare @resultado varchar(20) if @mes=1 set @resultado ='Enero' if @mes=2 set @resultado ='Febrero' if @mes=3 set @resultado ='Marzo' if @mes=4 set @resultado ='Abril' if @mes=5 set @resultado ='Mayo' if @mes=6 set @resultado ='Junio' if @mes=7 set @resultado ='Julio' if @mes=8 set @resultado ='Agosto' if @mes=9 set @resultado ='Setiembre' if @mes=10 set @resultado ='Octubre' if @mes=11 set @resultado ='Noviembre' if @mes=12 set @resultado ='Diciembre' return @resultado end --Prueba SELECT dbo.fn_devolverMes(4)

Función 2. Función Tabla en linea: Devolver Detalle de Pedido CREATE FUNCTION dbo.fn_DevolverDetallePedido(@idPedido int) RETURNS TABLE AS RETURN (SELECT nombreProducto as Producto, Precio, Cantidad, precio*cantidad as Subtotal FROM detallepedido dp inner join producto p on dp.idproducto= p.idproducto WHERE idpedido= @idPedido) --Prueba SELECT *from dbo.fn_DevolverDetallePedido(10)

Página 195

Docente: Ing. Núñez Marinovich Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación

Función 3. Funciones de tabla de multi sentencias CREATE FUNCTION dbo.fn_CategoriaClientes() RETURNS @Result TABLE ( Cliente varchar(20), Recaudacion float, Categoria char(1) ) AS BEGIN INSERT INTO @Result SELECT nombre as Cliente,SUM(monto)as Total, case whensum(monto)>=9000 then'A' whensum(monto)>=1500 andsum(monto)<9000 then'B' whensum(monto)<1500 then'C' endas Categoria from cliente c inner join pedido p on c.idCliente = p.idCliente GROUP BY nombre ORDER BY Total desc RETURN END --Prueba SELECT *from dbo.fn_CategoriaClientes()

BASE DE DE DATOS COMPUTIENDA EN MYSQL /*Creamos la BD*/ DROP DATABASE IF EXISTS bdcomputienda; CREATE DATABASE bdcomputienda; USE bdcomputienda;

/*Creamos las tablas*/ CREATE TABLE cliente ( idCliente INT(10) UNSIGNED NOT NULL AUTO_INCREMENT, nombre VARCHAR(80) NOT NULL, direccion VARCHAR(50) DEFAULT NULL, telefono VARCHAR(20) DEFAULT NULL, email VARCHAR(50) DEFAULT NULL, PRIMARY KEY (idCliente) ) ENGINE=INNODB ; CREATE TABLE producto ( idProducto INT(10) UNSIGNED NOT NULL AUTO_INCREMENT, nombreProducto VARCHAR(100) NOT NULL, stock INT(10) UNSIGNED DEFAULT NULL, precioVenta DECIMAL(10,2) DEFAULT NULL, rutaImagen VARCHAR(150) DEFAULT NULL, descripcion VARCHAR(200) DEFAULT NULL, PRIMARY KEY (idProducto) ) ENGINE=INNODB ;

Página 196

Docente: Ing. Núñez Marinovich Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación CREATE TABLE pedido ( idPedido INT(10) UNSIGNED NOT NULL AUTO_INCREMENT, idCliente INT(10) UNSIGNED NOT NULL , fecha DATE DEFAULT NULL, monto DECIMAL(10,0) DEFAULT NULL, despachado BIT(1) DEFAULT NULL, PRIMARY KEY (idPedido), FOREIGN KEY (idCliente) REFERENCES cliente (idCliente) ) ENGINE=INNODB ; CREATE TABLE detallepedido ( idPedido INT(10) UNSIGNED NOT NULL, idProducto INT(10) UNSIGNED NOT NULL, cantidad INT(10) UNSIGNED DEFAULT NULL, precio DECIMAL(10,2) DEFAULT NULL, FOREIGN KEY (idPedido) REFERENCES Pedido(idPedido), FOREIGN KEY (idProducto) REFERENCES Producto(idProducto) ) ENGINE=INNODB ; CREATE TABLE usuario ( idUsuario INT(10) UNSIGNED NOT NULL AUTO_INCREMENT, nombreUsuario VARCHAR(50) DEFAULT NULL, password VARCHAR(50) DEFAULT NULL, PRIMARY KEY (idUsuario) ) ENGINE=INNODB;

/* Eliminar tablas (Opcional ya q recién hemos cerado las tablas por lo tanto están vacias)*/ DELETE DELETE DELETE DELETE DELETE

FROM FROM FROM FROM FROM

detallepedido; pedido; cliente; producto; usuario;

/*Realizamos los INSERTS*/ INSERT INTO cliente (idCliente, nombre, direccion, telefono, email) VALUES (1, 'Carlos Romero', 'Las Flores', '291006', 'romero@latinmail.com'), (2, 'Condorito', 'Los Paujiles 773', '256301', 'condorito@yahoo.com'), (3, 'Mendoza Castañeda', 'Av Los Incas 778', '210123', 'conchudo@gmail.com'), (4, 'Asto Pajares', 'Mochica 210', '285269', 'pajares@hotmail.com'), (5, 'TROLONCHE', 'Las torres 234', '2334455', 'tr@hotmail.com'), (6, 'Miguel Camacho', 'Las Palmeras 256', '3256211', 'camayus@hotmail.com'), (7, 'Pepe Botellas', 'Los pinos 234', '259888', 'pepebotellas@hotmail.com'), (8, 'Rosita Copas', 'ONPE', '2896544', 'rositacopa@yahoo.es'), (9, 'Pamela Chu', 'Av. Las Pildoras 250', '2541360', 'pamelachu@gmail.com'), (10, 'Napoleon Bonaparte', 'Av. France 256', '2411001', 'don_napo@hotmail.com'), (11, 'Pastruli', 'Av. Washington 1879', '2563114', 'pastruli@yahoo.com'), (12, 'Magdalena Chu', 'ONPE', '5456516', 'magda@onpe.gob.pe'), (13, 'Adolfo Hitler', 'Av. Los geranios 243', '5411162', 'adolf@yahoo.gr'), (14, 'Paulin Paletazo', 'ONPE', '255555', 'paleta@hotmail.com');

INSERT INTO producto (idProducto, nombreProducto, stock, precioVenta, rutaImagen, descripcion) VALUES (1, 'Memoria RAM DDR2 1 GB', 300, '150.00', 'Galeria Equipos/memoria_ram.jpg', 'Memoria DDR2.'), (2, 'Disco Duro 160 GB', 90, '220.00', 'Galeria Equipos/disco duro.jpg', 'Hard Disk.'), (3, 'Teclado Multimedia', 50, '30.00', 'Galeria Equipos/teclado.jpg', 'Teclado Universal.'), (4, 'Mouse Optico', 100, '15.00', 'Galeria Equipos/mouse_cyberlink.jpg', 'Logitech.'), (5, 'Grabadora CD/DVD', 50, '90.00', 'Galeria Equipos/grabadora.jpg', 'LG'), (7, 'Fuentes ATX', 25, '50.00', 'Galeria Equipos/fuentes atx.bmp', ''), (8, 'Estabilizador Hibrido', 35, '70.00', 'Galeria Equipos/estabilizador hibrido.bmp', ''), (9, 'Case CPU Atlon', 80, '70.00', 'Galeria Equipos/CASE CPU ATLON.jpg', ''), (10, 'Web CAM', 15, '50.00', 'Galeria Equipos/web cam.bmp', ''), Docente: Ing. Núñez Marinovich Manuel URL: http://manhiuco.es.tl Página 197 Ingeniero Informático Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación (11, 'Monitor LCD', 35, '300.00', 'Galeria Equipos/monitor.jpg', ''), (12, 'Router', 23, '120.00', 'Galeria Equipos/router.bmp', ''), (13, 'Disqueteras', 2, '10.00', 'Galeria Equipos/disqueteras.bmp', ''), (14, 'Laptop HP Pavilium 3770', 20, '3200.00', 'Galeria Equipos/laptop hp pavilium.bmp', ''), (15, 'Memorias USB', 25, '80.00', 'Galeria Equipos/memoria usb.bmp', 'Memorias USB Kingston'), (16, 'Impresora', 200, '100.00', 'Galeria Equipos/impresora.jpg', 'Impresora Laser'), (17, 'Scanner', 600, '75.00', 'Galeria Equipos/scanner.bmp', ''), (18, 'Joystick', 25, '35.00', 'Galeria Equipos/joystick.jpg', NULL), (19, 'Plotter', 70, '1200.00', 'Galeria Equipos/plotter.jpg', NULL), (20, 'Lectora de codigo de barras', 6, '80.00', 'Galeria Equipos/lectora de codigo de barras.jpg', 'Lectora de codigo de barras'); INSERT INTO pedido (idPedido, idCliente, fecha, monto, despachado) VALUES (1, 1, '2008-06-04', '1270', b'1'), (25, 11, '2010-05-25', '3395', b'1'), (2, 2, '2008-07-04', '610', b'1'), (26, 2, '2010-06-04', '11295', b'1'), (19, 6, '2009-02-22', '210', b'1'), (27, 2, '2010-06-17', '500', b'1'), (20, 7, '2009-03-15', '1820', b'1'), (28, 10, '2010-06-22', '800', b'1'), (21, 8, '2010-01-07', '1510', b'1'), (29, 12, '2011-03-25', '1810', b'1'), (22, 5, '2010-02-12', '2940', b'1'), (30, 13, '2011-03-26', '850', b'1'), (23, 9, '2010-05-02', '9375', b'1'), (31, 14, '2011-03-28', '2160', b'1'); (24, 10, '2010-05-15', '2235', b'1'), INSERT INTO detallepedido (idPedido, idProducto, cantidad, precio) VALUES (1, 1, 150, '2.00'), (22, 12, 4, '120.00'), (1, 2, 220, '4.00'), (23, 17, 5, '75.00'), (1, 3, 15, '6.00'), (23, 19, 7, '1200.00'), (2, 4, 70, '3.00'), (23, 4, 22, '15.00'), (2, 5, 80, '5.00'), (23, 5, 3, '90.00'), (19, 9, 3, '70.00'), (24, 18, 7, '35.00'), (20, 9, 4, '70.00'), (24, 16, 13, '100.00'), (20, 2, 2, '220.00'), (24, 4, 6, '15.00'), (20, 13, 3, '10.00'), (24, 17, 8, '75.00'), (20, 8, 4, '70.00'), (25, 18, 7, '35.00'), (20, 7, 5, '50.00'), (25, 16, 13, '100.00'), (20, 5, 6, '90.00'), (25, 4, 6, '15.00'), (21, 9, 5, '70.00'), (25, 17, 8, '75.00'), (21, 2, 5, '220.00'), (25, 15, 6, '80.00'), (21, 13, 6, '10.00'), (25, 2, 3, '220.00'), (22, 9, 10, '70.00'), (25, 13, 2, '10.00'), (22, 2, 5, '220.00'), (26, 18, 7, '35.00'), (22, 13, 6, '10.00'), (26, 16, 13, '100.00'), (22, 8, 5, '70.00'), (26, 4, 6, '15.00'), (22, 10, 5, '50.00'), (26, 17, 8, '75.00'),

(26, (26, (26, (26, (26, (27, (27, (28, (28, (28, (28, (29, (29, (30, (30, (30, (31, (31, (31, (31,

15, 6, '80.00'), 2, 3, '220.00'), 13, 2, '10.00'), 14, 2, '3200.00'), 11, 5, '300.00'), 15, 5, '80.00'), 7, 2, '50.00'), 15, 5, '80.00'), 7, 2, '50.00'), 17, 2, '75.00'), 1, 1, '150.00'), 9, 7, '70.00'), 2, 6, '220.00'), 9, 2, '70.00'), 8, 3, '70.00'), 16, 5, '100.00'), 9, 5, '70.00'), 2, 6, '220.00'), 13, 4, '10.00'), 5, 5, '90.00');

INSERT INTO usuario (idUsuario, nombreUsuario, password) VALUES (1, 'Administrador', '1');

/*Funcion Nro1: Devolver el nombre del mes ingresando el nro del mes*/ DELIMITER // DROP FUNCTION IF EXISTS fn_devolverMes// CREATE FUNCTION fn_devolverMes (mes INT) RETURNS VARCHAR(20) BEGIN DECLARE resultado VARCHAR(20); IF (mes=1) THEN SET resultado ='Enero'; ELSEIF (mes=2) THEN SET resultado ='Febrero'; ELSEIF (mes=3) THEN SET resultado ='Marzo'; ELSEIF (mes=4) THEN SET resultado ='Abril'; ELSEIF (mes=5) THEN SET resultado ='Mayo'; ELSEIF (mes=6) THEN SET resultado ='Junio'; ELSEIF (mes=7) THEN SET resultado ='Julio'; ELSEIF (mes=8) THEN SET resultado ='Agosto'; ELSEIF (mes=9) THEN SET resultado ='Setiembre'; ELSEIF (mes=10) THEN SET resultado ='Octubre'; Docente: Ing. Núñez Marinovich Manuel Página 198 Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación ELSEIF (mes=11) THEN SET resultado ='Noviembre'; ELSEIF (mes=12) THEN SET resultado ='Diciembre'; END IF; RETURN resultado; END// DELIMITER ;

Creamos los Procedures Procedimiento Nro1: Crear Pedidos: DELIMITER // DROP PROCEDURE IF EXISTS ups_registrarPedido// CREATE PROCEDURE ups_registrarPedido( OUT p_estado VARCHAR(500), -- Parámetro de salida in_nombre VARCHAR(100), in_direccion VARCHAR(100), in_telefono VARCHAR(50),in_email VARCHAR(100), in_monto DECIMAL(10,0), listaCantidad VARCHAR(1000),listaProducto VARCHAR(1000),listaPrecio VARCHAR(1000)) BEGIN DECLARE var_total INT; DECLARE var_idCliente INT; DECLARE var_idPedido INT; DECLARE var_idProducto INT; DECLARE var_producto VARCHAR(100); DECLARE var_cantidad VARCHAR(10); DECLARE var_precio VARCHAR(10);

DECLARE EXIT HANDLER FOR SQLEXCEPTION, SQLWARNING, NOT FOUND BEGIN

-- Cancela la transacción ROLLBACK; SET p_estado := 'Error en el proceso de actualización.'; END; SET p_estado = NULL;

-- Iniciar Transacción START TRANSACTION;

/*1. asignamos a var_total el total de clientes q existen con los datos de entrada. Debe ser 0 o 1*/ SELECT COUNT(idCliente) INTO var_total FROM Cliente usp_reporteTotalesusp_reporteTotalesusp_reporteTotales WHERE nombre=in_nombre AND direccion=in_direccion AND telefono=in_telefono AND email=in_email;

/*1.1 Si no existe el cliente entoces insertamos*/ IF (var_total=0) THEN INSERT INTO Cliente(nombre,direccion,telefono,email) VALUES(in_nombre,in_direccion,in_telefono,in_email); END IF;

/*1.2 extraemos idCliente*/ SELECT idCliente INTO var_idCliente FROM Cliente WHERE nombre=in_nombre AND direccion=in_direccion AND telefono=in_telefono AND email=in_email;

/*2. Insertamos en Pedido*/ INSERT INTO Pedido(idCliente,fecha,monto,despachado) VALUES(var_idCliente,CURRENT_DATE,in_monto,0);

Página 199

Docente: Ing. Núñez Marinovich Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación /*2.1 extraemos idPedido*/ SELECT idPedido INTO var_idPedido FROM Pedido WHERE idCliente=var_idCliente AND fecha=CURRENT_DATE AND monto=in_monto AND despachado=0;

/* Tener en cuenta que: SUBSTRING_INDEX: Return a substring from a string before the specified number of occurrences of the delimiter */ /*3. Insertamos en DetallePedido*/ WHILE (LENGTH(listaProducto)!=0) DO

/*3.1 extraemos el producto*/ SET var_producto=SUBSTRING_INDEX(listaProducto,'|',1); SET listaProducto=SUBSTRING(listaProducto,LENGTH(var_producto) + 2);

/*3.2 extraemos el cantidad*/ SET var_cantidad=SUBSTRING_INDEX(listaCantidad,'|',1); SET listaCantidad=SUBSTRING(listaCantidad,LENGTH(var_cantidad) + 2);

/*3.3 extraemos el precio*/ SET var_precio=SUBSTRING_INDEX(listaPrecio,'|',1); SET listaPrecio=SUBSTRING(listaPrecio,LENGTH(var_precio) + 2);

/*3.4 extraemos idProducto*/ SELECT idProducto INTO var_idProducto FROM Producto WHERE nombreProducto=var_producto; INSERT INTO DetallePedido(idPedido,idProducto,cantidad,precio) VALUES(var_idPedido,var_idProducto,var_cantidad,var_precio); END WHILE;

-- Confirma Transaccion COMMIT; SET p_estado = 'ok'; END // DELIMITER ;

Procedimiento Nro2: Mostrar Pedidos: DELIMITER $$ DROP PROCEDURE IF EXISTS usp_mostrarPedidos$$ CREATE PROCEDURE usp_mostrarPedidos() BEGIN SELECT P.idPedido, C.nombre AS Cliente, P.Fecha, P.Monto, CASE P.Despachado WHEN 1 THEN 'ENTREGADO' ELSE 'PENDIENTE' END AS Despachado FROM Cliente C INNER JOIN Pedido P ON C.idCliente=P.idCliente ORDER BY P.Fecha DESC; END$$ DELIMITER ;

Página 200

Docente: Ing. Núñez Marinovich Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación Procedimiento Nro3: Reporte resumen totales x Año, Mes, Trimestre y Día DELIMITER $$ DROP PROCEDURE IF EXISTS bdcomputienda.usp_reporteTotales$$ CREATE PROCEDURE usp_reporteTotales(IN resumenTiempo VARCHAR(20)) BEGIN SET resumenTiempo=UPPER(resumenTiempo); IF(resumenTiempo='AÑO') THEN SELECT SUM(P.monto) AS Monto, YEAR(P.Fecha) AS Tiempo FROM Pedido P GROUP BY Tiempo ORDER BY Tiempo; ELSEIF(resumenTiempo='MES') THEN SELECT SUM(P.monto) AS Monto, CONCAT(fn_devolverMes(MONTH(P.Fecha)),' ' , YEAR(P.Fecha)) AS Tiempo FROM Pedido P GROUP BY Tiempo ORDER BY fecha; ELSEIF(resumenTiempo='TRIMESTRE') THEN SELECT SUM(P.monto) AS Monto, CONCAT(YEAR(P.Fecha),'-',QUARTER(P.Fecha)) AS Tiempo FROM Pedido P GROUP BY Tiempo ORDER BY Tiempo; ELSEIF(resumenTiempo='DIA') THEN SELECT SUM(P.monto) AS Monto, fecha AS Tiempo FROM Pedido P GROUP BY Tiempo ORDER BY Tiempo; END IF; END$$ DELIMITER ;

COMPUTIENDA - ADO.NET– ADO.NET– SQL SERVER

Para realizar cada procedimiento, haremos uso de las funciones implementadas en la sección de ADO.NET 1. Función que devuelve la cadena de conexión Function devolverCadenaConexion() Return Base_Datos.SQLServer.generarCadenaConexionSQL("bdcomputienda", "GSIE-ALQ-NNUÑEZ\SQLEXPRESS") End Function

2. Procedimiento que muestra el resultado de una consulta de un Stored Procedure con parámetro de entrada. Sub devolverDT() Dim str As String str = devolverCadenaConexion() Dimnp() As String = {"@resumenTiempo"} Dimvp() As String = {"DIA"} Me.DataGridView1.DataSource = Base_Datos.SQLServer.SP_devolverDataTable(str, "usp_reporteTotales", np, vp) End Sub

Página 201

Docente: Ing. Núñez Marinovich Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación 3. Procedimiento que ejecuta un Stored Procedure de Registrar un Pedido, el cual se realiza con transacciones, parámetros de entrada y salida. SubejecutarSP() Dim str As String str = devolverCadenaConexion() Dim np() As String = {"@in_nombre", "@in_direccion", "@in_telefono", "@in_email", "@in_monto", "@listaCantidad", "@listaProducto", "@listaPrecio"} Dim vp() As String = {"Pepito2", "Las Golondrinas 328", "234433", "pp@hotmail.com", 1500.0, "10|12|31", "Joystick|Impresora|Router", "10|20|30"} Dimnps() As String = {"@p_estado"} Dimvps() As String = {""} Base_Datos.SQLServer.SP_ejecutarStoreProcedure(str, "ups_registrarPedido", np, vp, nps, vps) Ifvps(0) = "OK"Then MsgBox("Grabado OK") Else MsgBox("ABORT") End If End Sub

4. Procedimiento muestra el resultado de una función Escalar SubdevolverEscalarFuncion() Dim str As String str = devolverCadenaConexion() Dimnp() As String = {"@mes"} Dimvp() As String = {"12"} MsgBox(Base_Datos.SQLServer.FN_devolverEscalar(str, "fn_devolverMes", np, vp)) End Sub

5. Procedimiento muestra el resultado de una procedimiento almacenado con instrucción RETURN Sub devolverRETURN_StoredProcedure() Dim str As String str = devolverCadenaConexion() Dim np() As String = {"@fechaI", "@fechaF"} Dim vp() As String = {"02/04/2011", "03/04/2011"} Dim nps() As String = {"@resultado"} Dim vps() As String = {""} MsgBox(Base_Datos.SQLServer.FN_devolverEscalar(str, "ups_devolverMonto", np, vp)) End Sub

6. Procedimiento muestra el resultado de una Función en Linea Sub devolverFuncionTablaEnLinea() Dim str As String str = devolverCadenaConexion() Dim np() As String = {"@idPedido"} Dim vp() As String = {"10"} Me.DataGridView1.DataSource = Base_Datos.SQLServer. FN_devolverDT_FuncionReturnTable (str, "SELECT * from dbo.DevolverDetallePedido(@idpedido)", np, vp) End Sub

7. Procedimiento muestra el resultado de una Función Multisentencia SubdevolverFuncionTablaMultiSentencia() Dim str As String str = devolverCadenaConexion() Dim np() As String = {"@idPedido"} Dim vp() As String = {"93"} Me.DataGridView1.DataSource = Base_Datos.SQLServer. FN_devolverDT_FuncionReturnTable (str, "SELECT * from dbo.fn_CategoriaClientes()") End Sub

Página 202

Docente: Ing. Núñez Marinovich Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación

COMPUTIENDA - JDBC– JDBC– MYSQL 1. Clase AccesoDB. Función que devuelve el objeto conexión package database.acceso; import java.sql.Connection; import java.sql.DriverManager; /* import javax.naming.Context; import javax.naming.InitialContext; import javax.sql.DataSource; */ public class AccesoDB { /* public static Connection getConnection() throws Exception { //Usar JNDI Context ctx = new InitialContext(); DataSource ds = (DataSource) ctx.lookup("jdbc/Eureka"); //Obtener la conexión del Pool Connection cn = ds.getConnection(); return cn; } */ private static Connection cn = null; public static Connection getConnection() throws Exception { if (cn == null) { try { Class.forName("com.mysql.jdbc.Driver").newInstance(); String url = "jdbc:mysql://localhost:3306/bdcomputienda"; cn = DriverManager.getConnection(url, "root", "mysql"); } catch (Exception e) { throw e; } }

}

}

return cn;

2. Clase Producto. Mostrar la lista de productos e Insertar uno nuevo package model; import database.acceso.AccesoDB; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map;

Página 203

Docente: Ing. Núñez Marinovich Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación public class ProductoModel { public List<Map<String, String>> mostrarProductos(String nombreProducto) throws Exception { List<Map<String, String>> lista = new ArrayList<Map<String, String>>(); Connection cn = null; try { cn = AccesoDB.getConnection(); // Datos de la cuenta String query = "SELECT * FROM producto WHERE nombreProducto like ? " + " order by nombreProducto "; PreparedStatement pstm = cn.prepareStatement(query); pstm.setString(1, nombreProducto.trim()); ResultSet rs = pstm.executeQuery();

}

while (rs.next()) { Map rec = new HashMap(); rec.put("idProducto", rs.getInt("idProducto")); rec.put("nombreProducto", nombreProducto); rec.put("stock", rs.getInt("stock")); rec.put("precioVenta", rs.getDouble("precioVenta")); rec.put("rutaImagen", rs.getString("rutaImagen")); rec.put("descripcion", rs.getString("descripcion")); lista.add(rec); } rs.close(); } finally { try { //cn.close(); cn=null; } catch (Exception e) { } } return lista;

public void agregaProducto(String nombreProducto, Integer stock, Double precioVenta, String rutaImagen, String descripcion) throws Exception { Connection cn = null; try { cn = AccesoDB.getConnection(); cn.setAutoCommit(false); // Obtener el codigo de sucursal String query = "insert producto(nombreProducto,stock,precioVenta,rutaImagen,descripcion)" + "values(?,?,?,?,?)"; PreparedStatement pstm = cn.prepareStatement(query); pstm.setString(1, nombreProducto); pstm.setInt(2, stock); pstm.setDouble(3, precioVenta); pstm.setString(4, rutaImagen); pstm.setString(5, descripcion); pstm.executeUpdate(); // Confirmar Tx cn.commit(); } catch (Exception e) {

Página 204

Docente: Ing. Núñez Marinovich Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación try {

}

cn.rollback(); } catch (Exception e1) { } throw e; } finally { try { //cn.close(); // Devuelves la conxión al pool cn=null; } catch (Exception e) { } }

}

3. Clase Item y Canasta. Usada para mostrar los productos en el Carrito de Compras. Clase Item package model; public class Item { private String articulo; private Integer cant; private Double precio; public Item() { } public String getArticulo() { return articulo; } public void setArticulo(String articulo) { this.articulo = articulo; } public Integer getCant() { return cant; } public void setCant(Integer cant) { this.cant = cant; } public Double getPrecio() { return precio; } public void setPrecio(Double precio) { this.precio = precio; }

}

public Double getImporte() { return getPrecio() * getCant(); }

Página 205

Docente: Ing. Núñez Marinovich Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación Clase Canasta package model; import database.acceso.AccesoDB; import java.sql.Connection; import java.sql.ResultSet; import java.sql.Statement; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; public class Canasta { private List<Item> lista; public Canasta() { lista = new ArrayList<Item>(); } public void agregarItem(Item item) { for (Item item2 : lista) { if (item2.getArticulo().equals(item.getArticulo())) { item2.setCant(item2.getCant() + item.getCant()); item2.setPrecio(item.getPrecio()); return; } } lista.add(item); } public List<Item> getLista() { return lista; } public void clearLista() { lista.clear(); } public static List<Map<String, String>> mostrarProductos() throws Exception { List<Map<String, String>> listaP = new ArrayList<Map<String, String>>(); Connection cn = null; try { cn = AccesoDB.getConnection(); // Datos de la cuenta String query = "SELECT * FROM producto order by nombreProducto "; Statement stm = cn.createStatement(); ResultSet rs = stm.executeQuery(query); while (rs.next()) { Map rec = new HashMap(); rec.put("idProducto", rs.getInt("idProducto")); rec.put("nombreProducto", rs.getString("nombreProducto")); rec.put("stock", rs.getInt("stock")); rec.put("precioVenta", rs.getDouble("precioVenta")); rec.put("rutaImagen", rs.getString("rutaImagen")); rec.put("descripcion", rs.getString("descripcion"));

Página 206

Docente: Ing. Núñez Marinovich Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación

}

}

listaP.add(rec); } rs.close(); } finally { try { //cn.close(); //cn=null; } catch (Exception e) { } } return listaP;

4. Clase Pedido package model; import database.acceso.AccesoDB; import java.sql.CallableStatement; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.Types; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; public class Pedido { public Pedido() { } public void registrarDeposito( String nombreCliente, String direccion, String telefono, String email, Double monto, String listaCantidad, String listaProducto, String listaPrecio) throws Exception { Connection cn = AccesoDB.getConnection(); cn.setAutoCommit(true); String query = "{call ups_registrarPedido(?,?,?,?,?,?,?,?,?)}"; CallableStatement cstm = cn.prepareCall(query); cstm.registerOutParameter(1, Types.VARCHAR, 50); cstm.setString(2, nombreCliente); cstm.setString(3, direccion); cstm.setString(4, telefono); cstm.setString(5, email); cstm.setDouble(6, monto); cstm.setString(7, listaCantidad); cstm.setString(8, listaProducto); cstm.setString(9, listaPrecio); cstm.executeUpdate(); String estado = cstm.getString(1); if (!estado.equals("ok")) { throw new Exception(estado);

Página 207

Docente: Ing. Núñez Marinovich Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación

}

} cn = null;

public List<Map> reportePedidos() throws Exception { //List<Map<String, String>> lista = new ArrayList<Map<String, String>>(); List<Map> lista = new ArrayList<Map>(); Connection cn = null; try { cn = AccesoDB.getConnection(); //cn.setAutoCommit(true); String query = "{call usp_mostrarPedidos()}"; CallableStatement cstm = cn.prepareCall(query); ResultSet rs = cstm.executeQuery(); while (rs.next()) { Map rec = new HashMap(); rec.put("idPedido", rs.getString("idPedido")); rec.put("cliente", rs.getString("cliente")); rec.put("fecha", rs.getDate("fecha")); rec.put("monto", rs.getDouble("monto")); rec.put("despachado", rs.getString("despachado")); lista.add(rec); } rs.close();

}

} finally { try { cn = null; //cn.close(); } catch (Exception e) { } } return lista;

public List<Map> reporteDetallePedido(int idPedido) throws Exception { //List<Map<String, String>> lista = new ArrayList<Map<String, String>>(); List<Map> lista = new ArrayList<Map>(); Connection cn = null; try { cn = AccesoDB.getConnection(); //cn.setAutoCommit(true); String query = "SELECT nombreProducto AS Producto, cantidad, precio, cantidad*precio AS subtotal" + " FROM detallePedido d INNER JOIN producto p " + " ON d.idProducto=p.idProducto" + " WHERE d.idPedido=?;"; PreparedStatement pstm = cn.prepareStatement(query); pstm.setInt(1, idPedido); ResultSet rs = pstm.executeQuery(); while (rs.next()) { Map rec = new HashMap();

Página 208

Docente: Ing. Núñez Marinovich Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación rec.put("producto", rs.getString("producto")); rec.put("cantidad", rs.getDouble("cantidad")); rec.put("precio", rs.getDouble("precio")); rec.put("subtotal", rs.getDouble("subtotal")); lista.add(rec);

} rs.close();

}

} finally { try { cn = null; //cn.close(); } catch (Exception e) { } } return lista;

public List<Map> reporteMontosxAño() throws Exception { List<Map> lista = new ArrayList<Map>(); Connection cn = null; try { cn = AccesoDB.getConnection(); //cn.setAutoCommit(true); String query = "{call usp_reporteTotales('AÑO')}"; CallableStatement cstm = cn.prepareCall(query); ResultSet rs = cstm.executeQuery(); while (rs.next()) { Map rec = new HashMap(); rec.put("monto", rs.getDouble("monto")); rec.put("tiempo", rs.getInt("tiempo")); lista.add(rec); } rs.close();

}

} finally { try { cn = null; //cn.close(); } catch (Exception e) { } } return lista;

public void actualizarEntregaPedido(Integer idPedido) throws Exception { Connection cn = null; try { cn = AccesoDB.getConnection(); cn.setAutoCommit(false); // Obtener el codigo de sucursal String query = "UPDATE pedido " + "SET despachado=1 " + "WHERE idPedido=? "; PreparedStatement pstm = cn.prepareStatement(query);

Página 209

Docente: Ing. Núñez Marinovich Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación pstm.setInt(1, idPedido); pstm.executeUpdate(); // Confirmar Tx cn.commit();

}

}

} catch (Exception e) { try { cn.rollback(); } catch (Exception e1) { } throw e; } finally { try { //cn.close(); // Devuelves la conxión al pool cn=null; } catch (Exception e) { } }

5. Clase Cliente package model; import database.acceso.AccesoDB; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.Statement; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; public class ClienteModel { public List<Map<String, String>> getClientes() throws Exception { List<Map<String, String>> lista = new ArrayList<Map<String, String>>(); Connection cn = null; try { cn = AccesoDB.getConnection(); // Datos de la cuenta String nombreCliente = ""; String query = "SELECT * FROM cliente WHERE nombre like ? " + " order by nombre "; PreparedStatement pstm = cn.prepareStatement(query); pstm.setString(1, "%" + nombreCliente + "%"); ResultSet rs = pstm.executeQuery(); /* String query = "SELECT * FROM cliente order by nombre "; Statement stm = cn.createStatement(); ResultSet rs = stm.executeQuery(query); */

Página 210

Docente: Ing. Núñez Marinovich Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación

}

while (rs.next()) { Map rec = new HashMap(); //rec.put("idProducto", rs.getInt("idProducto")); rec.put("nombre", rs.getString("nombre")); rec.put("direccion", rs.getString("direccion")); rec.put("telefono", rs.getString("telefono")); rec.put("email", rs.getString("email")); lista.add(rec); } rs.close(); } finally { try { // cn.close(); } catch (Exception e) { } } return lista;

public List<Map> mostrarClientesMasCompraron() throws Exception { List<Map> lista = new ArrayList<Map>(); Connection cn = null; try { cn = AccesoDB.getConnection(); // Datos de la cuenta String query = "SELECT c.nombre as Cliente, sum(monto) Recaudacion " + "FROM cliente c inner join pedido p " + "on c.idCliente=p.idCliente " + "where despachado=1 " + "GROUP BY Cliente ORDER BY Recaudacion DESC "; Statement stm = cn.createStatement(); ResultSet rs = stm.executeQuery(query); while (rs.next()) { Map rec = new HashMap(); rec.put("cliente", rs.getString("cliente")); rec.put("recaudacion", rs.getString("recaudacion")); lista.add(rec); } rs.close();

}

}

} finally { try { //cn.close(); cn=null; } catch (Exception e) { } } return lista;

Página 211

Docente: Ing. Núñez Marinovich Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación

COMPUTIENDA – PHP – MYSQL MYSQL Archivos comunes: head.php, conexión.php Carrito de compras: catalogo.php, llenarCarrito.php head.php <?php echo "<html> <head> <link rel='stylesheet' type='text/css' href='estilo1.css'/> </head> <body>"; ?> conexion.php <?php /****************ARCHIVO DE CONEXION A NUESTRA BD************************/ $username="root"; $password="mysql"; $server="localhost"; $bdatos="BDCompuTienda"; //*/ $ocn=@mysql_connect($server,$username,$password) or die("<h2>!!!Error de conexion al servidor!!!</h2>"); mysql_select_db($bdatos,$ocn);

?> Catalogo.php <?php

include("head.php"); include("conexion.php"); $SQL = "SELECT * FROM Producto" ; $rs = @mysql_query($SQL,$ocn) or die("<h2>!!!Error: no se puedo ejecutar la consulta!!!</h2>"); echo "<table align='center' border='0' cellspacing='6' cellpadding='0' > <tr>"; $cont=0; while($reg=mysql_fetch_array($rs)){ $cont++; $rutaImagen=$reg[4]; $descripcion= $reg[5]; // echo "$descripcion"; echo "<td> <form id='$reg[0]' action='llenarCarrito.php' method='POST' > <table border='0' cellspacing='10' cellpadding='0' bgcolor='lightblue' > <tr> <td colspan='3' align='center'> <a href='$reg[4]' target='_blank'> <img height='80' width='80' border='0' src='$rutaImagen' ALT='Descripcion: $descripcion'> </a> </td> </tr>

Página 212

Docente: Ing. Núñez Marinovich Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación <tr> <td colspan='3' align='center'>$reg[1]</td> </tr> <tr> maxlength='4'>

<td align='center'> Cant:<input type='text' name='txtCantidad' size='4' <input type='hidden' name='txtProducto' value='$reg[1]'> <input type='hidden' name='txtPrecio' value='$reg[3]'> <input type='hidden' name='pagina' value='Catalogo.php'> </td> <td>Precio: S/. $reg[3]</td> <td>

src='Imagenes/carrito.gif'>

<input type='image' name='$reg[0]'

</td>

</tr> </table> </form> </td>" ; if ($cont==2) { echo "</tr><tr>"; $cont=0; }

} echo "</table>"; mysql_free_result($rs); mysql_close($ocn); ?>

llenarCarrito.php <? //grabarcompras.php session_register("nrocompra"); include("conexion.php"); $SQL="INSERT INTO TempoPedido values('$nrocompra', '$txtProducto', $txtPrecio, $txtCantidad)"; $rs = @mysql_query($SQL,$ocn) or die("<h2>!!!Error: no se puedo ejecutar la consulta!!!</h2></br>".$SQL); //sleep(2); //header("Location: $pagina"); HEADER("Location: catalogo.php"); ?>

Página 213

Docente: Ing. Núñez Marinovich Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación Mantenimiento de productos: Producto.php <?php include("head.php"); //Paginacion /************Parametros de conexion****************/ include("conexion.php"); /***********Consulta principal******************/ if(!isset($nro)) $nro=0; $regxpag=10;//nro de registros por consulta $SQL="SELECT * FROM Producto LIMIT $nro, $regxpag"; $tabla=@mysql_query($SQL, $ocn) or die ("<h2>Error en la consulta</h2>"); //echo "<h3>Lista de Productos</h3><hr>"; echo "<table align='center' border=1 width='600' bordercolor='navy' cellpading='0' cellspacing='0'>"; echo " <tr><td align='center' bgcolor='#3399FF' colspan=6><b>Lista de Productos</b></td></tr> <tr align='center' bgcolor='lightblue' style='font-size:14px' > <td width='0'><b>Codigo</b></td> <td><b>Producto</b></td> <td><b>Stock</b></td> <td><b>Precio</b></td> <td></td> <td></td> </tr> "; while($fila=mysql_fetch_array($tabla)) echo "<tr><td>" . $fila[0] . "</td>" . "<td>" . $fila[1] . "</td>" . "<td align='center' >" . $fila[2] . "</td>" . "<td align='center' >" . $fila[3] . "</td>" . "<td align='center'><a href='modificarProducto.php?cod=$fila[0]'><img height='20' width='20' alt='Modificar' src='imagenes/modificar.ico' border='0'></a></td>" . "<td align='center'><a href='eliminarProducto.php?cod=$fila[0]'><img alt='Eliminar'src='imagenes/eliminar.ico' border='0'></a></td>" . "</tr>" ; echo "</table>"; /************fin de Consulta principal**********/ /***********consulta para la paginacion********/ $SQL="SELECT * FROM Producto"; $tabla=@mysql_query($SQL, $ocn) or die ("<h2>Error en la consulta</h2>"); /***********calculando el nro de paginas ********/ $totalreg=mysql_num_rows($tabla); $nropags=$totalreg/$regxpag; /*********** imprimiendo el nro de paginas ******/ echo "<center>"; for($j=0; $j<=$nropags; $j++) {$inicio=$j*$regxpag; if($nro==$inicio) echo "<a href='productos.php?nro=$inicio'> <font face='verdana' size='3' color='#3399FF'><b>[$j]</b></font></a>"; else echo "<a href='productos.php?nro=$inicio'><font face='verdana' size='2'>[$j]</font></a>"; } echo "</center>"; /***********fin de la paginacion********/

Página 214

Docente: Ing. Núñez Marinovich Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com


Aromas de Bases de Datos y otras fragancias de Programación mysql_close($ocn); echo " <table align=right bgcolor='#3399FF' > <tr> <td> <a class='agregar' href='insertarProducto.php'> Agregar Producto </a> <td><tr></table>"; ?> </body> </html>

Página 215

Docente: Ing. Núñez Marinovich Manuel Ingeniero Informático

URL: http://manhiuco.es.tl Email: manhiuco@hotmail.com

Aromas de Base de datos y otras fragancias de programación  

La presente obra es un compendio que abarca la implementación de bases de datos (SQL Server, Oracle, MySQL, PostgreSQL), y sus diferentes co...

Aromas de Base de datos y otras fragancias de programación  

La presente obra es un compendio que abarca la implementación de bases de datos (SQL Server, Oracle, MySQL, PostgreSQL), y sus diferentes co...

Advertisement