Más dudas de Oracle

Hola de nuevo Ramón! Otra vez dándote el follón xD.
Resulta que me pedía que creara unas tablas, algunas con indices, otras con particiones y otras con subparticiones. Ok. Esa parte la e hecho.
El problema viene cuando me pide que muestre con un SELECT los tablespaces donde se han creado todas las tablas (nombre de la tabla, nombre de la partición, nombre de la subparticion, nombre del tablespace de la tabla / partición / subparticion).
Aquí supongo que tengo que hacer un OUTER JOIN, lo que pasa es que a mi me explicaron la reunión de tablas mediante atributos, pero no el OUTER JOIN.
Hemos probado con esta consulta.
select table_name, partition_name, subpartition_name, tablespace_name
from user_tab_partitions FULL OUTER JOIN user_tab_subpartitions
ON user_tab_partitions.table_name = user_tab_subpartitions.table_name;
Nos da error y nos dice que los atributos son ambiguos. Esto supongo que sera porque al existir el atributo en ambas tablas tengo que especificar el nombre y llegamos a la siguiente consulta.
select p1.table_name, s1.table_name, p1.partition_name, s1.partition_name, subpartition_name, p1.tablespace_name, s1.tablespace_name
from user_tab_partitions p1 FULL OUTER JOIN user_tab_subpartitions s1
ON p1.table_name = s1.table_name;
También nos da error y nos dice que el error se debe a que "la expresión debe tener el mismo tipo de dato que la expresión"
Aver si nos hechas una mano que estamos hartos con el OUTER JOIN.
Gracias de antemano Ramón y saludos,
Juan.

1 respuesta

Respuesta
1
Uff! A bueno se lo pides ...
Últimamente los nuevos programadores (así todos con herencias del dichoso Microsoft) no para de usar ese tipo de condicionantes de JOIN.
Es algo que odio! Pero que Oracle tuvo que asumir por temas de estándares ANSI de SQL (donde Microsoft tiene una importante presencia, aunque sea de los últimos que se han montado al carro de BB. DD. Serias!). Por otra parte, los de Oracle -que no son tontos- lo aceptaron, pensando más en vender sus productos para que la gente de Microsoft con su 'patético' SQL*Server se migren a ORACLE. Para ello ha construido herramientas que con un asistente pasas de un entorno SQL*Server a uno Oracle de forma transparente.
Pero buen ... Intentaremos solucionar el problema (Tu tutor es por-MOCOSOFT, ¿no? Jajaja).
A ver ... te solicita :
" ... Muestre con un SELECT los tablespaces donde se han creado todas las tablas
(Nombre de la tabla, nombre de la partición, nombre de la subparticion,
nombre del tablespace de la tabla / partición / subparticion).".
¿Entiendo qué sólo desea las tablas de un usuario propietario que tiene definidadas "Particiones y / o Subparticiones"? De ahí lo del OUTER JOIN, ¿no?
Primero, pensad que si utilizáis las vistas 'USER_...' sólo tendréis aquellos objetos propiedad del usuario con el que os conectáis. Si quisieseis TODAS, bastaría con conectaros con los permisos adecuados y acceder a las mismas con prefijo "dba_" e incluir la restricción de JOIN del TABLE_OWNER.
En Oracle, sería tan fácil, sencillo y elegante como :
Select a.table_name Tabla, 
      a.partition_name Particion, 
      nvl(b.subpartition_name, '------------') SubParticion,
      a.table_name||' / '||a.partition_name||' / '||nvl(b.subpartition_name, '------------') Todo from user_tab_partitions a, user_tab_subpartitions b
where a.table_name = b.table_name(+)
and a.partition_name = b.partition_name(+)
order by a.table_name, a.partition_position, b.subpartition_position
Le añado aún más información ... ordenando por el número de partición y subpartición en que se crearon!
Sin embargo, si acudimos al 'cutre' MOCOSOFT y su 'imposición en el estándar (ANSI SQL) queda algo tan complejo y horrible como (supongo que lo hacen para que como en cobol, leer una sentencia es como leer en inglés, y los analista no se pierdan ... jajaja) :
Select a.table_name Tabla,
     a.partition_name Particion,
     nvl(b.subpartition_name, '------------') SubParticion,
     a.table_name||' / '||a.partition_name||' / '||nvl(b.subpartition_name, '------------') Todo
from user_tab_partitions a LEFT OUTER JOIN user_tab_subpartitions b
        ON a.table_name = b.table_name
        AND a.partition_name = b.partition_name
order by a.table_name, a.partition_position, b.subpartition_position
Bueno ... ahí lo tenéis. Es fácil, si en Oracle ponéis el '(+)' para que te retorne un registro 'padre' sin tener 'hijo' aquí se substituye por el dichoso 'LEFT OUTER JOIN' y toda la parrafada. Indicando que la tabla de la izquierda (LEFT) es la 'padre'.
Espero que no os obligue a poner en los 'Alias de las columnas el -AS-' como :
Select a.table_name AS Tabla, ...
En fin para gustos ... Aunque yo particularmente leo mejor la sentencia en puro SQL de ORACLE.
Otros que sigan con nomenclatura MS Access ... jajaja
Joder Ramón eres un fiera! Va perfecta la secuencia aunque he tenido que cambiar alguna cosilla.
Mi siguiente duda se la pregunte ayer a mi profesor y me dijo que no sabia respondérmela, que mirara en manuales. Se quedo a gusto el tío.
Resulta que tengo que insertar varias filas con el SQL*LOADER y esto se hacerlo. Uno de los campos (idcasa) ha de ser un número secuencial obtenido automáticamente a partir de una secuencia.
La secuencia que utilizo es esta:
CREATE SEQUENCE (xxxxxx)_IDCASA
INCREMENT BY 1
START WITH 01
minvalue 01
maxvalue 50
NOCYCLE;
Tenemos que crear un archivo .dat en donde pongamos las filas. Este es nuestro archivo.dat:
idcasa,'LA HIDRA', MURCIA, 645823432, 48123065F
idcasa,'LA PERLA', ALBACETE, 645781237, 48753693J
idcasa,'EL CISNE', MURCIA, 679123907, 48230948R
Donde pone idcasa tendría que ir el valor de idcasa que es un NUMBER(3), pero como es una secuencia no sabemos que poner. ¿Tenemos qué poner ahí el nombre de la secuencia o tenemos que especificar algo en el fichero .ctl?
Aver si nos echas una mano, que el profesor que ma tocado es un incompetente.
Saludos,
Juan.
¿Cambiar alguna cosilla? Jajaja),
Respecto a lo que dices ... Dos cosas :
1.- El objeto 'seqüence' que has creado piensa que sólo aceptara 50 valores y que no es cíclico. SI te falla el proceso de lectura para carga ... entonces tendrías que modificar la secuencia para inicializarla al valor inicial. (" ... MAXVALUE 50 INCREMENT BY 1").
3.- Para que ello no te ocurra, Oracle ya hace tiempo creó una función que te permite asignar números correlativos sin necesidad de crear un objeto SEQÜÈNCE ...
Mira el siguiente ejemplo :
LOAD DATA
INFILE 'ti_fichero_dat.dat'
BADFILE 'xyz.bad'
LOG xyz.log
INSERT INTO TABLE tu_tabla
(Emp_no POSITION(1:6) INTEGER,
Emp_name POSITION(7:31) CHAR,
Seq_no SEQUENCE(MAX, 1))
Aunque en lugar de posiciones fijas, como el ejemplo, tu tengas como delimitador el carácter 'coma' -que yo no usaría porque muchos literales pueden contenerlo-.
En el fichero de 'datos', no pongas 'idcasa' ... Quítalo ...
Y luego en el de control, pones algo parecido a lo anterior pero :
INSERT INTO tu_tabla
(Idcasa SEQUENCE(MAX, 1),
... etc.
POr tanto, no necesitarás crear ningún objeto secuencia y esta función hará las mismas acciones. Y en caso de fallo, no tendría que inicializar la secuencia al valor inicial.
Mira a ver si lo entiendes, lo implementas y verás que fácil es ...
Un Saludo
Joan ... y cuando un profesor te hace recurrir a un libro es por dos razones : O porque piensa que no estudias lo suficiente (o le has hecho alguna pregunta que no sabe y se siente molesto) o porque no tiene ni idea y tan sólo sigue un guión de Oracle que le han preparado. Pero poca idea tiene más de este Gestor.
La solución que me das es buena, pero el enunciado me dice claramente que tengo que crear la secuencia sin más narices, asique tengo que hacerlo creando la secuencia y cargándola de alguna manera, pero he mirado en un montón de libros y no encuentro nada.
Cuando en el fichero de datos pongo idcasa, era para indicarte que ahí va el valor de idcasas.
Saludos Ramon y gracias de nuevo,
Juan.
Vaya! Encima tozudo ...
A ver ... prueba con esto. Yo no lo he probado, pero tendría que funcionar.
Si te da un error, primero averigua si es por esta restricción o assignación o por motivos de no encontrar la secuencia o repetirse ... OK.
En Control_File :
...
column_name "nombre_sequence.nextval",
...
Un saludo
Y ya me comentarás. Ya que últimamente se utiliza lo que anteriormente te dije. Y más aún en Sistemas RAC 10g, donde te obliga a tener las secuencias no ordenadas y en cache. Para no crear contención en todos los nodos definidos!

Añade tu respuesta

Haz clic para o

Más respuestas relacionadas