更新嵌套表

时间:2015-04-22 15:29:37

标签: oracle sql-update nested

我有以下对象和嵌套表

set serveroutput on

declare
  contador pls_integer;
begin
  select count(*) into contador from user_objects where object_name=upper('Matriculación');
  if contador = 1 then
    execute immediate 'drop table Matriculación';
  end if;
  select count(*) into contador from user_objects where object_name=upper('Matrícula');
  if contador = 1 then
    execute immediate 'drop table Matrícula';
  end if;
  select count(*) into contador from user_objects where object_name=upper('AlumnoObj');
  if contador = 1 then
    execute immediate 'drop type AlumnoObj';
  end if;
  select count(*) into contador from user_objects where object_name=upper('TablaTitulación');
  if contador = 1 then
    execute immediate 'drop type TablaTitulación';
  end if;
  select count(*) into contador from user_objects where object_name=upper('TitulaciónObj');
  if contador = 1 then
    execute immediate 'drop type TitulaciónObj';
  end if;
  select count(*) into contador from user_objects where object_name=upper('TablaAsignatura');
  if contador = 1 then
    execute immediate 'drop type TablaAsignatura';
  end if;
  select count(*) into contador from user_objects where object_name=upper('AsignaturaObj');
  if contador = 1 then
    execute immediate 'drop type AsignaturaObj';
  end if;
end;
/

CREATE TYPE AsignaturaObj AS OBJECT(
  idAsignatura    varchar2(6),
  nombre          varchar2(50),
  curso           number(1,0), -- en el original curso y cuatrimestre son varchar2, lo he cambiado por probar
  cuatrimestre    number(1,0),
  créditos        number(3,1),
  coste           number(6,2), -- no necesitamos un número de 16 dígitos como en el original
  idProfesor      varchar2(4)
);
/

CREATE OR REPLACE TYPE TablaAsignatura AS TABLE OF AsignaturaObj;
/

show errors
CREATE TYPE TitulaciónObj AS OBJECT(
  idTitulación    varchar2(6),
  nombre          varchar2(30),
  asignaturas     TablaAsignatura
) ;--NESTED TABLE asignaturas STORE AS Asignatura_Tabla return as value; -- esto NO
/

CREATE OR REPLACE TYPE TablaTitulación AS TABLE OF TitulaciónObj;
/

CREATE TYPE AlumnoObj AS OBJECT(
  dni             varchar2(9),
  idAlumno        varchar2(7),
  nombre          varchar2(20),
  apellido        varchar2(30),
  dirección       varchar2(35), -- calle {coma espacio} número --> 30+2+3=35
  ciudad          varchar2(20),
  teléfono        varchar2(9)
);
/

-- El objetivo es guardar una tabla que contenga por cada alumno cada titulación en la que esté, y por cada titulación las asignaturas en las que está matriculado
-- Nota: en este nuevo ejemplo por cada alumno se crea una nueva entrada (fila), cada fila contendrá una o varias titulaciones y a su vez cada titulación una o varias asignaturas
CREATE TABLE Matriculación (
  num_matrícula   number(5,0)     CONSTRAINT Matriculación_PK PRIMARY KEY,
  alumno          AlumnoObj       CONSTRAINT Matriculación_ALUMNO_NN NOT NULL,
  titulación      TablaTitulación
) NESTED TABLE titulación STORE AS Titulaciones_Tabla
  (NESTED TABLE asignaturas STORE AS Asignatura_Tabla); 

有这些数据:

Insert into MATRICULACIÓN (NUM_MATRÍCULA,ALUMNO,TITULACIÓN) values (1,ALUMNOOBJ('12345678A','A000000','Juan','Pérez Quintanilla','Calle Quintana, 23','Madrid','913217712'),TABLATITULACIÓN(TITULACIÓNOBJ('111111','Ciencias del Mar',TABLAASIGNATURA(ASIGNATURAOBJ('222222','Pulpos',2,1,4.5,120,'Q000'),ASIGNATURAOBJ('222223','Pólipos',2,1,3,80,'Q000'))),TITULACIÓNOBJ('222222','Geología',TABLAASIGNATURA(ASIGNATURAOBJ('922222','Cuevas',2,1,4.5,120,'Q900'),ASIGNATURAOBJ('922223','Resistencia de materiales',2,1,10,80,'Q900')))));
Insert into MATRICULACIÓN (NUM_MATRÍCULA,ALUMNO,TITULACIÓN) values (2,ALUMNOOBJ('21212121A','A010101','Rosa','García','Alegría, 16','Haro','941161616'),TABLATITULACIÓN(TITULACIÓNOBJ('150210','Químicas',TABLAASIGNATURA(ASIGNATURAOBJ('150212','Química Física',1,2,4.5,70,'P304')))));
Insert into MATRICULACIÓN (NUM_MATRÍCULA,ALUMNO,TITULACIÓN) values (3,ALUMNOOBJ('18181818A','A020202','Pepe','Pérez','Percebe, 13','Madrid','913131313'),TABLATITULACIÓN(TITULACIÓNOBJ('130110','Matemáticas',TABLAASIGNATURA(ASIGNATURAOBJ('130113','Programación I',1,1,9,60,'P101'))),TITULACIÓNOBJ('150210','Químicas',TABLAASIGNATURA(ASIGNATURAOBJ('150212','Química Física',1,2,4.5,70,'P304')))));
Insert into MATRICULACIÓN (NUM_MATRÍCULA,ALUMNO,TITULACIÓN) values (4,ALUMNOOBJ('20202020A','A030303','Luis','Jiménez','Cigüeña, 15','Nájera','941151515'),TABLATITULACIÓN(TITULACIÓNOBJ('130110','Matemáticas',TABLAASIGNATURA(ASIGNATURAOBJ('130122','Análisis II',2,2,9,60,'P203'),ASIGNATURAOBJ('130113','Programación I',1,1,9,60,'P101'))),TITULACIÓNOBJ('150210','Químicas',TABLAASIGNATURA(ASIGNATURAOBJ('150212','Química Física',1,2,4.5,70,'P304')))));
Insert into MATRICULACIÓN (NUM_MATRÍCULA,ALUMNO,TITULACIÓN) values (5,ALUMNOOBJ('26262626A','A040404','Elena','González','Percebe, 20','Logroño','941202020'),TABLATITULACIÓN(TITULACIÓNOBJ('130110','Matemáticas',TABLAASIGNATURA(ASIGNATURAOBJ('130122','Análisis II',2,2,9,60,'P203')))));
Insert into MATRICULACIÓN (NUM_MATRÍCULA,ALUMNO,TITULACIÓN) values (6,ALUMNOOBJ('16161616A','A121212','Luis','Ramírez','Pez, 34','Haro','941111111'),TABLATITULACIÓN(TITULACIÓNOBJ('170056','Turismo',TABLAASIGNATURA(ASIGNATURAOBJ('000115','Seguridad Vial',1,1,4.5,30,'P204')))));
Insert into MATRICULACIÓN (NUM_MATRÍCULA,ALUMNO,TITULACIÓN) values (7,ALUMNOOBJ('21123124R','A122143','Javier','Maganto','Fax, 23','Madrid','917643653'),TABLATITULACIÓN(TITULACIÓNOBJ('130110','Matemáticas',TABLAASIGNATURA(ASIGNATURAOBJ('130122','Análisis II',2,2,9,60,'P203'),ASIGNATURAOBJ('130113','Programación I',1,1,9,60,'P101'),ASIGNATURAOBJ('976677','Análisis matemático',3,2,6,764.89,'P203')))));
Insert into MATRICULACIÓN (NUM_MATRÍCULA,ALUMNO,TITULACIÓN) values (8,ALUMNOOBJ('17171717A','A131313','Laura','Beltrán','Gran Vía, 23','Madrid','912121212'),TABLATITULACIÓN(TITULACIÓNOBJ('160000','Empresariales',TABLAASIGNATURA(ASIGNATURAOBJ('160002','Contabilidad',1,1,6,70,'P117')))));
Insert into MATRICULACIÓN (NUM_MATRÍCULA,ALUMNO,TITULACIÓN) values (9,ALUMNOOBJ('07634664I','A232358','Benito','Encinas','Polar, 67','Madrid','916436467'),TABLATITULACIÓN(TITULACIÓNOBJ('110053','Informática Sistemas',TABLAASIGNATURA(ASIGNATURAOBJ('856557','Algoritmos y estructuras de datos I',2,2,9,67,'P500'),ASIGNATURAOBJ('076767','Ampliación de informática gráfica',4,1,6,658.89,'P500'),ASIGNATURAOBJ('323336','Algoritmos y estructuras de datos II',3,2,4.5,45.67,'P500')))));
Insert into MATRICULACIÓN (NUM_MATRÍCULA,ALUMNO,TITULACIÓN) values (10,ALUMNOOBJ('32456245H','A256346','Gustavo','Pérez','Numancia, 234','Valencia','947676576'),TABLATITULACIÓN(TITULACIÓNOBJ('110055','Ingeniero en Informática',TABLAASIGNATURA(ASIGNATURAOBJ('897478','Ampliación de inteligencia artificial',4,2,9,56.89,'P600'),ASIGNATURAOBJ('896476','Arquitecturas avanzadas',3,2,9,34.89,'P600'),ASIGNATURAOBJ('786476','Análisis de datos',2,2,9,76.89,'P999'),ASIGNATURAOBJ('986796','Arquitectura e Ingenieria de los computadores',3,2,6,45.89,'P600')))));
Insert into MATRICULACIÓN (NUM_MATRÍCULA,ALUMNO,TITULACIÓN) values (11,ALUMNOOBJ('76453435G','A344746','Joaquín','Carmona','Caracas, 12','Valencia','937634566'),TABLATITULACIÓN(TITULACIÓNOBJ('110052','Ingeniero Industrial',TABLAASIGNATURA(ASIGNATURAOBJ('213123','Automatización industrial',2,2,6,78.89,'P303'),ASIGNATURAOBJ('872464','Ampliación de electrónica',2,1,6,56.09,'P203')))));
Insert into MATRICULACIÓN (NUM_MATRÍCULA,ALUMNO,TITULACIÓN) values (12,ALUMNOOBJ('57632786G','A444378','Susana','Moral','Gran Vía, 35','Guadalajara','915762646'),TABLATITULACIÓN(TITULACIÓNOBJ('110054','Informática Gestión',TABLAASIGNATURA(ASIGNATURAOBJ('123536','Ampliación de estructura de computadores',3,2,4.5,68.89,'P600'),ASIGNATURAOBJ('765376','Antecedentes y evolución de la informática',2,2,6,87.56,'P202'),ASIGNATURAOBJ('634437','Administración avanzada de sistemas informáticos',3,1,9,110.89,'P415'),ASIGNATURAOBJ('232325','Ampliación de redes',3,1,6,78.9,'P888'),ASIGNATURAOBJ('324234','Aplicaciones específicas de red',3,1,4.5,67.67,'P888'),ASIGNATURAOBJ('097343','Algoritmos paralelos',3,1,6,78,'P500'),ASIGNATURAOBJ('455457','Álgebra',2,1,4.5,78,'P415')))));
Insert into MATRICULACIÓN (NUM_MATRÍCULA,ALUMNO,TITULACIÓN) values (13,ALUMNOOBJ('44212123J','A465665','Paloma','Morales','Gotan, 34','Madrid','917636436'),TABLATITULACIÓN(TITULACIÓNOBJ('110055','Ingeniero en Informática',TABLAASIGNATURA(ASIGNATURAOBJ('986796','Arquitectura e Ingenieria de los computadores',3,2,6,45.89,'P600'),ASIGNATURAOBJ('897478','Ampliación de inteligencia artificial',4,2,9,56.89,'P600'),ASIGNATURAOBJ('896476','Arquitecturas avanzadas',3,2,9,34.89,'P600'),ASIGNATURAOBJ('786476','Análisis de datos',2,2,9,76.89,'P999')))));
Insert into MATRICULACIÓN (NUM_MATRÍCULA,ALUMNO,TITULACIÓN) values (14,ALUMNOOBJ('86546543R','A653344','Rufino','Mellado','Rufino, 45','Sevilla','948765676'),TABLATITULACIÓN(TITULACIÓNOBJ('110052','Ingeniero Industrial',TABLAASIGNATURA(ASIGNATURAOBJ('872464','Ampliación de electrónica',2,1,6,56.09,'P203'),ASIGNATURAOBJ('213123','Automatización industrial',2,2,6,78.89,'P303')))));
Insert into MATRICULACIÓN (NUM_MATRÍCULA,ALUMNO,TITULACIÓN) values (15,ALUMNOOBJ('84545680F','A654455','Daniel','Chavero','jázmin, 34','Madrid','917664764'),TABLATITULACIÓN(TITULACIÓNOBJ('110054','Informática Gestión',TABLAASIGNATURA(ASIGNATURAOBJ('123536','Ampliación de estructura de computadores',3,2,4.5,68.89,'P600'),ASIGNATURAOBJ('634437','Administración avanzada de sistemas informáticos',3,1,9,110.89,'P415'),ASIGNATURAOBJ('097343','Algoritmos paralelos',3,1,6,78,'P500'),ASIGNATURAOBJ('455457','Álgebra',2,1,4.5,78,'P415')))));
Insert into MATRICULACIÓN (NUM_MATRÍCULA,ALUMNO,TITULACIÓN) values (16,ALUMNOOBJ('63456432G','A747647','Esther','Barahona','Valencia, 123','Valencia','935476548'),TABLATITULACIÓN(TITULACIÓNOBJ('110052','Ingeniero Industrial',TABLAASIGNATURA(ASIGNATURAOBJ('872464','Ampliación de electrónica',2,1,6,56.09,'P203'),ASIGNATURAOBJ('213123','Automatización industrial',2,2,6,78.89,'P303')))));
Insert into MATRICULACIÓN (NUM_MATRÍCULA,ALUMNO,TITULACIÓN) values (17,ALUMNOOBJ('76666436D','A754576','Gerardo','Prado','Del Olmo, 145','Madrid','917643643'),TABLATITULACIÓN(TITULACIÓNOBJ('130110','Matemáticas',TABLAASIGNATURA(ASIGNATURAOBJ('130113','Programación I',1,1,9,60,'P101'),ASIGNATURAOBJ('130122','Análisis II',2,2,9,60,'P203'),ASIGNATURAOBJ('976677','Análisis matemático',3,2,6,764.89,'P203')))));
Insert into MATRICULACIÓN (NUM_MATRÍCULA,ALUMNO,TITULACIÓN) values (18,ALUMNOOBJ('54343433T','A796476','Alfonso','Cuevas','Valencia, 45','Valencia','937845754'),TABLATITULACIÓN(TITULACIÓNOBJ('130110','Matemáticas',TABLAASIGNATURA(ASIGNATURAOBJ('976677','Análisis matemático',3,2,6,764.89,'P203'),ASIGNATURAOBJ('130122','Análisis II',2,2,9,60,'P203'),ASIGNATURAOBJ('130113','Programación I',1,1,9,60,'P101')))));
Insert into MATRICULACIÓN (NUM_MATRÍCULA,ALUMNO,TITULACIÓN) values (19,ALUMNOOBJ('12354123T','A834532','Gregorio','Llamas','Ro, 67','Sevilla','942133336'),TABLATITULACIÓN(TITULACIÓNOBJ('110052','Ingeniero Industrial',TABLAASIGNATURA(ASIGNATURAOBJ('872464','Ampliación de electrónica',2,1,6,56.09,'P203'),ASIGNATURAOBJ('213123','Automatización industrial',2,2,6,78.89,'P303')))));

1)如何更新“matriculación”(注册)表中的“titulación”(大学学位)字段,但该字段“titulación”只是子字段“nombre”(名称)?如果我尝试像

那样的话
update TABLE(SELECT titulación FROM matriculación ) set nombre = 'aaa';

我得到一个错误SQL:ORA-01427:“单行子查询返回多行”

除了使用PL / SQL之外别无他法?

2)问题1的相同更新,但只更新那些具有特定名称的“titulación”。

这是使用PL / SQL的解决方案,但目标是避免它,使用纯SQL语句

declare 
  TYPE referencias_matrícula IS TABLE OF pls_integer;
  matrículas referencias_matrícula;
  TYPE referencias_titulación IS TABLE OF varchar2(6);
  titulaciones referencias_titulación;
begin
  SELECT num_matrícula, titu.idtitulación BULK COLLECT INTO matrículas, titulaciones FROM matriculación m, table(m.titulación) titu where nombre = 'Matemáticas';

  for índice in matrículas.FIRST .. matrículas.LAST loop
    update TABLE(SELECT titulación FROM matriculación where  num_matrícula = matrículas(índice)) set nombre = 'Ingeniería de Núm. Perfectos'
    where idtitulación = titulaciones(índice);
  end loop;
end;
/

1 个答案:

答案 0 :(得分:2)

我没有使用嵌套表,但这对我有用:

update /*+ NESTED_TABLE_GET_REFS */ Titulaciones_Tabla   -- <- storage table
  set nombre = 'aaa'
  where nombre = 'Matemáticas';

从此网站Oracle SQL Hints

  

NESTED_TABLE_GET_REFS

     

用法:NESTED_TABLE_GET_REFS

     

描述:通过此提示,用户可以直接访问嵌套表。

您可能也对clauses RETURN AS LOCATORRETURN AS VALUE感兴趣。