miércoles, 9 de febrero de 2011

0007 – Instalar pldebugger en postgreSQL bajo Windows

Pldebugger es un plugin para depurar scripts plpgsql en PostgreSQL. Usando el "one-click-installer" de postgreSQL no hace falta bajarse el plugin y compilarlo para que funcione. El paquete de instalación "one-click-installer" ya se encarga de hacerlo por nosotros.

En este artículo voy a explicar cómo se debe configurar el pldebugger bajo Windows una vez instalado PostgreSQL.

Descripción técnica:

S.O.

Windows XP SP3

Versión de postgreSQL

9.0



  • Abrir explorador de Windows e ir a la ruta de instalación de postgreSQL: ..\PostgreSQL\9.0\data


    Image Hosted by ImageShack.usBy xdrtas_001 at 2011-02-09



  • En la carpeta "data", abrir el archivo de configuración: "postgresql.conf" con el editor de preferencia, para este caso uso el block de notas clásico.

    Image Hosted by ImageShack.usBy xdrtas_001 at 2011-02-09



  • Buscar la opción "shared_preload_libraries".

    Image Hosted by ImageShack.usBy xdrtas_001 at 2011-02-09



  • Colocar la siguiente ruta como se muestra a continuación: shared_preload_libraries = '$libdir/plugins/plugin_debugger.dll' #Guardar los cambios.

    Image Hosted by ImageShack.usBy xdrtas_001 at 2011-02-09



  • Detener PostgreSQL y volverlo a iniciar.


  • Iniciar pgAdminIII y buscar la Base de datos donde se requiera el uso del debugger.


  • Como se puede observar en la siguiente imagen, la opción "Debugging" está inhabilitado pese a que se tiene seleccionado la función a la cual se le va aplicar el debugger, que en este caso, la función es "modfechserial(bigint, date, date), el siguiente paso es habilitar la opción "Debugging".


    Image Hosted by ImageShack.us
    By xdrtas_001 at 2011-02-09




  • Abrir una ventana de Query y hacer click en "Abrir" o "Open" según el idioma en que esté configurado el pgAdminIII.


    Image Hosted by ImageShack.us
    By xdrtas_001 at 2011-02-09




  • Ir a la siguiente ruta: ..\PostgreSQL\9.0\share\contrib y buscar el archivo pldbgapi.sql.


    Image Hosted by ImageShack.us
    By xdrtas_001 at 2011-02-09



  • Ejecutar el script cargado.

    Image Hosted by ImageShack.us
    By xdrtas_001 at 2011-02-09




  • Como se puede observar en la siguiente imagen, la opción de "Debugging" ya está habilitado para las funciones de esa base de datos.

    Image Hosted by ImageShack.us
    By xdrtas_001 at 2011-02-09



Puntos a considerar:


  1. Al abrir el archivo de "postgresql.conf" es importante recordar quitar el símbolo de numeral "#"al comienzo de la línea shared_preload_libraries.
  2. Una vez hecha esa modificación hay que reiniciar el servidor de base de datos.
  3. Si al ejecutar el script "pldbgapi.sql" no aparece habilitado la opción "Debugging" entonces reiniciar de nuevo el servidor.
  4. La opción de "Debugging" sólo se habilitará cuando se seleccione una de las funciones.
  5. No hace falta bajar ningún archivo extra, todo lo necesario para habilitar el "Debugging" se encuentra en el instalador "one-click-installer".

Hecho por David Lastra – XDRTAS

Un cordial saludo.

lunes, 16 de agosto de 2010

0006 Ajax – PHP – PostgreSQL II



En este segundo tutorial sobre AJAX – PHP – PostgreSQL se van a tratar los siguientes puntos:

  1. Mostrar el contenido de la página "index.html" dependiendo de un parámetro seleccionado por el usuario.

  2. Enviar un parámetro a través de AJAX al script de PHP por medio de POST.

  3. Guardar el resultado de la consulta SQL en formato XML y leer el contenido del resultado mediante AJAX.

  4. Leer etiquetas HTML contenidos en el XML resultante.
  5. Leer caracteres especiales HTML, (á, é, í, ó, ú), contenidos en el archivo XML dentro de los etiquetas HTML.
Código de la tabla ajax:
 CREATE TABLE ajax  
   
 (  
   
 id serial NOT NULL,  
   
 nombre character varying(50),  
   
 apellido character varying,  
   
 cedula character varying(8),  
   
 sexo boolean,  
   
 CONSTRAINT pid PRIMARY KEY (id)  
   
 )  
   
 WITH (  
   
 OIDS=FALSE  
   
 );  
   
 ALTER TABLE ajax OWNER TO postgres;  
   
   
   
 INSERT INTO ajax (id, nombre, apellido, cedula, sexo) VALUES (1, 'David', 'Lastra', '14852152', true);  
   
 INSERT INTO ajax (id, nombre, apellido, cedula, sexo) VALUES (2, 'David', 'Lastra', '14852152', true);  
   
 INSERT INTO ajax (id, nombre, apellido, cedula, sexo) VALUES (3, 'David', 'Lastra', '14852152', true);  
   
 INSERT INTO ajax (id, nombre, apellido, cedula, sexo) VALUES (4, 'David', 'Lastra', '14852152', true);  
   
 INSERT INTO ajax (id, nombre, apellido, cedula, sexo) VALUES (5, 'David', 'Lastra', '14852152', true);  
   
 INSERT INTO ajax (id, nombre, apellido, cedula, sexo) VALUES (6, 'Miss', 'Universo', '11111111', false);  
   
 INSERT INTO ajax (id, nombre, apellido, cedula, sexo) VALUES (7, 'Miss', 'Universo', '11111111', false);  
   
 INSERT INTO ajax (id, nombre, apellido, cedula, sexo) VALUES (8, 'Miss', 'Universo', '11111111', false);  
   
 INSERT INTO ajax (id, nombre, apellido, cedula, sexo) VALUES (9, 'Miss', 'Universo', '11111111', false);  
   
 INSERT INTO ajax (id, nombre, apellido, cedula, sexo) VALUES (10, 'Miss', 'Universo', '11111111', false);  
   
 INSERT INTO ajax (id, nombre, apellido, cedula, sexo) VALUES (11, 'Miss', 'Universo', '11111111', false);  
   
 INSERT INTO ajax (id, nombre, apellido, cedula, sexo) VALUES (12, 'David', 'Lastra', '14852152', true);  
   
 INSERT INTO ajax (id, nombre, apellido, cedula, sexo) VALUES (13, 'David', 'Lastra', '14852152', true);  
   
 INSERT INTO ajax (id, nombre, apellido, cedula, sexo) VALUES (14, 'David', 'Lastra', '14852152', true);  
   
 INSERT INTO ajax (id, nombre, apellido, cedula, sexo) VALUES (15, 'David', 'Lastra', '14852152', true);  
   
 INSERT INTO ajax (id, nombre, apellido, cedula, sexo) VALUES (16, 'Miss', 'Universo', '11111111', false);  
   
 INSERT INTO ajax (id, nombre, apellido, cedula, sexo) VALUES (17, 'Miss', 'Universo', '11111111', false);  
   
 INSERT INTO ajax (id, nombre, apellido, cedula, sexo) VALUES (18, 'Miss', 'Universo', '11111111', false);  
   
 INSERT INTO ajax (id, nombre, apellido, cedula, sexo) VALUES (19, 'Miss', 'Universo', '11111111', false);  
   
 INSERT INTO ajax (id, nombre, apellido, cedula, sexo) VALUES (20, 'Miss', 'Universo', '11111111', false);  
   
 INSERT INTO ajax (id, nombre, apellido, cedula, sexo) VALUES (21, 'Miss', 'Universo', '11111111', false);  
La primera parte consta de la creación de la tabla con el nombre de "ajax" en minúsculas. La segunda parte es la inserción de datos para trabajar con los mismos desde los scripts.

Código index.html:
 <!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>Prueba de [ AJAX - PHP - POSTGRESQL II]</title>  
  <script language="javascript" src="js/ajax.js" type="application/javascript"></script>  
 </head>  
 <body style="background-color:#366;">  
 <table border="0" style="color:white; background-color:#000;" align="center">  
 <tr>  
 <td colspan="2" align="center">  
 <strong>Prueba de:</strong><span style="color:#F00; font-weight:bolder;">[ AJAX - PHP - POSTGRESQL II]</span>  
 </td>  
 </tr>  
 <tr>  
 <td colspan="2">  
      <div id="contenido" style="color:#1FE4EF; font-family:'Times New Roman', Times, serif;"></div>  
 </td>  
 </tr>  
 <tr>  
 <td align="center">  
 <form action="#" name="frmSexo">  
 <select name="sexo"><option value="true" >Hombre</option><option value="false">Mujer</option></select>  
 </form>  
 <hr />  
      <a href="#" onclick="javascript:fDatos('contenido',frmSexo.sexo.options[frmSexo.sexo.selectedIndex].value ,'ajax.php');" style="color:#0F0; text-decoration:none;">[ Mostrar datos ]</a>  
 </td>  
 <td align="center">  
      <a href="#" onclick="javascript:fBorrar('contenido');" style="color:#F00; text-decoration:none;">[ Limpiar contenido ]</a>  
 </td>  
 </tr>  
 </table>  
 </body>  
 </html>  
Las etiquetas HTML más importantes que se muestran arriba están resaltadas en colores.

  1. <script language>: para indicar donde se encuentra el archivo javascript con las funciones a usar.
  2. <div id="contenido">: el contenido de este div es el que se va a modificar por medio de las funciones "fDatos" y "fBorrar" de javascript.
  3. <form name="frmSexo">: formulario con un campo select para seleccionar los datos de las personas de la tabla "ajax" según el sexo.
  4. <a href="#" onclick="javascript:fDatos>: Al hacer "click" en éste link se inicia el proceso para la carga de datos mediante AJAX en el DIV correspondiente.
  5. <a href="#" onclick="javascript:fBorrar>: Al hacer "click" en éste link se borra el contenido del DIV.
  6. fDatos('contenido',frmSexo.sexo.options[frmSexo.sexo.selectedIndex].value ,'ajax.php');:
    1. fDatos: nombre de la función javascript.
    2. 'contenido': nombre de la etiqueta DIV donde se va a modificar el contenido.
    3. frmSexo.sexo.options[].value: El valor seleccionado por el usuario en el menú desplegable, (frmSexo.sexo.options à es un array para poder acceder a los posibles valores), los posibles valores para este caso son: true - "Hombre", false – "Mujer".
    4. frmSexo.sexo.selectedIndex: Sirve para indicar cuál es la opción actualmente seleccionada por el usuario. El valor seleccionado del menú desplegable, (0 - true, 1 - false).
    5. frmSexo.sexo.options[ frmSexo.sexo.selectedIndex ].value = true o false.
  7. fBorrar('contenido'): Función que se encarga de borrar el contenido al DIV seleccionado.
Código ajax.js:
1:  /*------------------------------------------------------*/  
2:  //Función para crear el objeto Ajax.          //  
3:  /*------------------------------------------------------*/  
4:  function nuevoAjax()  
5:  {  
6:   var xmlhttp=false;  
7:   try  
8:   {  
9:    xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");  
10:   }  
11:   catch (e)  
12:   {  
13:    try  
14:    {  
15:     xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");  
16:    }  
17:    catch (e)  
18:    {  
19:     xmlhttp = false;  
20:    }  
21:   }  
22:   if (!xmlhttp && typeof XMLHttpRequest!='undefined')  
23:   {  
24:    xmlhttp = new XMLHttpRequest();  
25:   }  
26:   return xmlhttp;  
27:  }  
28:  /*------------------------------------------------------*/  
29:  //id: id del control div que va a recibir los datos.  //  
30:  //sexo: verdadero o falso, filtro booleando para la   //  
31:  //carga de datos según el campo sexo.          //  
32:  //url: Dirección url de la página donde se       //  
33:  //obtiene los datos.                  //  
34:  /*------------------------------------------------------*/  
35:  function fDatos(id, sexo, url)  
36:  {  
37:   var objDiv = document.getElementById(id);  
38:   var objXML = null;  
39:   var objTBL = null;  
40:   if (sexo == 'true')  
41:    sexo = true;  
42:   else  
43:    sexo = false;  
44:   ajax = nuevoAjax();  
45:   ajax.open("POST", url, true);  
46:   ajax.onreadystatechange = function()  
47:   {  
48:    switch (ajax.readyState)  
49:    {  
50:    case 0:  
51:     objDiv.innerHTML = 'Error 0. No se ha abierto la comunicaci&oacute;n.';  
52:     break;  
53:    case 1:  
54:     objDiv.innerHTML = 'Por favor, espere. Cargando...';  
55:     break;  
56:    case 2:  
57:     objDiv.innerHTML = 'Petici&oacute;n cargada, esperando respuesta del servidor...';  
58:     break;  
59:    case 3:  
60:     objDiv.innerHTML = '';  
61:     break;  
62:    case 4:  
63:     if(ajax.status == 200)  
64:     {  
65:       try  
66:       {  
67:       objDiv.innerHTML = "Datos a mostrar... <hr />";  
68:       objXML = ajax.responseXML;  
69:       objTBL = objXML.getElementsByTagName('tabla');  
70:       objDiv.innerHTML += objTBL[0].firstChild.nodeValue;  
71:       objDiv.innerHTML += "<hr />";  
72:       }  
73:       catch (e)  
74:       {  
75:        objDiv.innerHTML += e.toString() + " Error al recibir datos de archivo XML...";  
76:       }  
77:     }  
78:     else  
79:     {  
80:       objDiv.innerHTML = 'Error 200';  
81:     }  
82:     break;  
83:    }  
84:   }  
85:   ajax.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");  
86:   ajax.send("sexo="+sexo);  
87:  }  
88:  /*------------------------------------------------------*/  
89:  //Borrar los datos de la celda en la página web...   //  
90:  /*------------------------------------------------------*/  
91:  function fBorrar(id)  
92:  {  
93:   document.getElementById(id).innerHTML = "";  
94:  }  
  1. Función nuevoAjax: Se encarga de crear el objeto AJAX para poder hacer la carga de datos de forma asincrónica.
  2. Función fDatos:
    1. Id = id del objeto DIV que se va a manipular.
    2. Sexo = booleano, filtro para obtener datos según la selección hecha por el usuario mediante el control SELECT del formulario de la página "index.html".
    3. url = página que se va a llamar para obtener los datos deseados mediante AJAX, en este caso la página a llamar es "ajax.php".
    4. El valor de los parámetros es colocado en la llamada a la función fDatos en la página de "index.html".
    5. objXML = ajax.responseXML;: Indica que el tipo de respuesta vendrá en formato XML.
    6. objTBL = objXML.getElementsByTagName('tabla');: Se asigna a la variable objTBL el contenido de la etiqueta "tabla" del archivo XML. "objTBL" es un array del tamaño de todas las etiquetas con el nombre "tabla" que existan en el archivo XML. (En el siguiente apartado se verá el contenido del archivo XML).
    7. objDiv.innerHTML += objTBL[0].firstChild.nodeValue;: Se accede al valor del primer elemento de la variable "objTBL" y se muestra en la etiqueta DIV correspondiente, para este caso 'contenido'.
    8. ajax.send("sexo="+sexo);: En el método "send" del objeto "ajax" se introduce el parámetro que se va a enviar al script "ajax.php". En el caso de que se quiera enviar más parámetros, la cadena de construcción queda con el siguiente formato: [ajax.send("nomvar1="+valvar1+"&nomvar2="+valvar2+"&nomvar3="+valvar3 + … +"&nomvarN="+valvarN)]. Hay que usar el carácter "&" para concatenar las variables.
    9. "nomvar" acrónimo de nombre de variable. "valvar" acrónimo de valor de variable.
  3. Función fBorrar: Se encarga de limpiar el contenido de la etiqueta DIV.
Código ajax.php:
1:  <?php  
2:  $conbd = pg_connect("host=localhost port=5432 dbname=prueba user=tuusuario password=tucontraseña") or die(pg_last_error());  
3:  $sql = "SELECT id, nombre, apellido, cedula FROM ajax WHERE sexo = " . $_POST['sexo'] . ";";  
4:  $res = pg_query($conbd, $sql);  
5:  if($res)  
6:  {  
7:  if(pg_num_rows($res)>0)  
8:  {  
9:  header("Content-Type: text/xml");  
10:  $xml = "<?xml version='1.0' encoding='ISO-8859-1' ?>\n";  
11:  $xml .= "<datos>\n";  
12:  $xml .= "<tablas>\n";  
13:  $xml .= "<tabla>";  
14:  $xml .= "<!--<table border=\"1\">\n";  
15:  $xml .= "<tr>\n";  
16:  $xml .= "<td align=\"center\"> [ ID ]      </td>\n";  
17:  $xml .= "<td align=\"center\"> [ NOMBRE ]    </td>\n";  
18:  $xml .= "<td align=\"center\"> [ APELLIDO ]   </td>\n";  
19:  $xml .= "<td align=\"center\"> [ C&#201;DULA ] </td>\n";  
20:  $xml .= "</tr>\n";  
21:  while($val = pg_fetch_array($res))  
22:  {  
23:  $xml .= "<tr><td>" . $val[0] . "</td><td>" . $val[1] . "</td><td>" . $val[2] . "</td><td>" . $val[3] . "</td></tr>\n";  
24:  }  
25:  $xml .= "</table>-->";  
26:  $xml .= "</tabla>\n";  
27:  $xml .= "</tablas>\n";  
28:  $xml .= "</datos>\n";  
29:  echo $xml; //escribe, en resultado, un archivo XML con los datos obtenidos mediante la consulta…  
30:  }  
31:  pg_free_result($res);  
32:  }  
33:  pg_close($conbd);  
34:  ?>  

En el script "ajax.php" es donde se va a crear el contenido XML con los datos que se obtienen de la consulta SQL. Se describe, a continuación, los pasos del script "ajax.php":
  1. Cadena de conexión para acceder a la base de datos con el nombre de "prueba", ($conbd: ID de conexión).
  2. Cadena de consulta que tiene por filtro la variable "sexo" que viene por POST desde AJAX y se ejecuta sobre la tabla "ajax", ($sql - $_POST['sexo']).
  3. Ejecución de la consulta, ($res = pg_query($conbd, $sql);).
  4. Si la consulta es correcta, entonces…
  5. Si la consulta ha traído más de 0 filas entonces…
  6. Se define la cabecera del archivo con el comando "header". "Content-Type: text/xml", define los datos que siguen como contenido XML.
  7. La primera línea del archivo XML define la versión y la codificación de caracteres.
  8. Primera etiqueta: <datos>\n.
  9. Segunda etiqueta: <tablas>\n.
  10. Tercera etiqueta: <tabla> + código embebido HTML (Siguiente punto a explicar) + </tabla>\n.
  11. Cerrar segunda etiqueta: </tablas>\n.
  12. Cerrar primera etiqueta: </datos>.
  13. echo $xml;: Mostrar el resultado.
  14. Limpiar la consulta, (pg_free_result($res);).
  15. Cerrar la conexión a la base de datos, (pg_close($conbd);).
Código embebido HTML:
El código HTML del script "ajax.php" está embebido en el XML resultante del script "ajax.php". Para que se puedan interpretar los tags HTML, el HTML embebido debe empezar como si se tratase como un comentario, como se muestra a continuación: <!—Introducir código HTML aquí. -->. Esto permite la distinción entre las etiquetas XML y las etiquetas HTML.
Todos las etiquetas HTML entre de "<!--" y "-->" serán ignorados como etiquetas XML pero no como etiquetas HTML, lo que permite recuperar el contenido HTML sin que entre en conflicto con las etiquetas XML. Es muy importante que se tenga presente lo siguiente: XML no puede leer, distinguir ni interpretar código HTML, si dentro de un archivo XML se encuentra una etiqueta HTML como por ejemplo "<br>" o "<table>", XML lo tomará como parte del formato del documento, no como una etiqueta HTML.
  1. "<!--<table border=\"1\">\n";: Inicio del comentario XML e inicio de la etiqueta <table> para definir la tabla con los resultados a mostrar.
  2. "<tr>\n";: Inicio de la primera fila que contiene la cabecera de la tabla.
  3. "<td align=\"center\">[ ID ]</td>\n";: Celda ID.
  4. "<td align=\"center\">[ NOMBRE ]</td>\n";: Celda Nombre.
  5. "<td align=\"center\">[ APELLIDO ]</td>\n";: Celda Apellido.
  6. "<td align=\"center\">[ C&#201;DULA ]</td>\n";: Celda Cédula.
  7. "</tr>\n";: Fin de la cabecera.
  8. while($val = pg_fetch_array($res)): Bucle para obtener todas las filas devueltas por la consulta.
  9. "<tr><td>" . $val[0] . "</td><td>" . $val[1] . "</td><td>" . $val[2] . "</td><td>" . $val[3] . "</td></tr>\n";: Fila y celdas con los datos obtenidos de la consulta.
  10. "</table>-->";: Cierre del tag HTML "</table>" y cierre de la línea de comentario XML "-->".
A continuación se muestra como se vería el XML resultante, desde mozilla firefox, al ejecutar el script "ajax.php" con el parámetro "true" en la consulta SQL.

1:  <?xml version="1.0" encoding="ISO-8859-1"?>  
2:  <datos>  
3:  <tablas>  
4:  <tabla><!--<table border="1">  
5:  <tr>  
6:  <td align="center"> [ ID ]      </td>  
7:  <td align="center"> [ NOMBRE ]    </td>  
8:  <td align="center"> [ APELLIDO ]   </td>  
9:  <td align="center"> [ C&#201;DULA ] </td>  
10:  </tr>  
11:  <tr><td>1</td><td>David</td><td>Lastra</td><td>14852152</td></tr>  
12:  <tr><td>2</td><td>David</td><td>Lastra</td><td>14852152</td></tr>  
13:  <tr><td>3</td><td>David</td><td>Lastra</td><td>14852152</td></tr>  
14:  <tr><td>4</td><td>David</td><td>Lastra</td><td>14852152</td></tr>  
15:  <tr><td>5</td><td>David</td><td>Lastra</td><td>14852152</td></tr>  
16:  <tr><td>12</td><td>David</td><td>Lastra</td><td>14852152</td></tr>  
17:  <tr><td>13</td><td>David</td><td>Lastra</td><td>14852152</td></tr>  
18:  <tr><td>14</td><td>David</td><td>Lastra</td><td>14852152</td></tr>  
19:  <tr><td>15</td><td>David</td><td>Lastra</td><td>14852152</td></tr>  
20:  </table>--></tabla>  
21:  </tablas>  
22:  </datos>  

Caracteres especiales HTML:
Dentro de las etiquetas XML se pueden encontrar fallos a la hora de usar entidades por nombre para visualizar caracteres especiales HTML, la solución pasa por usar su equivalente entidad numérica.
Si hay errores al visualizar caracteres especiales HTML dentro de las etiquetas XML como entidades por nombre, "&aacute;", siempre se puede recurrir a su equivalente entidad numérica. Por ejemplo, la palabra "Cédula" en HTML se podría escribir de la siguiente manera "C&eacute;dula", pero, con la codificación de caracteres actual "&eacute;" no funciona dentro del XML, para solucionar este inconveniente se puede recurrir a su entidad numérica "&#201;" y quedaría de la siguiente manera "C&#201;dula".
Usando la correspondiente entidad numérica se puede solventar los fallos de interpretación de las entidades por nombre de las etiquetas HTML en el contenido XML.
A continuación adjunto el link con las tablas de conversiones entre entidades por nombre y su correspondencia a entidades numéricas: Tablas de conversión
Resumen:
En este artículo se han cubierto los siguientes puntos:
  • Paso de parámetros desde AJAX por POST a PHP usando el método "send".
  • Según el parámetro seleccionado el contenido a mostrar cambia dentro de la página HTML.
  • Lectura HTML embebido en XML por medio de javascript.
  • Guardar el resultado obtenido en la consulta SQL a formato XML.
  • Interpretar caracteres especiales HTML embebidos en XML mediante el uso de entidades numéricas en el caso de que falle la interpretación de entidades por nombre.
Si tienen alguna duda o algo constructivo que añadir, pueden dejar un comentario o enviarme un e-mail.
Un cordial saludo.
Firma: XDRTAS

martes, 11 de mayo de 2010

0005 Excel – PostgreSQL III


Para este artículo se van a usar las tres librerías para el manejo de Excel desde python, estas librerías son: xlrd, xlwt, xlutils.
El siguiente diagrama explica lo que se quiere conseguir con el procedimiento almacenado:





  • Hoja de Excel "original.xls", (Crear este libro antes de ejecutar el procedimiento almacenado):
    • Crear la hoja de Excel con los siguientes campos:


A
B
C
D
1David
100
0
100
2Jorge
100
1
99
3Arturo
100
2
98
4Sylvia
100
3
97
5Carolina
100
4
96
6Graciela
100
5
95
7Fernando
100
6
94
8Elena
100
7
93
9Carlos
100
8
92
10Daniela
100
9
91

  • Crear la tabla "excel" en la base de datos:
 CREATE TABLE excel  
 (  
 campo1 character varying(80),  
 campo2 integer  
 )  
 WITH (  
 OIDS=FALSE  
 );  
 --Sin registros…  

  • Procedimiento almacenado:
 CREATE OR REPLACE FUNCTION f_proceso_completo(nombre character varying, copiar character varying, tabla character varying, actualizar smallint)  
   
 RETURNS integer AS  
   
 $BODY$  
   
 #***************************************************************************************  
   
 #Creado por:  David A. Lastra N.  
   
 #Alias:    xdrtas  
   
 #Fecha:    10/05/2010  
   
 #Objetivo:    Leer celdas desde libro de excel, guardar los datos en la tabla y actualizar el libro de excel...  
   
 #***************************************************************************************  
   
   
   
 #Llamar a las librerías que entran en juego para porder realizar el proceso...  
   
 from xlrd import open_workbook  
   
 from xlwt import Formula, XFStyle  
   
 from xlutils.copy import copy  
   
   
   
 #Abrir el libro para leer las celdas...  
   
 lb = open_workbook(nombre)  #lb = leer libro...  Abrir el libro...  
   
 lh = lb.sheet_by_index(0)  #lh = leer hoja...  para leer la primera hoja...  
   
 lc = copy(lb)      #lc = libro copia...  copiar el libro...  
   
 eh = lc.get_sheet(0)    #eh = escribir hoja...  escribir en la primera hoja...  
   
   
   
 #Borrar los datos anteriores de la tabla...  
   
 plpy.execute("DELETE FROM "+tabla+";")  
   
   
   
 #Leer el libro para guardar los datos de las celdas en la tabla "excel"...  
   
 for fila_ID in range(lh.nrows):  
   
 uno = lh.cell(fila_ID,0).value    #El valor de la celda fila_ID, columna 0 o "A"...  
   
 dos = int(lh.cell(fila_ID,2).value)  #El valor de la celda fila_ID, columna 2 o "C"...  
   
 sql = "INSERT INTO %s(campo1, campo2) VALUES ('%s', %d::int);" % (tabla, uno, dos)  
   
 plpy.execute(sql)      #Insertar los valores de las celdas en la tabla "nombre"...  
   
   
   
 #Formato de celda numérico...  
   
 formato = XFStyle()  
   
 formato.num_format_str = '0'  
   
   
   
 #Leer los datos de la tabla y grabar los datos en las celdas correspondientes...  
   
 datos = plpy.execute("SELECT campo1, campo2 FROM "+tabla+";")  
   
 fila = 0  
   
 for campo in datos:          #Escribir en todas las filas de la columna 0 o "A" y columna 2 o "C"...  
   
 eh.write(fila,0,campo['campo1'])    #Escribir el valor de campo1 en la celda "A"...  
   
 eh.write(fila,2,int(campo['campo2']),formato)  #Escribir el valor del campo2 en la celda "C"...  
   
 fila = fila + 1          #Pasar a la siguiente fila...  
   
   
   
 #Guardar en las celdas de la columna 1 o "B" la formula: "=Cn+Dn" donde "n" es el valor que va desde 1 hasta n...  
   
 for i, celda in enumerate(lh.col(1)):          #Escribir en todas las filas de la columna 1 o "B"...  
   
 eh.write(i,1,Formula('C'+str(i+1)+'+D'+str(i+1)),formato)  #Escribir la formula de (Cn+ Dn) en la columna 1 o "B"...  
   
   
   
 #Guardar en las celdas de la columna 3 o "D" los valores de las celdas del libro abierto...  
   
 for i, celda in enumerate(lh.col(3)):    #Escribir en todas las filas de la columna 3 o "D"...  
   
 eh.write(i,3,celda.value,formato)  #Los datos se obtienen de las celdas del libro "lb" hoja "lh"...  
   
   
   
 #Actualizar el libro y crear copia, de lo contrario, sólo crear copia...  
   
 if actualizar == 1:  
   
 lc.save(nombre)  
   
 lc.save(copiar)  
   
 else:  
   
 lc.save(copiar)  
   
   
   
 return 1;  
   
 $BODY$  
   
 LANGUAGE 'plpythonu' VOLATILE  
   
 COST 100;  

  1. El procedimiento recibe cuatro valores:
    1. Ruta del archivo a copiar/Actualizar.
    2. Ruta del archivo que será la copia del original.
    3. Nombre de la tabla donde se van a guardar/recuperar los datos.
    4. Valor para indicar si se quiere actualizar el archivo o si sólo se quiere crear una copia.
  2. from xlrd import open_workbook: Abrir el archivo para la lectura de las celdas.
  3. from xlwt import Formula, XFStyle: Preparar la escritura para añadir fórmulas y formatos a las celdas.
  4. from xlutils.copy import copy: Crear una copia virtual del archivo para actualizar los datos de las celdas.
  5. lb = open_workbook(nombre): Abrir el libro para leer las celdas.
  6. lh = lb.sheet_by_index(0): Leer las celdas de la primera hoja.
  7. lc = copy(lb): Crear una copia del libro abierto para actualizar las celdas.
  8. eh = lc.get_sheet(0): Obtener acceso a la primera hoja para escribir en las celdas.
  9. plpy.execute("DELETE FROM "+tabla+";"): Borrar los datos de la tabla "excel".
  10. for fila_ID in range(lh.nrows):: Iniciar bucle for para cada uno de las filas.
  11. uno = lh.cell(fila_ID,0).value: Obtener los datos de las celdas de la columna "A".
  12. dos = int(lh.cell(fila_ID,2).value): Obtener los datos de las celdas de la columna "C".
  13. sql = "INSERT INTO %s(campo1, campo2) VALUES ('%s', %d::int);" % (tabla, uno, dos): Cadena SQL para insertar los datos en la tabla "excel".
  14. plpy.execute(sql): Ejecutar la consulta, aquí finaliza los comandos internos de este bucle.
  15. formato = XFStyle(): Para establecer el formato de las celdas a numérico sin decimales, en este caso, para las celdas de las columnas "B", "C" y "D", ya que "A" contiene caracteres y por eso el formato de ésta columna no se modifica.
  16. formato.num_format_str = '0': Formato de las celdas numérico sin decimales.
  17. datos = plpy.execute("SELECT campo1, campo2 FROM "+tabla+";"): Leer los datos de la tabla "excel".
  18. fila = 0: Para ir moviendo el cursor entre las filas de las columnas.
  19. for campo in datos:: Bucle para leer los datos obtenidos de la consulta a la tabla "excel".
  20. eh.write(fila,0,campo['campo1']): Escribir los datos en las celdas de la columna "A".
  21. eh.write(fila,2,int(campo['campo2']),formato): Escribir los datos en las celdas de la columna "C" con el formato numérico sin decimal.
  22. fila = fila + 1: Avanzar a la siguiente fila.
  23. for i, celda in enumerate(lh.col(1)):: Bucle para escribir en cada una de las celdas de la columna "B".
  24. eh.write(i,1,Formula('C'+str(i+1)+'+D'+str(i+1)),formato): Escribir en cada celda la fórmula "Cn+Dn" con formato numérico sin decimal.
  25. for i, celda in enumerate(lh.col(3)):: Bucle para escribir en cada una de las celdas de la columna "D".
  26. eh.write(i,3,celda.value,formato): Escribir en cada celda los valores tomados del libro "original.xls".
  27. if actualizar == 1:: Si Actualizar es igual a 1, entonces.
  28. lc.save(nombre): Actualizar el libro "original.xls".
  29. lc.save(copiar): Crear una copia del libro "original.xls" con el nombre de "copia.xls".
  30. else:: Si actualizar es distinto de 1, entonces.
  31. lc.save(copiar): Crear una copia del libro "original.xls" con el nombre de "copia.xls".
  32. return 1;: Fin del procedimiento.

  • Ejecutar el procedimiento almacenado:
 SELECT f_proceso_completo('C:/Users/xdrtas/Documents/Documentos/test/original.xls','C:/Users/xdrtas/Documents/Documentos/test/copia.xls','excel',1::smallint);  
  • Puntos a destacar en este procedimiento almacenado:
    • El procedimiento está habilitado para la lectura del libro de Excel.
    • El procedimiento está habilitado para la escritura del libro de Excel.
    • Hay tres fuentes de datos:
      • Datos obtenidos por consulta a la tabla "excel", (líneas 20 y 21).
      • Datos escritos directamente, (línea 24), el programador puede quitar la fórmula e introducir los datos que desee.
      • Datos obtenidos desde el libro abierto, (línea26).
    • El procedimiento está habilitado para el cambio de formato de las celdas mediante el módulo XFStyle().

Como se puede observar, en este procedimiento se hacen todas las operaciones disponibles que permiten las librerías xlrd, xlwt, xlutils.
  • Las operaciones de lectura de celdas viene dado por la librería xlrd.
  • Las operaciones de escritura de celdas viene dado por la librería xlwt.
  • Librería xlutils, para habilitar la actualización del libro mediante una copia virtual del libro abierto para lectura.
Importante: Es muy importante tener los permisos de lectura y escritura en la ruta donde se va a trabajar con los documentos de Excel, si los permisos no están habilitados para el usuario de postgres que se encarga de la ejecución del/los procedimiento/s entonces el/los procedimiento/s van a fallar.
Un cordial saludo.
Firma: XDRTAS


lunes, 3 de mayo de 2010

0004 Excel – PostgreSQL II

Este es el segundo artículo para trabajar con postgreSQL y Excel, si quieren ver el primero pueden seguir este link: 0003 excel - postgresql.

En esta segunda parte se muestra cómo escribir los datos obtenidos mediante una consulta a una tabla de postgreSQL para poder guardar esos datos en un documento de Excel.
La librería que se va a usar para escribir datos en una hoja de Excel se llama "xlwt".






Lo primero que se tiene que hacer, es crear la tabla que contiene los datos. Aquí está el código de la tabla:
CREATE TABLE excel
(
campo1 character varying(20),
campo2 character varying(20)
)
WITH (
OIDS=FALSE
);
ALTER TABLE excel OWNER TO postgres;

INSERT INTO excel (campo1, campo2) VALUES ('David', '0.0');
INSERT INTO excel (campo1, campo2) VALUES ('Jorge', '1.0');
INSERT INTO excel (campo1, campo2) VALUES ('Arturo', '2.0');
INSERT INTO excel (campo1, campo2) VALUES ('Sylvia', '3.0');
INSERT INTO excel (campo1, campo2) VALUES ('Carolina', '4.0');
INSERT INTO excel (campo1, campo2) VALUES ('Graciela', '5.0');
INSERT INTO excel (campo1, campo2) VALUES ('Fernando', '6.0');
INSERT INTO excel (campo1, campo2) VALUES ('Elena', '7.0');
INSERT INTO excel (campo1, campo2) VALUES ('Carlos', '8.0');
INSERT INTO excel (campo1, campo2) VALUES ('Daniela', '9.0');

El siguiente paso es el procedimiento almacenado hecho en "plpython":
CREATE OR REPLACE FUNCTION fescribirexcel() RETURNS text AS
$BODY$
from xlwt import Workbook
libro = Workbook()
hoja = libro.add_sheet('Informex')
datos = plpy.execute("SELECT * FROM excel")
fila = 0
for campo in datos:
hoja.write(fila,0,campo['campo1'])
hoja.write(fila,1,campo['campo2'])
fila = fila + 1
libro.save("C:/prueba.xls")
return "Funciona"
$BODY$
LANGUAGE 'plpythonu' VOLATILE;

El procedimiento "fescribirexcel()" hace lo siguiente:
  1. Llamar a la librería xlwt e importar el módulo Workbook.
  2. Asignar el nuevo Workbook a la variable "libro", esto significa que libro se convierte en un objeto "libro de Excel".
  3. Asignar a la variable "hoja" una nueva hoja con el nombre de "Informe".
  4. "datos" contendrá los datos obtenidos por medio de la consulta a la tabla "excel".
  5. "fila" guarda el número de fila donde se quiere guardar los datos.
  6. Se crea un bucle para recorrer los datos obtenidos por medio de la consulta.
  7. "hoja.write(fila,0,campo['campo1'])": Se asigna el valor de "campo['campo1']" a la fila "fila" columna "0".
  8. "hoja.write(fila,1,campo['campo2'])": Se asigna el valor de "campo['campo2']" a la fila "fila" columna "1".
  9. "fila" se le suma 1 para pasar a la siguiente fila, ( fila = fila + 1 ).
  10. Una vez finalizado el bucle se salva el nuevo libro en la ruta deseada, en este caso es: "libro.save("C:/prueba.xls")".
El último paso es llamar al procedimiento:
select fescribirexcel();

Links de las librerías:
  • xlrd-0.7.1.win32 – web: xlrd
  • xlwt-0.7.2.win32 – web: xlwt
  • xlutils-1.4.1.win32 – web: xlutils
Nota importante:
  1. Con este procedimiento: Hay que tener en cuenta que si el libro de Excel ya existe, éste será sustituido por completo con los datos nuevos.
  2. Este ejemplo se probó bajo Windows 7, por lo tanto se tiene que tener en cuenta los permisos de escritura; en el ejemplo expuesto, el nuevo documento se crea en la ruta "C:\" por mi configuración personal sobre esa ruta; si no tiene permisos de escritura en esa ruta entonces no va a funcionar el procedimiento.
  3. Si quiere cambiar la ruta a una carpeta en la cual tenga los permisos, sustituya la siguiente línea "libro.save("C:/prueba.xls")" por "libro.save("C:/RutaConLosPermisos/prueba.xls")" en el procedimiento almacenado con el nombre de "fescribirexcel()".
Un cordial saludo.
Firma: XDRTAS


miércoles, 28 de abril de 2010

0003 Excel - PostgreSQL


En muchas ocasiones me he encontrado con el siguiente problema: "¿Cómo hacer para pasar datos de Excel a postgreSQL?" Para ésta pregunta hay varias respuestas:
  1. La más común es pasar del formato XLS, (Excel), a el formato CSV, (comma-separated values), y desde postgreSQL llamar al archivo CSV por medio de un procedimiento almacenado para añadir los datos a una tabla en la base de datos.
  2. Otra forma es usar los drivers ODBC desde el archivo de Excel para pasar los datos de las celdas a una tabla o varia tablas en postgreSQL.
  3. Una tercera sería pasar los datos desde Excel a MS-Access
    y luego desde Access pasar a postgreSQL.
En el siguiente tutorial explico cómo leer directamente los datos desde un archivo de Excel mediante un procedimiento almacenado de postgreSQL para añadir los datos a una tabla.
Con los métodos antes expuestos tenemos los siguientes problemas:
  • Excel a CSV: Cada vez que se haga una modificación sobre el archivo de Excel habrá que pasar nuevamente al formato CSV para leer los nuevos valores.
  • Excel con ODBC: Si se tienen varios archivos de Excel, cada uno de ellos tiene que estar configurado para poder trabajar con el driver ODBC, si uno de ellos no está configurado entonces no se podrá pasar la información a la base de datos. Otro inconveniente es que se tiene que ejecutar el archivo de Excel cada vez que se hagan cambios en sus celdas.
  • Excel a Access: Los mismos problemas antes mencionados, añadiendo un nivel extra de incomodidad y dificultad al proceso cada vez que se hagan actualizaciones en los archivos de Excel.
Método a tratar: Leer el archivo desde un procedimiento almacenado de postgreSQL.
¿Qué ventaja puede traer este método?: Al estar el proceso de lectura de un archivo de Excel en un procedimiento almacenado en postgreSQL, se automatiza el proceso de actualización de datos de la tabla relacionada cada vez que el usuario quiera con tantos archivos de Excel que se esté trabajando, eliminando así los inconvenientes antes mencionados.
¿Cómo es esto posible?: Una de las razones por la cual he seleccionado postgreSQL como plataforma de base de datos es su capacidad para usar varios lenguajes de programación para el desarrollo de procedimientos almacenados y es aquí donde viene el "quid" de la cuestión. Para leer directamente de un archivo de Excel desde un procedimiento almacenado en postgreSQL se va a usar el lenguaje plpythonu, una vez leídas las celdas, los datos de éstas serán guardadas en la tabla correspondiente.
El siguiente ejemplo es muy sencillo pero será suficiente para ver el funcionamiento del procedimiento.
Aplicaciones y versiones que se usaron para este ejemplo:
AplicaciónVersión
S.O.: Windows 76.1 compilación 7600
PostgreSQL8.4
Python2.6.5
MS-Excel 200712.0.6524.5003 SP2


Librerias python que se usan para la comunicación con archivos de excel:
  • xlrd-0.7.1.win32 – web: xlrd
  • xlwt-0.7.2.win32 – web: xlwt
  • xlutils-1.4.1.win32 – web: xlutils 1.4.1
Una vez bajados, instalar los archivos empezando por el archivo xlrd-0.7.1.
Archivo Excel:

A
B
1
David
0
2
Jorge
1
3
Arturo
2
4
Sylvia
3
5
Carolina
4
6
Graciela
5
7
Fernando
6
8
Elena
7
9
Carlos
8
10
Daniela
9


Guardar el archivo en formato "Libro de Excel 97 – 2003 *.xls", en la ruta "c:\" con el nombre de prueba.xls, ejemplo: C:\prueba.xls

Crear tabla:
CREATE TABLE excel
(
campo1 character varying(20),
campo2 character varying(20)
)
WITH (
OIDS=FALSE
);
ALTER TABLE excel OWNER TO postgres;


Pocedimiento almacenado:
CREATE OR REPLACE FUNCTION fexcel1() RETURNS text AS
$BODY$
from xlrd import open_workbook,cellname
libro = open_workbook('c:/prueba.xls')
hoja = libro.sheet_by_index(0)
for row_index in range(hoja.nrows):
val1 = hoja.cell(row_index,0).value
val2 = hoja.cell(row_index,1).value
plpy.execute("INSERT INTO excel(campo1, campo2) VALUES ( '" + val1 + "', '" + str(val2) + "' )")
return "Funciona"
$BODY$
LANGUAGE 'plpythonu' VOLATILE
COST 100;
ALTER FUNCTION fexcel1() OWNER TO postgres;


Comentarios:
from xlrd import open_workbook,cellname:Esta línea indica que se va a importar la librería xlrd para abrir y leer un archivo de Excel.
libro = open_workbook('c:/prueba.xls'):Se abre el archivo de Excel y se asigna a la variable "libro".
hoja = libro.sheet_by_index(0):Se accede a la primera hoja del libro abierto y se le asigna a la variable "hoja".
for row_index in range(hoja.nrows):Se comienza un bucle con el número de iteraciones igual al número máximo de filas.
val1 = hoja.cell(row_index,0).value:Se asigna el valor de la fila en que se encuentre el bucle de la primera columna a la variable "val1".
val2 = hoja.cell(row_index,1).value:Se asigna el valor de la fila en que se encuentre el bucle de la segunda columna a la variable "val2".
plpy.execute("INSERT INTO excel(campo1, campo2) VALUES ( '" + val1 + "', '" + str(val2) + "' )"):Se ejecuta el "insert" para guardar los valores obtenidos de las celdas.


Ejecución del script:
select fexcel1();


Comentarios finales:
Con las librerías de python antes expuestas se pueden hacer muchas más cosas, como por ejemplo actualizar los valores de una celda en el archivo de Excel y combinando esto con postgreSQL se puede hacer la actualización de un libro obteniendo primero los datos de una tabla, aunque eso quedará para otro tutorial.
Recuerden instalar el lenguaje plpythonu, si no, este ejemplo no funcionará.
Sólo ha sido probado bajo Windows, los usuarios de Linux están marginados de momento.
Nota importante: Recién estoy aprendiendo python, cualquier comentario sobre el lenguaje les recomiendo que busquen por "San" google, les proporcionará más información de la que yo les puedo dar.
Muchas gracias.
Firma: XDRTAS


jueves, 22 de abril de 2010

0002 Ajax – PHP – PostgreSQL I

La explicación de lo que es AJAX va más allá de este tema, por "San" google podrán encontrar referencias excelentes de qué es AJAX y su historia.

En este artículo se va a mostrar el funcionamiento básico de AJAX puro y duro, los frameworks los veremos más adelante. Espero que les guste.
En este ejemplo se establece la comunicación por medio del método "POST".
Lo primero es, tener claro lo que se va a realizar en este artículo y para eso he realizado el siguiente diagrama con MS-Visio:


Image Hosted by ImageShack.us

Explicación:
  1. El cliente llama al servidor para visualizar la página "html", (testhtml.html), que contiene la información.
  2. La página testhtml.html contiene un link que al hacer "click" en él, éste hace la llamada a la función correspondiente para obtener los datos que el usuario busca.
  3. La función javascript se encarga de llamar al script php, (testphp.php). El script php contiene la conexión a la base de datos y la consulta SQL que trae los datos de la tabla.
  4. El script testphp.php se ejecuta, éste llama a la base de datos "pruebas" tabla "prueba" y devuelve el resultado a la función javascript que hizo la llamada, (fDatos(id, url)),desde el script javascript, (testajax.js) luego se actualiza la página "html" con los resultados obtenidos.
  5. El cliente visualiza el nuevo resultado.
Código SQL:

 CREATE TABLE prueba (  
   id integer NOT NULL,  
   nombre character varying(50),  
   apellido character varying(50),  
   cedula character varying(10)  
 );  
 --Recuerden añadir datos a la tabla...  
Código HTML – (testhtml.html):

 <!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>Prueba de [ AJAX - PHP - POSTGRESQL ]</title>  
  <script language="javascript" src="testajax.js" type="application/javascript"></script>  
 </head>  
 <body style="background-color:#366;">  
  <table border="0" style="color:white; background-color:#000;" align="center">  
   <tr>  
    <td colspan="2" align="center">  
     <strong>Prueba de:</strong><span style="color:#F00; font-weight:bolder;">[ AJAX - PHP - POSTGRESQL ]</span>  
    </td>  
   </tr>  
   <tr>  
    <td colspan="2">  
     <div id="contenido" style="color:#1FE4EF; font-family:'Times New Roman', Times, serif;"></div>  
    </td>  
   </tr>  
   <tr>  
    <td align="center">  
     <a href="#" onclick="javascript:fDatos('contenido','testphp.php');" style="color:#0F0; text-decoration:none;">[ Mostrar datos ]</a>  
    </td>  
    <td align="center">  
     <a href="#" onclick="javascript:fBorrar('contenido');" style="color:#F00; text-decoration:none;">[ Limpiar contenido ]</a>  
    </td>  
   </tr>  
  </table>  
 </body>  
 </html>  
Código JavaScript – (testajax.js):

 /*------------------------------------------------------*/  
 //Función para crear el objeto Ajax.   //  
 /*------------------------------------------------------*/  
 function nuevoAjax()  
 {  
  var xmlhttp=false;  
  try  
  {  
     xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");  
  }  
  catch (e)  
  {  
     try  
     {  
        xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");  
     }  
     catch (e)  
     {  
        xmlhttp = false;  
     }  
  }  
  if (!xmlhttp && typeof XMLHttpRequest!='undefined')  
  {  
     xmlhttp = new XMLHttpRequest();  
  }  
  return xmlhttp;  
 }  
 /*------------------------------------------------------*/  
 //id: id del control div que va a recibir los datos. //  
 //url: Dirección url de la página donde se  //  
 // obtiene los datos.    //  
 /*------------------------------------------------------*/  
 function fDatos(id, url)  
 {  
  var objDiv = document.getElementById(id);  
  ajax = nuevoAjax();  
  ajax.open("POST", url, true);  
  ajax.onreadystatechange = function()  
  {  
    switch (ajax.readyState)  
    {  
       case 0:  
          objDiv.innerHTML = 'Error 0. No se ha abierto la comunicaci&oacute;n.';  
          break;  
       case 1:  
          objDiv.innerHTML = 'Por favor, espere. Cargando...';  
          break;  
       case 2:  
          objDiv.innerHTML = 'Petici&oacute;n cargada, esperando respuesta del servidor...';  
          break;  
       case 3:  
          objDiv.innerHTML = '';  
          break;  
       case 4:  
          if(ajax.status == 200)  
          {  
            objDiv.innerHTML = "";  
            objDiv.innerHTML = ajax.responseText;  
          }  
          else  
          {  
            objDiv.innerHTML = 'Error 200';  
          }  
          break;  
    }  
  }  
  ajax.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");  
  ajax.send();  
 }  
 /*------------------------------------------------------*/  
 //Borrar los datos de la celda en la página web... //  
 /*------------------------------------------------------*/  
 function fBorrar(id)  
 {  
   document.getElementById(id).innerHTML = "";  
 }  

La función nuevoAjax() es la función estándar que sirve para crear el objeto ajax que se encarga de la actualización del contenido de forma asincrónica, o sea, que un elemento de la página se actualice sin que el resto de la página se vea afectada.
La función fDatos(id, url) es la función que se encarga de obtener los datos del script de php para poder visualizarlo en la página html, (testhtml.html). El parámetro "id" contiene el nombre de la etiqueta "DIV" con el nombre "contenido" de la página testhtml.html. El parámetro "url" contiene la dirección del script php que se va a ejecutar, en este caso es testphp.php.
La función fBorrar(id), borra el contenido de la etiqueta "DIV" denominado "contenido".
Código PHP – testphp.php:

 <?php  
 //Conexión a la BBDD en postgreSQL...  
 $conbd = pg_connect("host=localhost port=5432 dbname=pruebas user=tuusuario password=tupassword") or die(pg_last_error());  
 $sql = "SELECT * FROM prueba;"; //Consulta SQL...  
 $res = pg_query($conbd, $sql);  
 if($res)  
 {  
   $html = "<table border=\"1\">";  
   $html .= "<tr>";  
   $html .= "<td align=\"center\"> [ ID ]  </td>";  
   $html .= "<td align=\"center\"> [ NOMBRE ]  </td>";  
   $html .= "<td align=\"center\"> [ APELLIDO ] </td>";  
   $html .= "<td align=\"center\"> [ C&Eacute;DULA ] </td>";  
   $html .= "</tr>";  
   while($val = pg_fetch_array($res))  
   {  
     $html .= "<tr><td>" . $val[0] . "</td><td>" . $val[1] . "</td><td>" . $val[2] . "</td><td>" . $val[3] . "</td></tr>";  
   }  
   $html .= "</table>";  
   pg_close($conbd);  
   echo $html;  
 }  
 ?>  

El código php muestra la conexión a la base de datos con la función "pg_connect()", la variable "$sql" contiene la cadena de consulta SQL para obtener los datos y la variable "$html" contiene una cadena de caracteres con el código HTML más el resultado de la consulta que es devuelta por medio del comando "echo".
"$html" es la variable que se devuelve a la función de javascript fDatos(id, url). fDatos(id, url) se encarga de actualizar la página html por medio del siguiente método "innerHTML" que pertenece al objeto document.getElmentId().
Elementos de la función fDatos(id, url) - AJAX:
  • Ajax = nuevoAjax() – para crear el objeto ajax.
  • Ajax.open: Método que abre el script para obtener los datos.
  • Ajax.onreadystatechange: Método que se encarga de evaluar el estado del script que se ha llamado, hay 5 estados posibles:
    • 0: No se ha abierto la comunicación con el script seleccionado.
    • 1: Estado en espera.
    • 2: La petición está cargando, esperando respuesta del servidor.
    • 3: Estado interactivo.
    • 4: Comprobar el status de la respuesta, si es 200 todo ok, si no, hubo un fallo.
  • Ajax.setRequestHeader: el formato de la cabecera del archivo para procesar los datos.
  • Ajax.send(): Para enviar parámetros al script php. Más adelante colocaré un ejemplo de cómo usar este método.
Para más información sobre AJAX, pueden visitar la siguiente página: librosweb
Conclusión:
Usar AJAX es realmente muy sencillo sólo hay que tener claro cómo funciona básicamente el proceso de comunicación, aquí les dejo un pequeño resumen visual del proceso.
Petición de datos:


Image Hosted by ImageShack.us


Recepción de datos:


Image Hosted by ImageShack.us

De momento esto es todo, recuerden que "San" google les puede proveer más información, esto es sólo un ejemplo de lo que se puede hacer con AJAX – PHP – POSTGRESQL sin usar ningún framework.
Un cordial saludo.
Firma: XDRTAS