Saltar al contenido

www. La Mandarina Mecánica .es

…ahora con internet los niños se te educan solos… Homer Simpson…

Archivo

Categoría: Bases de Datos

1. Introducción

Un índice es un conjunto de páginas asociado a una tabla (o a una vista) que se utiliza para acelerar la recuperación de filas de la tabla o para exigir unicidad.
Se utilizan índices para señalar la ubicación de una fila en una página de datos en lugar de tener que recorre todas las páginas de datos de una tabla.
Un índice contiene claves formadas a partir de una o más columnas de la tabla.

1.1 Acceso de SQL Server a los datos

Hay dos maneras de acceder a los datos:

Examinando todas las páginas de datos de una tabla, lo que se denomina recorrido de tabla.

1 Empieza por el principio de la tabla.
2 Avanza de página en página por todas las filas de la tabla.
3 Extrae las filas que cumplen los criterios de la consulta.

Utilizando índices. Cuando SQL Server utiliza un índice:

1 Recorre la estructura de árbol de índices para encontrar las filas solicitada por la consulta.
2 Extrae únicamente las filas necesarias que cumplen los criterios de la consulta.

1.2 Índices agrupados.

Un índice agrupado ordena y almacena las filas de datos de la tabla según la clave del índice agrupado. El índice agrupado se implementa como un árbol.
En un índice agrupado, los nodos raíz e intermedios contienen páginas de índice que incluyen filas de índice. Cada fila de índice contiene un valor de clave y un puntero a una página de nivel intermedio del árbol b o a una fila de datos en el nivel de hoja del índice.

continúe leyendo…

Este error de Oracle, traducido sería algo así:

TNS:el listener no ha encontrado ningún manejador disponible con una pila de protocolos coincidente

El otro día nos dió aquí al tratar de conectar a BBDD, y era porque estabamos cerca de alcanzar el número máximo de sesiones y procesos establecidos.

Si en máquina ejecutais cualquiera de estas dos líneas, os dará el número de conexiones que hay en ese momento:

ps -ef | grep oracleSID | grep -v grep | wc -l
ps aux | grep oracleSID | grep -v grep | wc -l

Teneís que poner oracle unido al SID de vuestra BBDD.

Luego os conectáis a BBDD para comprobar si estáis cerca del valor máximo de procesos y sesiones establecido:

select NAME, DISPLAY_VALUE, DESCRIPTION from v$parameter where name in (’processes’,’sessions’);

Si es así, lo podéis aumentar de esta manera:

SQL> alter system set processes=300 scope=spfile;
SQL> alter system set sessions=300 scope=spfile;

Luego sólo queda tirar y levantar la BBDD (siempre que tengamos los permisos suficientes)

SQL> shutdown immediate;
SQL> startup;

Claro que si no tenéis permisos hacer esto, siempre podéis “eliminar” conexiones. Si no sabéis como, echarle un ojo a otro post que hay por ahí publicado sobre esto. 

Oracle Forms es un software para crear pantallas que interactúan con una base de datos (oracle), éste es un poco limitado, con lo que a veces necesitamos incluir Jbean dentro de nuestras aplicaciones. Para esto basta con hacer un .jar e incluir éste dentro de la pantalla o fmb.
Para integrar un java Bean en Oracle Forms, necesitamos copiar el bean.jar dentro del directorio <ORACLE_HOME>/forms/java
Luego editamos el archivo formsweb.cfg y añadimos el bean.jar.

# Forms applet archive setting for JInitiator
archive_jini=f90all_jinit.jar, archivo.jar
# Forms applet archive setting for Microsoft Internet Explorer native JVM
archive_ie=f90all.cab, archivo.jar

Añadimos el Bean en la pantalla y ponemos la ruta y el nombre del bean.jar en las propiedades del Bean, en Clases de implementación añadimos:
oracle/forms/archivo (sin la extensión).

Primero crearemos el directorio para trabajar. Tenéis que tener permisos para hacerlo:
create or replace directory DIR_TEST as ‘/usuarios/prueba’;
Si queréis borrarlo:
drop directory DIR_TEST;
Con esta select podréis ver todos los directorios creados:
select * from dba_directories;

OPERATIVA
Para trabajar con ficheros, es básico conocer la operativa de las dos operaciones más normalmente usadas.
ESCRITURA
1.     Declarar el descriptor
2.     Abrir el fichero con FOPEN de modo escritura
3.     Escribir los datos usando PUT, FPUT o PUT_LINE.
4.     Cerrar fichero FCLOSE

LECTURA
1.     Declarar el descriptor
2.     Declarar variable para almacenar datos
3.     Abrir el fichero con FOPEN de modo lectura.
4.     Leer datos con GET_LINE
5.     Cerrar fichero FCLOSE

continúe leyendo…

Con este paquete podemos obtener el código DLL (sentencia de creación) de cualquier objeto de BBDD.

 

Con la función GET_DDL de este paquete, extraeremos la DLL. Su sintaxis es la siguiente:

 

DBMS_METADATA.GET_DDL (
object_type IN VARCHAR2,
name IN VARCHAR2,
schema IN VARCHAR2 DEFAULT NULL,
version IN VARCHAR2 DEFAULT ‘COMPATIBLE’,
model IN VARCHAR2 DEFAULT ‘ORACLE’,
transform IN VARCHAR2 DEFAULT ‘DDL’)
RETURN CLOB;
 

 

 

Los parámetros que utiliza son:

1 .Tipo de objeto (tabla, index, vista…)

2. Nombre del objeto

3. El esquema al que pertenece ( No es necesario)

4. Versión de servidor para la cual se extraerá el código. Establece un filtro que limita la extracción del metadata para objetos superiores la versión indicada, que nunca puede ser menos de la 9.2.0.

5. Model: Por ahora sólo ORACLE

6. Con este parámetro podemos indicar si el metadata lo devolverá en DDL o en XML

 

 

 

SELECT dbms_metadata.get_ddl(’TABLE’, ‘PRUEBA’, ‘ORACLE’) from dual;

Devolvería:

  CREATE TABLE “ORACLE”.”PRUEBA”

   (    “NOMBRE” VARCHAR2(1)

   ) PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255 NOCOMPRESS LOGGING

  STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645

  PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT)

  TABLESPACE “ORACLE4″

 

continúe leyendo…

Es una nueva funcionalidad, a partir de Oracle 10gR2, que nos permite ejecutar una sentencia DML completa y si en el transcurso de la ejecución, algún registro diera error, se insertará en una tabla de error para, posteriormente, poder corregirlo y volver a insertarlo, continuando con los siguientes registros.

Así no tendremos que ir controlando por registro o por bloque de registros si se ha producido un error para realizar el commit.

 

Lo primero de todo. Ver si lo tenemos instalado:

 SELECT OBJECT_NAME FROM ALL_OBJECTS

      WHERE OBJECT_NAME LIKE ‘%DBMS_%’

          AND OBJECT_TYPE = ‘PACKAGE’ ORDER BY 1;

Si creamos una tabla:

  continúe leyendo…

BigTable es el sistema que tiene la compañía de google para almacenar enormes cantidades de información de una forma semi-estructurada.
Bigtable lo desarrollo  google en 2004, este sistema almacena la información en tablas multidimensionales,  está basado en el Google File System (GFS) y diseñado para la gestión de los más de 20 millones de Gigabytes que mueve diariamente Google en sus servidores. Además, estas celdas disponen de versiones temporales de sus valores, con lo que se puede hacer un seguimiento de los valores que han tomado históricamente.
BigTable  fue el modelo a seguir de  muchos  otros desarrolladores, de este modelo de datos surguieron otras implementaciones como HBase, Hypertable y Cassandra.
Básicamente funciona ‘mejor ‘ porque está distribuido en miles de servidores.

bigtable
“Las bases de datos relacionales, como pueden ser MySQL, PostgreSQL, Firebird u Oracle se diseñaron pensando que se ejecutaran  en una solo servidor con mucha potencia.
Jamas se penso en la posibilidad de que estuviesen distribuidas en miles de servidores.
Google creo Bigtable para que fuese, sobre todo, una base de datos en la que se almacenara una cantidad de información enorme, del orden de Peta bytes.”

Os dejo un enlace que encontré acerca de Bigtable en Linux-magazine  donde detalla su funcionamiento…

Antes de esta sentencia, que vino implementada en Oracle 9,  cuando se quería insertar/actualizar datos en una tabla que no estaba vacía, teníamos que ir procesando los registros y comprobar si estaba en la tabla antes de realizar un UPDATE o un INSERT, con algún tipo de lenguaje procesual.

Este tipo de sentencia permite actualizar registros (UPDATE) cuando la condición se cumple o insertar registros (INSERT) cuando la condición no se cumple.  Eso si, no es recomendable en cargas masivas de datos!

Esta sentencia tiene esta sintaxis:

MERGE INTO [tabla_destino]
USING ([tabla o vista o consulta])
ON ([condición de existencia de registro])
WHEN MATCHED THEN [sentencia de actualización]
WHEN NOT MATCHED THEN [sentencia de inserción];

MERGE INTO RESTO res USING prueba_tmp pru

ON (res.ID = pru.ID)

WHEN MATCHED THEN

UPDATE SET

 res.DNI = pru.DNI,

 res.departamento = pru.departamento

WHEN NOT MATCHED THEN

INSERT (ID, DNI, DEPARTAMENTO)

VALUES (pru.ID, pru.DNI, pru.DEPARTAMENTO)

He intentado meter más condiciones en la clausula ON, pero no he podido y tampoco he visto información al respecto.

Esta sentencia tiene otras posibilidades:

-       Sólo  insert (NOT MATCHED):

MERGE INTO RESTO res USING prueba_tmp pru

ON (res.ID = pru.ID)

WHEN NOT MATCHED THEN

INSERT (ID, DNI, DEPARTAMENTO)

VALUES (pru.ID, pru.DNI, pru.DEPARTAMENTO)

-       Sólo update (MATCHED):

MERGE INTO RESTO res USING prueba_tmp pru

ON (res.ID = pru.ID)

WHEN MATCHED THEN

UPDATE SET

 res.DNI = pru.DNI,

 res.departamento = pru.departamento

-       Con condiciones en el INSERT o el UPDATE ( Las condiciones tienen que basarse en la tabla de la que se recoge los datos)

MERGE INTO RESTO RES USING PRUEBA_TMP PRU

ON (RES.ID = PRU.ID)

WHEN MATCHED THEN

UPDATE SET

 RES.DNI = PRU.DNI,

 RES.DEPARTAMENTO = PRU.DEPARTAMENTO

WHERE PRU.DEPARTAMENTO != ‘CONTABILIDAD’

WHEN NOT MATCHED THEN

INSERT (ID, DNI, DEPARTAMENTO)

VALUES (PRU.ID, PRU.DNI, PRU.DEPARTAMENTO)

WHERE PRU.DEPARTAMENTO != ‘Contabilidad’

 

-       Con Delete (Siempre con el UPDATE) Haremos un update y luego borraremos los que pertenezcan a un departamento en la tabla en la que hemos hecho el update:

 

MERGE INTO RESTO RES USING PRUEBA_TMP PRU

ON (RES.ID = PRU.ID)

WHEN MATCHED THEN

UPDATE SET

 RES.DNI = PRU.DNI,

 RES.DEPARTAMENTO = PRU.DEPARTAMENTO

DELETE WHERE PRU.DEPARTAMENTO =  ‘Contabilidad’

 

-       Si queremos utilizarla con parámetros y la tabla DUAL:

 

MERGE INTO RESTO res

USING dual d

ON (res.ID = PARAMETRO1)

WHEN MATCHED THEN UPDATE SET res.DNI = PARAMETRO2

WHEN NOT MATCHED THEN INSERT (res.ID, res.DNI) VALUES (PARAMETRO1, PARAMETRO2);

 

 

Si el MERGE nos devuelve el siguiente error:

 

“ORA-30926: unable to get a stable set of rows in the source tables.

Cause: A stable set of rows could not be got because of large dml activity or a non-deterministic where clause.

Action: Remove any non-deterministic where clauses and reissue the dml.”

 

La verdadera causa del error no está en el “non-deterministic where clause“: quiere decir que hay dos filas de la tabla origen que actualizarían una de la tabla destino.

Desde la versión 9i podemos realizar este tiempo de inserciones. Podemos insertar en más de una tabla de forma paralela, en la misma sentencia, poniendo o no condiciones.

Utilizaremos la tabla EMPLEADOS para verlo más claramente:

 Name                                      Type                       

 DNI                                        VARCHAR2(20)               

 DEPARTAMENTO                VARCHAR2(20)

 EDAD                                    NUMBER(2)

 Crearemos tres tablas con sólo los dos primeros campos para separar a los empleados por edad;

 create table EMPLEADOS_20 as select DNI, DEPARTAMENTO from empleados where 1=0;

create table EMPLEADOS_30 as select DNI, DEPARTAMENTO from empleados where 1=0;

create table EMPLEADOS_40 as select DNI, DEPARTAMENTO from empleados where 1=0;

create table RESTO as select DNI, DEPARTAMENTO from empleados where 1=0;

 Si añadimos la condición WHERE la creará sin datos.

INSERT ALL

Como prueba insertaremos los datos de empleados en todas las tablas:

INSERT ALL

  INTO EMPLEADOS_20

  VALUES (DNI,DEPARTAMENTO)

  INTO EMPLEADOS_30

  VALUES (DNI,DEPARTAMENTO)

  INTO EMPLEADOS_40

  VALUES (DNI,DEPARTAMENTO)

  SELECT DNI,DEPARTAMENTO,EDAD FROM EMPLEADOS;

INSERT ALL WHEN (se insertan los valores especificados en todas las condiciones verdaderas.)

Ahora repartiremos los empleados en las tablas dependiendo de su edad. Crearemos una tabla para recoger al resto de las edades superiores:

 

INSERT ALL

WHEN (EDAD<30) THEN

  INTO EMPLEADOS_20

  VALUES (DNI,DEPARTAMENTO)

WHEN (EDAD<40) THEN

  INTO EMPLEADOS_30

  VALUES (DNI,DEPARTAMENTO)

WHEN (EDAD<50) THEN

  INTO EMPLEADOS_40

  VALUES (DNI,DEPARTAMENTO)

ELSE

      INTO RESTO

  VALUES (DNI,DEPARTAMENTO)

SELECT DNI,DEPARTAMENTO,EDAD FROM EMPLEADOS;

INSERT FIRST WHEN (sólo se insertan los valores especificados en la primera condición verdadera)

Si existe un empleado que tenga más de 50, aunque cumple la condición para ir a la tabla de EMPLEADOS_40 también,  se insertará en la tabla RESTO solamente, porque es la primera condición verdadera. 

 

INSERT FIRST

  WHEN (EDAD>50) THEN

    INTO RESTO

    VALUES (DNI,DEPARTAMENTO)

  WHEN (EDAD<30) THEN

    INTO EMPLEADOS_20

    VALUES (DNI,DEPARTAMENTO)

  WHEN (EDAD<40) THEN

    INTO EMPLEADOS_30

    VALUES (DNI,DEPARTAMENTO)

  WHEN (EDAD>40) THEN

    INTO EMPLEADOS_40

    VALUES (DNI,DEPARTAMENTO)

  SELECT DNI,DEPARTAMENTO,EDAD FROM EMPLEADOS 

Limitaciones:

La suma del total de las columnas INTO no puede exceder 999

Sólo funciona en tablas, no en vistas o vistas materializadas.

Navigation »