javoaxian cambió a: javoaxian.me
Este blog se mantendrá como histórico del nuevo javoaxian.me. Por tal motivo, sólo serán creados post que harán referencia a los del nuevo blog. Si hay dudas y comentarios, favor de hacerlos en javoaxian.me.
Mostrando entradas con la etiqueta SQL. Mostrar todas las entradas
Mostrando entradas con la etiqueta SQL. Mostrar todas las entradas

miércoles, 17 de septiembre de 2008

Obtener el tamaño de una base de datos en PostgreSQL

En ocasiones necesitamos saber el tamaño que está ocupando nuestra base de datos de PostgreSQL dentro del disco duro, ya sea para solicitar recursos para migrar alguna aplicación, o alguna estadística en cuestión del crecimiento de la base de datos, en fin, para diversas cosas.

La forma en que podemos obtener dicho tamaño dentro del prompt de PostgreSQL, puede ser ejecutando esta sentencia de SQL.

javoaxian=> SELECT datname, pg_database_size(datname) FROM pg_database;

La sentencia anterior nos devuelve el tamaño en bytes de todas las bases de datos que existen en el manejador.

Si quisieramos obtener el tamaño de una base en específco, podríamos ejecutar la sentencia de la siguiente manera:

javoaxian=> SELECT datname, pg_database_size(datname) FROM pg_database WHERE datname='javoaxian';

Para finalizar, si también quisieramos convertir a kbytes el tamaño de la base de datos, podemos hacer lo siguiente:

javoaxian=> SELECT datname, pg_size_pretty(pg_database_size(datname)) FROM pg_database WHERE datname='javoaxian';

lunes, 15 de septiembre de 2008

Crear una base de datos en PostgreSQL

Hoy veremos la manera básica en que podemos crear una base de datos en PostgreSQL. Para hacer ésto, nos deberemos de conectar con la cuenta de administración de PostgreSQL la cual es postgres o en su defecto con algún usuario que tenga los privilegios para crear bases de datos.

javoaxian@sky:~$ psql -U postgres -d template1
template1=#

Ahora que ya estamos conectados al manejador de base de datos, crearemos una base de datos llamada javoaxian en donde el dueño de dicha base de datos será el usuario javoaxian y el encoding utilizado en ella será LATIN1.

template1=# CREATE DATABASE javoaxian WITH OWNER=javoaxian ENCODING='LATIN1';

Con esto ha quedado creada nuestra base de datos, cabe recordar que también deberemos modificar el archivo pg_hba.conf para darle permisos al usuario javoaxian para que se pueda conectar a la base de datos.

Para ejemplificar, supondré que tenemos instalado PostgreSQL en /opt/pgsql, por lo tanto nuestro archivo pg_hba.conf se encuentra situado en /opt/pgsql/data. Editamos el archivo con el editor de texto de nuestra preferencia, siempre y cuando el usuario que lo edite sea el usuario postgres o el usuario root.
Al final del archivo agregaremos la siguiente línea para permitir que nuestro usuario (en mi caso javoaxian) se conecte a la base de datos (javoaxian) con el algoritmo de cifrado md5.

local   javoaxian   javoaxian                   md5

Y si deseamos que también se pueda conectar remotamente desde cualquier parte:
host    javoaxian   javoaxian   0.0.0.0 0.0.0.0       md5

Deberemos guardar los cambios y reiniciar el manejador de base de datos. Para detener el servicio pueden hacer ésto:

postgres@darthmaul:~$ kill -INT `head -1 /opt/pgsql/data/postmaster.pid`

y para reiniciarlo, pueden realizar esto otro:

postgres@darthmaul:~$ /opt/pgsql/bin/postmaster -D /opt/pgsql/data&

Con todo lo anterior, deberán poderse conectar a la nueva base de datos. En mi caso sería de la siguiente manera:

javoaxian@sky:~$ psql -U javoaxian -d javoaxian
Password for user javoaxian:

Welcome to psql 8.3.1, the PostgreSQL interactive terminal.

Type: \copyright for distribution terms
\h for help with SQL commands
\? for help with psql commands
\g or terminate with semicolon to execute query
\q to quit

javoaxian=>

sábado, 13 de septiembre de 2008

Ver los tablespaces de una base de datos con sqlplus en Oracle

En ocasiones deseamos consultar los tablespaces que se encuentran creado en una base de datos usando sqlplus pero no sabemos cómo. Pues bien, la forma de consultarlos es muy sencilla, deberemos ejecutar alguna de las siguientes instrucciones en SQL, las cuales nos devolverán los nombres de los tablespaces creado.

En caso de ser usuario sys o system, podemos ejecutar la siguiente consulta:

SQL> SELECT tablespace_name FROM dba_tablespaces;

En el caso de ser un usuario que no tiene privilegios de administrador, podemos ejecutar la siguiente consulta:

SQL> SELECT tablespace_name FROM user_tablespaces;

Como se puede observar, únicamente estamos obteniendo el nombre de los tablespaces, pero podemos obtener más información de ellos usando el operador *, por ejemplo:

SQL> SELECT * FROM dba_tablespaces;

o

SQL> SELECT * FROM user_tablespaces;

martes, 26 de agosto de 2008

Manipular tablespaces en Oracle 10g Expression Edition

En el siguiente post, mostaré la manipulación básica de los tablespace en Oracle. Cabe mencionar que no sólo se basa para la versión 10g Expression Edition sino también para las demás versiones de Oracle.

En Oracle una base de datos está formada por varias unidades lógicas, las cuales son llamadas Tablespaces y éstos a su vez, están formados por uno o más datafiles, los cuales son los archivos donde se almacenará la información físicamente.

Para poder manipular un tablespace, primeramente nos conectaremos a la base de datos usando sqlplus con la cuenta del usuario SYSTEM.

javoaxian@darthmaul:~$ sqlplus SYSTEM

SQL*Plus: Release 10.2.0.1.0 - Production on Mar Ago 26 17:25:32 2008

Copyright (c) 1982, 2005, Oracle. All rights reserved.

Introduzca la contraseña:

Conectado a:
Oracle Database 10g Express Edition Release 10.2.0.1.0 - Production

SQL>

Conectados a la base de datos, ejecutaremos el siguiente comando para crear nuestro tablespace.

SQL> CREATE TABLESPACE javoaxian DATAFILE 'javoaxian.dbf' size 100M;

Tablespace creado.

SQL>

Como se puede observar, se usará el comando CREATE TABLESPACE seguido del nombre del tablespace como le queramos modificar, posteriormente sigue la palabra DATAFILE donde se especifíca la ruta y el nombre del archivo que almacenará los datos físicamente con extensión ".dbf", y por último se especifíca el tamaño del tablespace con la palabra size y el número en megas o gigas que se desee.

Ahora, si lo que deseamos es incrementar el tamaño del tablespace que tenemos, bastará con hacer lo siguiente:

SQL> ALTER DATABASE DATAFILE 'javoaxian.dbf' RESIZE 50M;

Para borrar un tablespace haremos lo siguiente:

DROP TABLESPACE javoaxian;

Cabe mencionar que se borra el tablespace más no el datafile, por lo cual en el caso de Oracle XE, guarda por default los datafile en el directorio:
/usr/lib/oracle/xe/app/oracle/product/10.2.0/server/dbs.

Si deseamos dar de baja temporalmente el tablespace que queremos, la manera de hacerlo es la siguiente:

SQL> ALTER TABLESPACE javoaxian OFFLINE;

Y en el caso de dar de alta, deberemos hacer esto:

SQL> ALTER TABLESPACE javoaxian ONLINE;

También podemos hacer que nuestro tablespace sea creado de lectura únicamente:

SQL> ALTER TABLESPACE javoaxian READ ONLY;

Y si lo quisieramos poner de lectura/escritura, realizaríamos lo siguiente:

SQL> ALTER TABLESPACE javoaxian READ WRITE;

Espero que estas breves instrucciones puedan servirles.

martes, 24 de junio de 2008

Habilitar una base de datos en MySQL para poder conectar a ella vía remota

Vamos a ver el día de hoy cómo podemos configurar nuestra base de datos en MySQL para poder conectarnos a ella de forma remota. Esto nos servirá para permitir conectar clientes de base de datos o el comando mysql a nuestra base de datos que se encuentra en un equipo diferente del que nos estámos conectando.

La forma para habilitar la conexión remota a nuestra base de datos es dandole permisos al usuario que tiene acceso a la base de datos, y la forma de hacerlo es con el comando GRANT. Esto deberá ser ejecutado por el usuario root de mysql.

Aquí pongo un ejemplo de cómo le voy a dar permisos al usuario javoaxian para conectarse a la base de datos javoaxian de manera remota.

javoaxian@darthmaul:~$ mysql -u root -p mysql
Enter password:
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 7 to server version: 5.0.24-standard

Type 'help;' or '\h' for help. Type '\c' to clear the buffer.

mysql> GRANT ALL PRIVILEGES ON javoaxian.* TO 'javoaxian'@'%' IDENTIFIED BY 'CONTRASENIA';
mysql> FLUSH PRIVILEGES;

Como se puede observar, el signo "%" es el que hace la diferencia, éste le indica al comando GRANT que nuestro usuario tiene permisos para conectarse vía remota a la base de datos que le estamos especificando. Y el comando FLUSH PRIVILEGES sirve para actualizar los permisos;

Recuerden que si tienen un firewall activado, deberán construir las reglas para permitir a los usuarios conectarse al puerto 3306 que es el puerto por donde corre MySQL o el que tengan configurado en caso de haberlo cambiado.

Esto es todo para activar esta opción, ahora ya podrán conectar Eclipse y SQL Explorer o cualquier otro cliente que deseen usar con su base de datos.

domingo, 22 de junio de 2008

Crear una base de datos en MySQL junto con un usuario para accedera a ella

El motivo de crear este post, es para poder explicarle a una amiga como puede crear una base de datos en MySQL, así como un usuario para conectarse a esta base de datos.

Lo primero que debemos hacer, es conectarnos con el usuario root a mysql.
En caso de que el usuario root tenga asignada una contraseña deberemos ejecutar lo siguiente:

javoaxian@darthmaul:~$ mysql -u root -p mysql

En caso contrario:

javoaxian@darthmaul:~$ mysql -u root mysql

Ahora que ya estamos conectados a mysql, crearemos la base de datos. Para este ejemplo, el nombre de la base de datos será db_proyesp.

mysql> CREATE DATABASE db_proyesp;

Ya que tenemos creada la base de datos, crearemos el usuario que se podrá conectar a la base de datos dandole todos los privilegios, que en este caso será us_proyesp.

mysql> GRANT ALL PRIVILEGES ON db_proyesp.* TO 'us_proyesp'@'localhost' IDENTIFIED BY 'CONTRASEÑA';
mysql> FLUSH PRIVILEGES;

En las instrucciones anteriores, le decimos al comando GRANT que le de todos los privilegios al usuario us_proyesp sobre todos los elementos de la base de datos db_proyesp, además de asignarle una contraseña al usuario. Y con el comando FLUSH PRIVILEGES actualizamos los privilegios del manejador.

Con esto ya tenemos creada tanto la base de datos como nuestro usuario en mysql.

Nuestro siguiente paso será salirnos de nuestra sesión de usuario root de mysql.

mysql> exit;
Bye

Ahora nos conectaremos a la nueva base de datos con el usuario que también creamos.
El comando para conectarse a la base de datos será:

javoaxian@darthmaul:~$ mysql -u us_proyesp -p db_proyesp

Como podemos observar, con la opción -u le indicamos al comando mysql el usuario de la base de datos.
Con la opción -p, indicamos que nos deberá pedir la contraseña del usuario y por último, seguido a la opción -p le indicamos el nombre de la base de datos a la que deseamos conectarnos.

Esto es todo con relación a este tema.

miércoles, 18 de junio de 2008

SELECT INTO en MySQL

En algunas ocasiones necesitamos guardar el resultado de una consulta en otra tabla dentro de la base de datos, para ello en algunos manejadores de base de datos contamos con el comando SELECT INTO ..., pero éste no existe en MySQL, en su lugar deberemos usar el comando INSERT INTO ... SELECT.

La manera para usar este comando es muy sencilla. Vamos a suponer que contamos con las tablas pais y usuario:

CREATE TABLE pais (
id INTEGER UNSIGNED NOT NULL,
nombre VARCHAR(100) NOT NULL,
PRIMARY KEY(id)
)
TYPE=InnoDB;

CREATE TABLE usuario (
id BIGINT NOT NULL,
pais_id INTEGER UNSIGNED NOT NULL,
nombre VARCHAR(150) NOT NULL,
PRIMARY KEY(id, pais_id),
INDEX usuario_FKIndex1(pais_id),
FOREIGN KEY(pais_id)
REFERENCES pais(id)
ON DELETE NO ACTION
ON UPDATE NO ACTION
)
TYPE=InnoDB;

Ahora deseamos guardar en otra tabla únicamente el nombre de los usuarios y el nombre del país al que pertenece. Para esto crearemos una tabla llamada usuario_pais en la que vamos a depositar estos datos:

CREATE TABLE usuario_pais (
usuario_nombre VARCHAR(150) NOT NULL,
pais_nombre VARCHAR(100) NOT NULL,
PRIMARY KEY(usuario_nombre)
)
TYPE=InnoDB;

Una vez que ya se tienen las 3 tablas, deberemos ejecutar el comando INSERT INTO ... SELECT para guardar los nombres de los usuarios y sus países en la tercer tabla que creamos. Esto se hace de la siguiente manera:

mysql> INSERT INTO usuario_pais (usuario_nombre,pais_nombre)
SELECT usuario.nombre, pais.nombre FROM
usuario
INNER JOIN pais ON usuario.pais_id=pais.id;

Esto habrá guardado los registros que encontró en la tabla usuario_pais, y en mi caso el contenido de mi tabla queda de esta manera:

mysql> select * from usuario_pais;
+----------------+-------------+
| usuario_nombre | pais_nombre |
+----------------+-------------+
| Beatriz Guzmán | Portugal |
| Juan Pérez | México |
+----------------+-------------+

Listo, con esto ya pueden mandar el resultado de una consulta a otra tabla.

domingo, 8 de junio de 2008

Implementar trigger en PostgreSQL usando PL/pgSQL

En esta ocasión, voy a explicar como podemos crear un Trigger en PostgreSQL usando PL/pgSQL.

Lo primero que se debe de hacer, es crear una función la cual se encargará de manejar los procedimientos de PL. Esto deberá hacerse con la cuenta de usuario postgres en la base de datos donde vamos a crear el trigger. Por tal motivo abriremos una sesión de postgres con el usuario postgres en nuestra base de datos, la cual para fines de este ejemplo usaré el nombre de javoaxian.

javoaxian@darthmaul:~$ psql -U postgres -d javoaxian

Ya que estamos en el prompt de postgres, crearemos la función plpgsql_call_handler y le debemos de indicar donde debe encontrar el archivo plpgsql.so, el cual se encuentra situado en el directorio lib donde fue instalado postgresql, que en mi caso esta en /opt/pgsql/lib.

javoaxian=# CREATE FUNCTION plpgsql_call_handler() RETURNS language_handler AS '/opt/pgsql/lib/plpgsql.so' LANGUAGE C;

Ahora dejaremos de ser el usuario postgres y nos convertiremos en el dueño de la base de datos, que en mi caso será javoaxian.

javoaxian=# \c javoaxian javoaxian

Esto nos pedirá el password del usuario javoaxian y una vez que ingresemos éste, nos indicará que estamos conectados a la base de datos con el usuario que indicamos.

Password for user javoaxian:
You are now connected to database "javoaxian" as user "javoaxian".
javoaxian=>

Ahora que ya ingresamos con nuestro usuario, podemos crear el lenguaje plpgsql en nuestra base de datos y le indicamos la función plpgsql_call_handler que creamos con el usuario postgres.

javoaxian=> CREATE LANGUAGE 'plpgsql' HANDLER plpgsql_call_handler LANCOMPILER 'PL/pgSQL';

Lo anterior nos mostrará algo similar a esto:

NOTICE: using pg_pltemplate information instead of CREATE LANGUAGE parameters
CREATE LANGUAGE

Creado el lenguaje, procederemos a crear el procedimiento almacenado que llamará el trigger que crearemos. Este procedimiento se encargará de verificar que no se inserten más de 100 registros en una tabla llamada usuario, por tal motivo, deberemos tener creada una tabla llamada usuario y para fines de este post puede estar estructurada de la siguiente manera:

javoaxian=> CREATE TABLE usuario(
id INTEGER NOT NULL PRIMARY KEY,
nombre VARCHAR(80) NOT NULL);

Ahora crearemos el procedimiento:

javoaxian=> CREATE FUNCTION sp_max_100_registros() RETURNS trigger AS $trigger_max_100_registros$
DECLARE
registro RECORD;
BEGIN
SELECT INTO registro COUNT(*) AS numRegistros
FROM usuario;

IF registro.numRegistros < 100 THEN
RETURN NEW;
ELSE
RAISE EXCEPTION 'No pueden existir más de 100 registros en la tabla usuario';
RETURN NULL;
END IF;
END;
$trigger_max_100_registros$ LANGUAGE plpgsql;

Como se puede observar en el procedimiento, se le deberá poner un nombre, que en este caso es sp_max_100_registros(), seguido de esto le indicamos que vamos a devolver un tipo de dato trigger y que tendrá el nombre de trigger_max_100_registros entre signos de "$".
Posteriormente, declaramos una variable llamada registro en la sección de variables DECLARE y le indicamos que es de tipo RECORD ya que en esta variable se almacenará el resultado de nuestra consulta.
Seguido de esta sección, colocamos la sección BEGIN, la cual nos permitirá poner el comportamiente de nuestro procedimiento hasta encontrar una instrucción END que lo finalize.
Entre las instrucciones BEGIN y END ejecutaremos una sentencia SELECT que cuenta el número de registros en la tabla usuario. Dicha sentencia cuenta con la opción INTO, ya que es la que permite asignar el resultado a nuestra variable registro.
Luego encontraremos un IF con su respectivos THEN, ELSE y END IF, donde preguntamos por medio de la variable registro si obtuvo menos de 100 registros, si la condición es afirmativa, entonces devuelve una variable llamada NEW, la cual indica que puede ser insertado el registro en la tabla usuario, pero en caso contrario, entonces nos devuelve una excepción indicando que no pueden existir más de 100 registros en la tabla usuario.
Por último indicamos el nombre del trigger entre signos de "$" que en el ejemplo es: trigger_max_100_registros y el lenguaje del procedimiento, que en este caso es plpgsql.

Ya que contamos con el procedimiento almacenado, crearemos nuestro trigger, y para hacer esto, deberemos hacer lo siguiente:

javoaxian=> CREATE TRIGGER trigger_max_100_registros
BEFORE INSERT ON usuario
FOR EACH ROW EXECUTE PROCEDURE sp_max_100_registros();

La declaración del anterior nos indica que vamos a crear un TRIGGER llamado trigger_max_100_registros, el cual se deberá lanzar antes de realizar un INSERT sobre la tabla usuario para cada registro (FOR EACH ROW), y le indicamos que deberá ejecutar el procedimiento almacenado que creamos, el cual es: sp_max_100_registros().

Ahora ya tenemos creado nuestro trigger y cada vez insertemos un registro, verificará si puede insertar dicho registro.

Para borrar nuestro trigger, lo primero que hay que hacer, será ejecutar la siguiente línea:

javoaxian=> DROP TRIGGER trigger_max_100_registros ON usuario;

En la instrucción anterior indicamos el nombre del trigger que queremos borrar y sobre que tabla está referenciada.

Una vez que borramos el trigger, también deberemos borrar su procedimiento almacenado, y esto lo haremos de esta forma:

javoaxian=> DROP FUNCTION sp_max_100_registros();

Se puede observar, que en el comando anterior deberémos indicar el nombre del procedimiento y que este debe llevar los paréntesis que abren y cierra.

Ahora bien, pondré otro trigger, el cual se encarga de verificar que después de insertar en nuestra tabla usuario un registro cuyo nombre cuente con la palabra luis, ya no permita meter más registros.

El procedimiento sería de esta manera:

CREATE FUNCTION sp_sin_luis() RETURNS trigger AS $trigger_sin_luis$
BEGIN
PERFORM * FROM usuario WHERE UPPER(nombre) LIKE UPPER('%luis%');

IF NOT FOUND THEN
RAISE NOTICE 'Se insertará el registro';
RETURN NEW;
ELSE
RAISE EXCEPTION 'No se insertará el registro';
RETURN NULL;
END IF;
END;
$trigger_sin_luis$ LANGUAGE plpgsql;

Y el trigger:

CREATE TRIGGER trigger_sin_luis
BEFORE INSERT OR UPDATE ON usuario
FOR EACH ROW EXECUTE PROCEDURE sp_sin_luis();

Entre las cosas diferentes del procedimiento de este nuevo trigger, es que no definimos la sección DECLARE, aparte en lugar de poner la sentencia SELECT ponemos la palabra PERFORM. La diferencia radica en que PERFORM se usa para cuando hacemos consultas en las cuales no vamos a usar el resultado de ésta.
También otra diferencia es en la instrucción IF, ya que usamos la palabra NOT FOUND, la cual sirve para preguntar si no se encontraron registro en la consulta hecha.
La última diferencia del procedimiento está dentro del IF, podemos observar que antes de devolver el nuevo registro (RETURN NEW), usamos la instrucción: RAISE NOTICE, y ésta nos permite mandar un mensaje a la salida estandar de notificación.

La diferencia en la creación del trigger, es que también indicamos que se ejecute cuando se hagan UPDATE's.

Por último, pondré un ejemplo, el cual se encarga de verificar que no se pueda insertar un registro en la tabla usuario que contenga la cadena luis.

Procedimiento:

CREATE FUNCTION sp_no_luis() RETURNS trigger AS $trigger_no_luis$
BEGIN
IF UPPER(NEW.nombre) LIKE '%LUIS%' THEN
RAISE EXCEPTION 'El registro contiene el nombre de luis';
RETURN NULL;
ELSE
RAISE NOTICE 'Se agregará el registro';
RETURN NEW;
END IF;
END;
$trigger_no_luis$ LANGUAGE plpgsql;

Trigger:

CREATE TRIGGER trigger_no_luis
BEFORE INSERT OR UPDATE ON usuario
FOR EACH ROW EXECUTE PROCEDURE sp_no_luis();

La diferencia en este último, es que usamos la instrucción NEW para hacer la comparación. Esta instrucción contiene el nuevo registro y por consiguiente los datos de los campos ha insertar, los cuales podemos hacer referencia por medio del nombre del campo como se puede observar. Algo IMPORTANTE de mencionar, es que para poder usar la instrucción NEW u otra llamada OLD, es que cuando creemos el trigger, deberemos poner la instrucción FOR EACH ROW, ya que sin esta no se crearán estos elementos.

Si deseean ver un poco más de las opciones con que cuenta un trigger, puede ver este archivo, el cual encontré en esta página.

sábado, 31 de mayo de 2008

Cargar datos a una tabla en PostgreSQL desde un archivo de texto

La forma de cargar datos a una tabla de PostgreSQL desde un archivo es muy fácil. Bastará con usar el comando COPY que nos proporciona el prompt de postgres para obtener los datos y cargarlos a la tabla.

En este ejemplo usaremos un archivo llamado tipo_usuario.txt. El archivo contendrá los tipos de usuario de un sistema. Contará con dos columnas separadas por tabulador, la primer columna tendrá el id del tipo de usuario y la segunda columna tendrá el nombre del tipo de usuario.
Cada registro estará separado por una nueva línea por lo que el archivo quedaría de la siguiente manera:

1       Administrador
2 Editor
3 Redactor

En cuestion a la base de datos, deberemos tener una tabla llamada tipo_usuario en la que cargaremos los datos. Esta tabla podría tener la siguiente estructura:

CREATE TABLE tipo_usuario(
id NUMERIC(2) NOT NULL PRIMARY KEY,
nombre VARCHAR(50) NOT NULL);

Para cargar el archivo deberemos de ingresar al prompt de postgres. En este caso voy a usar como datos el usuario javoaxian y la base de datos javoaxian.
javoaxian@darthmaul:~$ psql -U javoaxian -d javoaxian

Una vez que estamos dentro del prompt de postgres ejecutaremos el siguiente comando para cargar nuestra información:

javoaxian=> \COPY tipo_usuario FROM '/home/javoaxian/tipo_usuario.txt' WITH DELIMITER AS '\t'

Listo, esto es todo para cargar los datos en la tabla desde un archivo de texto.

lunes, 26 de mayo de 2008

Exportar el resultado de una consulta a un archivo en MySQL

En unos cuantos posts anteriores publiqué como podíamos cargar la información de un archivo a una tabla. Pues el día de hoy voy a explicar como podemos enviar el resultado de una consulta a un archivo.

Al igual que el comando LOAD DATA, nuestra cuenta de usuario de MySQL necesita el privilegio global FILE. Para poder asignarlos pueden consultar el artículo que mencioné anteriormente, ya qué allí menciono como podemos asignar los privilegios necesarios.

Una vez que contamos con los permisos, ahora en el prompt de mysql, ejecutaremos la consulta que deseamos enviar a nuestro archivo, con la única diferencia que especificaremos el archivo de salida y delimitador de campos. Para ejemplificar esto, pondré una consulta de la tabla pais en el archivo /tmp/pais.txt y los campos los limitaré por un tabulador.

mysql> SELECT * INTO OUTFILE '/tmp/pais.txt' FIELDS TERMINATED BY '\t' LINES TERMINATED BY '\n' FROM pais;

Es importante mencionar que el archivo creado de esta forma, pertenece al usuario mysql, es por este motivo que indiqué que el archivo se guardara en el directorio /tmp.

Como podrán observar, es muy sencillo exportar datos a un archivo, por lo que espero que no tengan ningún problema al hacerlo.

domingo, 25 de mayo de 2008

Manejar transacciones con ADOdb para PHP

La forma de usar transacciones con ADOdb para PHP es muy sencilla.

Lo primero que se deberá de hacer después de crear la conexión, es iniciar la transacción. Posteriormente ejecutar las sentencias sql que queremos que entren dentro de la transacción y verificar si se hicieron correctamente, en caso de no ser así deberemos lanzar una instrucción Rollback, y en caso de que todo estuvo bien, deberemos lanzar una instrucción Commit.

$bd = NewADOConnection('mysql');
$conexion = $bd->Connect("servidor","usuarioBD","contraseniaBD","nombreBD"));
$conexion->BeginTrans();
$insert1 = "INSERT INTO ....";
$insert2 = "INSER INTO ....";

if(!$conexion->Execute($insert1))
$conexion->RollbackTrans();
elseif(!$conexion->Execute($insert2))
$conexion->RollbackTrans();
else
$conexion->CommitTrans();

$conexion->Close();

Como se puede observar, tenemos que ir rastreando los posibles errores de nuestras instrucciones sql para lanzar nuestros Rollback igual que como lo haríamos normalmente con sql.

Afortunadamente esta biblioteca nos facilita un poco más el uso de transacciones gracias al uso de lo que en su página llaman Transacciones Inteligentes.

Las transacciones inteligentes nos permiten iniciar y concluir nuestra transacción sin necesidad de ir rastreando los posibles errores, bastará con usar el método StartTrans() el cual permite iniciar la transacción y poner donde queramos que inicie nuestra transacción el método CompleteTrans(). Este último método, se encarga de verificar si hubo algún error en las instrucciones sql que están dentro de la transacción y, si detecta algún error, entonces lanza automáticamente una instrucción Rollback, en caso contrario lanza una instrucción Commit.

El ejemplo anterior, puede quedar de la siguiente manera:

$bd = NewADOConnection('mysql');
$conexion = $bd->Connect("servidor","usuarioBD","contraseniaBD","nombreBD"));
$conexion->StartTrans();
$insert1 = "INSERT INTO ....";
$insert2 = "INSER INTO ....";

$conexion->Execute($insert1);
$conexion->Execute($insert2);

$conexion->CompleteTrans();
$conexion->Close();

Como podemos observar, es mucho más fácil usar transacciones con esta última forma.

Ahora bien si de todas maneras, necesitamos por alguna razón lanzar una instrucción Rollback en una transacción inteligente, podemos usar el método FailTrans().

$conexion->FailTrans();

Este método le indica al método CompleteTrans() que deberá lanzar un Rollback.

Para finalizar esta entrada, me gustaría mencionar que en los manejadores de bases de datos que he usado (PostgreSQL, Oracle, Sybase y MySQL), las transacciones inteligentes trabajan sin problema con excepción de MySQL, ya que para que funcionen las transacciones inteligentes con este manejador, deberemos especificar el driver mysqlt en lugar de mysql cuando creamos el objeto de conexión.

$bd = NewADOConnection('mysqlt');

Hace mucho use esta opción pero ya no la recordaba, por eso agradezco al joven Alvajandro que me recordó la opción para poder usar este tipo de transacciones con MySQL.

También recuerden que para que funcionen transacciones e integridad referencial en mysql, deberemos crear nuestras tablas con el type=innoDB.

viernes, 23 de mayo de 2008

ADOdb para PHP

Para quienes apenas van empezando a programar en PHP o en su defecto necesitan de alguna biblioteca para conectarse a base de datos que les funcione de la misma manera para diversos manejadores de bases de datos, ADOdb para PHP es una buena alternativa.

Hace ya algunos años el buen JCLTOL me pasó la referencia a esta biblioteca, la he usado con diversos manejadores de bases de datos, entre los que se encuentran PostgreSQL, MySQL, Oracle y Sybase y debo mencionar que me ha funcionado bastante bien. En algunos casos como sybase me surgieron algunos problemitas pero nada que no se pudiera solucionar.

Las principales ventajas que le he encontrado ha esta herramienta son:

  • Podemos conectarnos a diversos manejadores de bases de datos entre los cuales se encuentran: MySQL, PostgreSQL, Interbase, Firebird, Informix, Oracle, MS SQL, Foxpro, Access, ADO, Sybase, FrontBase, DB2, SAP DB, SQLite, Netezza, LDAP, y los genericos ODBC, ODBTP.
  • Usamos casi la misma funciones para todos los manejadores de bases de datos. (Digo casi porque para manipular campos blob, clob hacen algunas diferencias).
  • Permite migrar una aplicación de una base de datos a otra sin tantos problemas. (Esto depende también en gran medida de usar campos y funciones estandar en SQL y no sintaxis especial de cada manejador de base de datos).
  • Cuenta con buena documentación.
  • Permite manejar las sesiones de PHP en nuestra base de datos y no en el directorio /tmp que es el que se encuentra por default.
  • La forma de usarlo es muy sencilla.
  • Cuenta con documentación en español.
  • Permite crear paginaciones.
  • Entre otra muchas otras cosas.

La forma de instalación es muy sencilla. Deberemos bajar el archivo desde su página de descargas y presionar en la opción Download from SourceForge.

Aquí nos aparecerán 3 archivos, uno para compatibilidad entre php 4 y 5, otro para compatibilidad únicamente para php 5 y otro con compatibilidad para python. Deberemos decidir cual bajar.

En mi caso yo bajo el de compatibilidad para php 4 y 5 ya que todavía tenemos que trabajar en algunos casos con php 4.

Una vez que hayan descargado el archivo deberán descomprimirlo, de preferencia en alguno de los directorios de su proyecto para que cuando lo migren vaya incluida esta biblioteca.

La versión en el momento de hacer este documento es la 4.98 y el archivo que descargué fue el adodb489.tgz.

Para descomprimirlo ejecutamos esto:

javoaxian@sky:~$ tar -xzvf adodb489.tgz

Esto nos creará el directorio adodb.

Ahora en nuestros programas donde deseemos conectarnos a alguna base de datos bastará con incluirlo con una instrucción include, include_once, require o require_once.

include("/ruta/adodb/adodb.inc.php");

Para concluir, explicaré como conectarnos a nuestra una base de datos. Esto es muy sencillo, lo primero que haremos será crear un objeto de la conexión especificando el manejador de base de datos que vamos a usar. Para este caso usaremos oracle.

$bd = NewADOConnection('oci8');

Ahora ejecutaremos la instrucción para conectarnos al manejador, pasandole los argumentos de conexión a la base de datos:

$conexion = $bd->Connect("servidor","usuarioBD","contraseniaBD","nombreBD"));

Esto nos debe conectar a la base de datos que especificamos.
Ahora cerrar nuestra conexión, bastará con ejecutar lo siguiente:

$conexion->Close();

En documentos posteriores trataré de mostrar ejemplos de como usar ADOdb para PHP.

jueves, 22 de mayo de 2008

Cargar información a una tabla en MySQL desde un archivo de texto

Muchas veces cuando desarrollamos un sistema, necesitamos cargar información que usamos en muchos de los sistemas que implementamos, como catálogo de estados, delegaciones, etc. y estos catálogos los exportamos en archivos de texto para posteriormente cargarlos en una nueva aplicación.

Para poder hacer esta acción en MySQL necesitaremos usar el comando LOAD DATA dentro del prompt de mysql.

Como primer paso para poder ejecutar este comando necesitamos que el administrador de mysql nos de permisos para ejecutar esta acción. Si contamos con la cuenta de root de mysql, nos loguearemos con dicha cuenta y daremos los permisos globales de FILE como a continuación se muestra:

javoaxian@sky:~$ mysql -u root -p mysql
mysql> GRANT FILE on *.* to 'usuario'@'localhost';

Para ejemplificar habilitaré mi cuenta en mysql.

mysql> GRANT FILE on *.* to 'javoaxian'@'localhost';

Los privilegios de FILE no están incluidos cuando damos permisos GRANT ALL por lo que se deberán asignar por aparte los privilegios de FILE a los usuario que deseemos que usen dichos privilegios.

Ahora podremos usar con la cuenta que especificamos tanto el comando LOAD DATA (para cargar información de archivos a una tabla) como el comando SELECT ... INTO OUTFILE (para mandar el resultado de una consulta a un archivo).

Para cargar el archivo de texto a una tabla, deberán de verificar que la tabla cuente con el mismo número de campos que el archivo de texto, por ejemplo si van a cargar un catálogo de países a lo mejor el archivo cuenta con una columna de id's y otra con los nombres de los países, por lo tanto, en nuestra base de datos deberemos tener creada la tabla pais con un campo que corresponda al id y otro para el nombre.

Para ejemplificar supondremos que nuestro archivo de texto tiene separados los campos con tabulador.

Ahora para cargar nuestro archivo de texto, por ejemplo paises.txt a la tabla pais, ingresaremos a nuestra base de datos con nuestra cuenta:

javoaxian@sky:~$ mysql -u javoaxian -p javoaxian

Una vez en nuestra base de datos ejecutaremos lo siguiente para cargar el archivo a nuestra tabla:

mysql> LOAD DATA INFILE '/ruta/archivo/paises.txt' INTO TABLE pais FIELDS TERMINATED BY '\t';

Esto cargará toda la información que tengamos en el archivo paises.txt a nuestra tabla pais.