Collection PL/SQL – TYPE TABLE OF

En Oracle el manejo de Collection es muy importante cuando se tiene varios datos no definidos. Ya que no existen los objetos por ser un lenguaje estructurado.

A continuación se detalla el uso de una Collection Simple.

Una Collection, se forma de dos partes: INDEX y VALUE. Donde el INDEX, será nuestra llave de acceso para localizar nuestro VALUE.

Para crear una Collection de este tipo se utilizan dos pasos:

1. Creación del tipo (type)

                Utilizamos la sentencia:

                  TYPE type_name IS TABLE OF XXXXX INDEX BY YYYYY;

                Dónde:

                               XXXXX : Indica el tipo de dato que almacenará nuestra  Collection (VALUE)

                               YYYYY : Indica el tipo de dato que utilizaremos para el INDEX.

                Es importante, notar que el INDEX, solo permite los tipos de datos: VARCHAR2 ó BINARY_INTEGER

                Ejemplo:

                                 TYPE estructura_t IS TABLE OF DATE INDEX BY VARCHAR2(255);

                                 INDEX: De tipo Varchar2

                                 VALUE: De tipo DATE

2. Creación de la Variable

                Con el tipo creado (declarado) procedemos a declarar la variable a utilizar:

                               estructura estructura_t;

Para agregar valores solo haremos lo siguiente (respetando los tipos de INDEX y VALUE declarados en el Tipo):

 estructura('MIERCOLES') := SYSDATE - 10;
estructura('LUNES') := SYSDATE;
estructura('MARTES') := SYSDATE - 3; 

Sin importar el orden en que los valores sean agregados, siempre serán ordenados en base al valor del INDEX.

Y punto a recordar, si buscamos un INDEX que no existe, este tipo de Collection devuelven un NO DATA FOUND.

Aquí el ejemplo completo:

DECLARE
--
TYPE estructura_t IS TABLE OF DATE --TIPO DATO A ALMACENAR
INDEX BY VARCHAR2(255); --TIPO DATO POR EL QUE SE ACCEDE (INDEX)
estructura estructura_t;
--
  l_idx         varchar2(30);
  IDX_NO_EXISTE NUMBER := '45';
BEGI
   --Llenado de estructura
  estructura('MIERCOLES') := SYSDATE - 10;
  estructura('LUNES') := SYSDATE;
  estructura('MARTES') := SYSDATE - 3;
  --Recorrerlos de Forma lineal
  l_idx := estructura.FIRST;
  LOOP
    EXIT WHEN l_idx IS NULL;
    dbms_output.put_line('[' || l_idx || '] : [' ||estructura(l_idx) || ']');
    l_idx := estructura.NEXT(l_idx);
  END LOOP;
  --No encontrado
  BEGIN
    dbms_output.put_line('[' ||estructura(IDX_NO_EXISTE) || ']');
  EXCEPTION
    WHEN NO_DATA_FOUND THEN
      dbms_output.put_line('INDEX NO ENCONTRADO: [' || IDX_NO_EXISTE || ']');
  END;
END;

Resultado:

JSON DESDE VIRTUOSO + SPARQL + AJAX

La comunicación con un TripleStore desde un aplicativo externo, en su mayoría web, suele ser un inconveniente en algunos casos. Esto por la variada forma de responder y el no existir un estándar para la comunicación.

El presente caso se muestra como extraer información desde un servidor Virtuoso (EndPoint) mediante una petición HTTP, y esperando el resultado en formato JSON, el cual es muy sencillo manejar desde JavaScript.

Virtuoso en su EndPoint (http://mi_servidor:8890/sparql) permite la realización de consultas tanto de forma directa como mediante peticiones HTTP. Pudiendo ser estas un GET (consultas pequeñas) o un POST(consultas mayores a 19000 bytes). Y una de sus principales ventajas es que podemos especificar el formato en que deseamos la respuesta, pudiendo soportar formatos como XML, RDF, JSON y muchos más.

A continuación se muestra una consulta sparql y el resultado de la misma. Este mismo resultado será extraído desde un ambiente web mediante una consulta HTTP realizada por AJAX mediante el framework JQuery.

consulta_sparql
Los archivos utilizados para la demostración son los siguientes:

estructura
Dónde:

peticionHTTP.php: Forma la dirección HTTP la cual se solicitará a Virtuoso.

procesoJS.js: Contiene la consulta SPARQL y la llamada mediante Ajax.

Index.html: Inicia el proceso de la consulta.

Para la realización de la petición HTTP a virtuoso la URL que se construye utiliza los parámetros que se detallan en la imagen. Para este caso estos son los básicos y necesarios.

parametros

Como se puede apreciar, se valida la información de la petición y respuesta recibida por parte del servidor en donde se observa el formato de respuesta.

tipo_respuesta

peticion_console

Y finalmente el resultado se puede visualizar en nuestra página.

resultado_json

Los archivos utilizados los pueden descargar del widget de la página o de este link.

Información adicional la pueden encontrar en el siguiente enlace: http://virtuoso.openlinksw.com/dataspace/doc/dav/wiki/Main/VOSSparqlProtocol

Saludos.

Pasar JSON desde PHP(MySql) a JavaScript

El trabajo con estructuras JSON para el intercambio de datos entre cliente y servidor es una tarea relativamente sencilla y potente que permite agilizar el desarrollo. En este caso si necesitamos enviar datos desde un servidor que utiliza PHP y recupera datos de una base MySql bastará con tener un archivo .php similar a este:

$sql = "SELECT ID, POBLACION, NUMVISITAS FROM VISITAS_CENTROS";

$resulset = mysql_query($sql, $_SESSION["idBD"])

$arr = array();
while ($obj = mysql_fetch_object($resulset)) {
	$arr[] = array('ID' => $obj->ID,
				   'P' => utf8_encode($obj->POBLACION),
				   'NV' => $obj->NUMVISITAS,
		);
}
echo '' . json_encode($arr) . '';

El tema de la conexión con MySql puede ser consultado acá.

Haciendo uso de la instrucción  mysql_fetch_object recorreremos cada unos de los resultados de la consulta y los introduciremos en un Array que será transaformado median la instrucción json_encode.

En nuestro cliente podemos llamar a este archivo mediante JQuery de la siguiente forma:

$.ajax({
        type: "POST",
        url:"getData.php",
        async: true,
        success: function(datos){
            var dataJson = eval(datos);
			
            for(var i in dataJson){
				alert(dataJson[i].ID + " _ " + dataJson[i].P + " _ " + dataJson[i].NV);
            }
			
        },
        error: function (obj, error, objError){
            //avisar que ocurrió un error
        }
});

Donde el mostrar la información será tan fácil como utilizar un for para el objeto Json. Utilizando la sintaxis dataJson[i].PROPIEDAD para acceder a la información.

Sencillo pero muy útil.

Saludos.

Expresiones Regulares – Java

El trabajo con expresiones regulares en java es relativamente sencillo y útil. A continuación un ejemplo de como reemplazar varios espacios en blanco por uno solo.

Primero, crear un compilado de la expresión regular mediante la clase Pattern, especificando que se buscará un conjunto de espacios de 1 ó más.

Pattern patron = Pattern.compile("[ ]+");

Creamos un objeto Matcher que permitirá establecer las coincidencias dentro de la cadena basados en el compilado anterior.

Matcher encaja = patron.matcher("x     000000000    estado    buenos    malos    rrrr");

Ejecutamos la operación de reemplazo para todas las cadenas que coincidan con nuestro patrón.

String resultado = encaja.replaceAll(" ");

Lo que obtendremos será de una cadena inicial:

x     000000000    estado    buenos    malos    rrrr

algo como

x 000000000 estado buenos malos rrrr

Saludos.

ResultSet closed – mysql – java

Nuevamente me encuentro con esta situación, así que mejor la coloco como un post en el blog para tenerla luego como referencia y haber si a alguien más le sirve.
Cuando se está iterando un ResultSet en java como resultado de una consulta hacia MySql (jdbc) es muy común querer extraer más datos por cada iteración, es decir ejecutar una nueva consulta dentro del while que está iterando y recibir una excepción del tipo:

java.sql.SQLException: Operation not allowed after ResultSet closed

La misma que puede ser generada con un código parecido a este:

Statement st_A = conexion.createStatement();
ResultSet rs_A = st_A.executeQuery("cualquierConsulta");
while(rs_A.next()){
ResultSet rs_B = st_A.executeQuery("otraConsulta");
}

El origen es muy simple, cada vez que se realiza la ejecución de una sentencia en el ‘Statement’ todos los ‘ResultSet’ asociados a este son cerrados por lo que iterarlos ya no es posible (el programa anterior fallará luego de la primer iteración).

Una solución que encontré a esto es crear ‘Statement’ separados por cada uno de los ‘ResultSet’ de la siguiente forma:

Statement st_A = conexion.createStatement();
ResultSet rs_A = st_A.executeQuery("cualquierConsulta");
while(rs_A.next()){
Statement st_B = conexion.createStatement();
ResultSet rs_B = st_B.executeQuery("otraConsulta");
}

Saludos.

Iterar HashMap – JAVA

La estructuras del tipo HashMap permiten almacenar contenido relacionado de la forma LLAVE –> VALOR. Una estructura de este tipo es útil cuando existen referencias a valores de los cuales se desea saber su correspondencia con otro valor. Evitando el uso de las estructuras IF y SWITCH.

Aunque presenta  todas estas ventajas uno de sus inconvenientes, muchas de las veces, es el iterar sus elementos uno a uno. A continuación el proceso a seguir ::

Creamos un HashMap para almacenar una llave de tipo caracter y su valor entero.

HashMap<String, Integer> ht = new HashMap<String, Integer>();

Si poseemos elementos en ella podremos iterarlos uno a uno, haciendo uso de un FOREACH en base a Map.Entry para ello ::

for (Map.Entry<String, Integer> elemento : ht.entrySet()) {
     System.out.println(elemento.getKey() + " _ " + elemento.getValue());
}

Hay que recordar que el elemento a iterar deberá ser de el mismo tipo que el HashMap, en este caso <String, Integer>. Aquí un proyecto en NetBeans implementando esta utilidad.

Saludos.

Encadenamiento Hacia Delante (EHD)

El encadenamiento hacia delante aplicado a la lógica de predicados permite inferir conocimiento (o comprobarlo) mediante la utilización de varias reglas predefinidas. Aquí pueden encontrar un programa desarrollado completamente en JAVA bajo NetBeans.

El mismo se basa en un conjunto de hechos y reglas que son dados como entrada a partir de los cuales se realiza interacciones sucesivas hasta que no se pueda inferir más premisas.

Espero les resulte útil.

 

Saludos.

PD: El programa utiliza un Look&Feel de Substance, por tanto hay que importarlo primero, se encuentra en la misma carpeta del proyecto.

 

Convertir Hexadecimal a Binario (hex to binary)

Más de una vez se presenta la necesidad de convertir un número de Hexadecimal a Binario, ya sea para cálculos o para extraer cada uno de los bits, como es mi caso y utilizando JAVA es tan sencillo como:

Transformar un String a Hexadecimal:

int numHex = Integer.parseInt("AA", 16);

Transformar el número Hexadecimal a Binario

String binary = Integer.toBinaryString(numHex);

y listo nuestra salida será similar a esto:

10101010

En el siguiente código(en NetBeans) pueden probarlo, además hay una función para completar el número de bits que necesitan en su número binario resultante.

Saludos.

CONEXIONES PHP – MYSQL & PHP-ACCESS

Siempre es común (indispensable diría yo ;-)) en el desarrollo de aplicaciones bajo php el conectarse a una BD. A continuación algunos ejemplos con dos Bases de Datos distintas:

PHP – MYSQL.

Para la conexión con una base MYSQL lo hacemos de la siguiente manera:

mysql_connect($dbhost, $dbusuario, $dbpassword) or die («Error al Conectar!»);

Especificamos el nombre de la BD en la que vamos a trabajar:

mysql_select_db($db) or die («Verifique la Base de Datos»);

Armamos la consulta y extraemos los datos:

$consulta = «SELECT titulo, latitud, longitud, descrip, icono FROM posicion»;

$respuesta = mysql_query ($consulta);

Verificamos si existió algún error o no:

if (!$respuesta) {

$message  = ‘Error en la consulta: ‘ . mysql_error() . «\n»;

$message .= ‘Busqueda: ‘ . $consulta;

die($message);

}

Presentamos la información que acabamos de extraer:

while ($row = mysql_fetch_array($respuesta))

{

$x = $row[1];

$y = $row[2];

$title = $row[0];

$desc = $row[3];

$icon = $row[4];

$info = «$y,$x» . «<br>» . «$title» . «<br>» . «$desc» .» <br>» .»$icon».»<br>»;

print($info);

}

PHP – ACCESS

La conexión anterior con MySql es muy fácil puesto que php presenta funciones nativas que permiten realizar operaciones con esta, pero en el caso de ACCESS se deberá hacer uso de una librería llamada ADODB que permite conexión con múltiples BD’s:

Creamos el tipo de conexión:

$db_connection = new COM(«ADODB.Connection»);

Cargamos el Drive:

Especificamos aquí la dirección de la Base ACCESS en este caso es el archivo datos.mdb.

$db_connstr = «DRIVER={Microsoft Access Driver (*.mdb)}; DBQ=». realpath(«d:/datos.mdb») .» ;UID=;PWD=1234;DefaultDir=». realpath(«d:/datos.mdb»);

Realizamos la conexión:

$db_connection->open($db_connstr);

Consultamos a la Base:

$rs = $db_connection->execute(«SELECT * FROM posicion»);

Recuperamos la diferentes columnas que posee la consulta que acabamos de ejecutar:

$rs_fld0 = $rs->Fields(«titulo»);

$rs_fld1 = $rs->Fields(«latitud»);

$rs_fld2 = $rs->Fields(«longitud»);

$rs_fld3 = $rs->Fields(«descripcion»);

$rs_fld4 = $rs->Fields(«icono»);

Recorremos las columnas hasta el final y las presentamos:

while (!$rs->EOF) {

$titulo = $rs_fld0->value;

$lat = $rs_fld1->value;

$lon = $rs_fld2->value;

$des = $rs_fld3->value;

$ico = $rs_fld4->value;

$info = «$lon,$lat» . «<br>» . «$titulo» . «<br>» . «$des» .» <br>» .»$ico».»<br>»;

print($info);

//Avanzamos un registro

$rs->MoveNext();

}

Cerramos tanto el ResulSet como la Conexión:

$rs->Close();

$db_connection->Close();

Como podemos ver los métodos de extracción de datos son diferentes pero útiles, los archivos de ejemplo utilizados puedes encontrarlos en la parte izquierda del blog o aquí.

Saludos.

Consultas Dinámicas SQL – ORACLE

Más de una vez se utilizan dentro de las bases de Datos consultas un poco parecidas o se necesita armar una consulta con determinados datos, algo que puede ser simplificado dentro de Oracle, con la utilización de el paquete DBMS_SQL.

Aquí un ejemplo:

Si poseemos la siguiente estructura de una tabla (muy sencilla solo para ejemplo):

create table registro (cliente  varchar2 (50),
compras  number (10,3),
ventas   number (10,3),
estado   varchar2 (25));

En donde se guardará información de ventas o compras de un cliente, tomando en cuenta que por cada transacción solo puede haber un valor en compras o ventas, pero no los dos, los datos son ingresados de la siguiente manera:

insert into registro ( cliente, compras, estado)
values ( 'Perez Juan', 123.4, 'CANCELADO');
insert into registro ( cliente, ventas, estado)
values ( 'Perez Juan', 452.8, 'PENDIENTE');

Como podemos ver la única diferencia entre estas sentencias de INSERT es la columna a la cual hacen referencia, ahora bien, que tal si creamos un pequeño procedimiento y lo almacenamos en un paquete de utilidad que luego podremos utilizar.

El procedimiento quedaría algo como esto:

PROCEDURE grabar_datos( nm_cliente     varchar2 (50),

columna        varchar2(50),

val_columna    number (10,3),

estado         number (10,3))

is

n_cursor INTEGER;

consulta VARCHAR2(250);

aux      number;

begin

consulta := 'insert into registro (cliente,:v1,estado)

values (:v2 , :v3 , v4)';

n_cursor := DBMS_SQL.OPEN_CURSOR;

DBMS_SQL.PARSE(n_cursor, consulta , DBMS_SQL.NATIVE );

DBMS_SQL.BIND_VARIABLE(n_cursor, ':v1', columna);

DBMS_SQL.BIND_VARIABLE(n_cursor, ':v2', nm_cliente);

DBMS_SQL.BIND_VARIABLE(n_cursor, ':v3', val_columna);

DBMS_SQL.BIND_VARIABLE(n_cursor, ':v4', estado);

aux := DBMS_SQL.EXECUTE (n_cursor);

DBMS_SQL.CLOSE_CURSOR(n_cursor);

end grabar_datos;

En este caso el parámetro val_columna podrá solo recibir dos valores «compras»  o «ventas» que son las columnas de la tabla. Podemos observar que para crear la consulta dinámica reemplazos los valores a utilizar por un expresión del tipo :nombre (similar a las variables host en oracle) para luego reemplazarlas con los valores originales mediante la instrucción:

DBMS_SQL.BIND_VARIABLE(n_cursor, ':v1',columna);

Se pudiera también formar la consulta dinámica de forma directa concatenando las expresiones que necesitamos, pero por algún motivo esto no es lo más óptimo pues puede presentar errores al concatener expresiones entre ‘ ‘ y números reales (12.3) .

Con esto habremos reemplazado los dos insert por un solo procedimiento.

Saludos ,