cambiar titulo a un plan vigente

Hola, necesitamos cambiar un titulo a un plan de una carrera, el plan esta vigente, buscando encontre alguien que hizo lo mismo de la siguiente forma y pudo cambiarlo :

begin work;
set constraints all deferred;
set triggers for sga_titulos_plan disabled;
update sga_titulos_plan
set titulo=‘00046’
where carrera=‘AF4’ and
plan = ‘00031’ ;
set triggers for sga_titulos_plan enabled;
commit work;

Yo corro este scrip , pero me da error como que la tabla no esta en modo exclusivo ??? no entiendo , lo hago en una base de prueba y estoy yo solo conectado.
Esto es lo que me dice :

Mode set.
1 row updated.
[Informix][Universal Server][dbalumnado_123] SQL Error (-692) : Key value for constraint (dba.pk_titulos_plan) is still being referenced.

No entiendo¡¡¡¡¡¡¡ por un lado me hace el Update y a continuacion el error…

desde ya muchas gracias…

Lo que sucede es que al correr la sentencia “set constraints all deferred” lo que hace es que los constraints (fk, check, not null, …) no se evaluen en el momento del UPDATE, Sino al cerrar la transaccion en el COMMIT.
Con lo cual te dice que actualiza una fila, pero luego al hacer el commit es donde se evaluan las contraints, en este caso esa fk y por eso falla.

El problema que tenes que estas cambiando la pk de la tabla sga_titulos_plan y está pk esta siendo referenciada desde alguna de las dos tablas siguientes:

sga_orientaciones
sga_areas_x_titulo

Seguramente tu problema es la tabla sga_orientaciones. deberias hacer el mismo update de titulo en las orientaciones de ese plan que contengan ese título…
Algo asi:


begin work;
set constraints all deferred;

set triggers for sga_orientaciones disabled;
set triggers for sga_titulos_plan disabled;

update sga_orientaciones ......

update sga_titulos_plan .....

set triggers for sga_orientaciones enabled;
set triggers for sga_titulos_plan enabled;
commit work; 

Alejandro, hize lo que me recomendaste pero persiste el error

Adjunto el Scrip y el resultado de la ejecucion.

begin work;

set constraints all deferred;

set triggers for sga_orientaciones disabled;
set triggers for sga_titulos_plan disabled;

–update sga_orientaciones …

update sga_orientaciones set titulo=‘00046’
where
carrera=‘AF4’ and plan = ‘00031’ ;

–update sga_titulos_plan …

update sga_titulos_plan set titulo=‘00046’
where
carrera=‘AF4’ and plan = ‘00031’ ;
set triggers for sga_orientaciones enabled;
set triggers for sga_titulos_plan enabled;
commit work;

Executing all SQL statements in C:\informix\dbspru\cambio_plan_activo.sql.
Transaction started.
Constraints set.
Mode set.
Mode set.
1 row updated.
1 row updated.
[Informix][Universal Server][dbalumnado_123] SQL Error (-242) : Could not open database table (dba.sga_orientaciones). [ ISAM error -106 : ISAM error: non-exclusive access. ]

Fijate bien el where de cada UPDATE, que sea por la totalidad de los campos de la pk, en sga_orientaciones los campos de la pk son:
UNIDAD_ACADEMICA, CARRERA, PLAN, TITULO, ORIENTACION (en este caso no considerarias orientacin ya que lo cambia para todas las orientaciones en donde se encuentre el id de titulo a cambiar)

En sga_titulos_plan son:
UNIDAD_ACADEMICA, CARRERA, PLAN, TITULO

Y tenes que seguir viendo las tablas que estan relacionadas, como ser sga_ciclos_orient
Campos de la PK: UNIDAD_ACADEMICA, CARRERA, PLAN, VERSION, CICLO, TITULO, ORIENTACION

Alejando , yo relaciono las siguientes tablas;

sga_titulos
sga_titulos_plan
sga_orientaciones
sga_ciclos_orient
sga_atrb_mat_orie (sin datos)
sga_orient_cambios (sin datos)
sga_orient_alumno (sin datos)

hay alguna mas…

El error -242 habla de problemas en esa base, en el tablespace de la tabla sga_orientaciones o algun indice de esta tabla

corre el comando:

oncheck -cIidD nombre_base

Fijate si te da error en algun indice o tablespace…
Podrias correrlo primero para esa tabla:

oncheck -cIidD nombre_base:dba.sga_orientaciones

Alejandro te adjunto el resultado del oncheck


resultado_oncheck.txt (1.74 KB)

El oncheck sobre esas tablas da bien.

Probaste actualizar esta 4 tablas y sigue dando ese error -242?
sga_titulos
sga_titulos_plan
sga_orientaciones
sga_ciclos_orient

si, yo creo que da bien, me dice que el indice esta fragmentado, te envio el resultado de una para que veas y se repite en todas.

Validating indexes for dbalumnado_123:dba.sga_orientaciones…
Index 627_3153
Index fragment in DBspace siu_guarani
Index 627_4737
Index fragment in DBspace siu_guarani

WARNING: index check requires a s-lock on tables whose lock level

TBLspace data check for dbalumnado_123:dba.sga_orientaciones

no creo que este sea el problema …

no, no hay ningun problema ahi en ese checkeo.

Alejandro, Lo resovimos creando un nuevo plan con el titulo correspondiente y pasamos los alumnos .

Muchas gracias.

Recién leo este hilo… aunque no lo crean estaba aburrido así que me puse a mirar el foro… una pena que no haya sido antes, pero igual posteo por si ayuda a alguien más :smiley:

el primer error:

[Informix][Universal Server][dbalumnado_123] SQL Error (-692) : Key value for constraint (dba.pk_titulos_plan) is still being referenced.

Ya te dijeron que era porque el id del titulo que intentas actualizar esta siendo referenciado en tablas que dependen de la tabla que estas actualizando.

Usando “set constraints all deferred” te ahorras bastante… podés actualizar las tablas en cualquier orden.

Con la consulta que dejo a continuación averiguás las tablas con una columna llamada ‘titulo’ de tipo varchar(5) (en mi caso particular tengo 19 tablas con ese campo):

select tabname from systables where tabid in (
   select tabid from syscolumns where colname='titulo' and coltype=269 and collength=5
) and tabtype='T';

Con eso solo tenés que determinar si debes actualizar todas esas tablas o si en alguna el campo se llama igual, es del mismo tipo, pero no tiene relación.

Si no querés hacer ese análisis podrías usar alguna herramienta case que haga ingenieria inversa, te arme el DER y ver gráficamente todas las dependencias.

Si no dispones de esos recursos, podrías escribir una consulta que haga lo que las herramientas case o parecido… te dejo un ejemplo :smiley:

-- tablas que referencian a la tabla sga_titulos
select r.constrid, c.tabid, t.tabname
from sysreferences r
inner join sysconstraints c on r.constrid = c.constrid
inner join systables t on t.tabid = c.tabid
where r.ptabid = (select tabid from systables where tabname='sga_titulos');
-- me devuelve 2 tablas: sga_titulos_otorg sga_titulos_plan
-- y para esas tablas:
select r.constrid, c.tabid, t.tabname
from sysreferences r
inner join sysconstraints c on r.constrid = c.constrid
inner join systables t on t.tabid = c.tabid
where r.ptabid in (select tabid from systables where tabname in ('sga_titulos_otorg','sga_titulos_plan'));
--me devuelve 6 tablas: sga_areas_x_titulo sga_cmb_tit_otorg sga_menc_tit_otorg sga_orie_tit_otorg sga_tit_otor_form sga_orientaciones

En resumen, debes actualizar todas las tablas en que se use el ID que estás intentando cambiar. Con que en 1 sola tabla siga existiendo el viejo ID te dará error…

Como para que quede en el foro dejo un ejemplo de referencias cruzadas… si intentan insertar sin usar verificación recién al fin de la transacción les dará error porque usan referencias cruzadas… pero más que mil palabras que escriba dice un ejemplo:

-- creo 3 tablas de ejemplo:

CREATE TABLE prueba1 (
  c1 varchar(10) not null,
  x1 date,
  x2 varchar(30),
  c2 integer
);

CREATE TABLE prueba2 (
  c2 integer not null,
  x3 varchar(30),
  c3 char(5)
);

CREATE TABLE prueba3 (
  c3 char(5) not null,
  x4 varchar(30),
  c1 varchar(10)  
);

-- les declaro sus claves primarias
ALTER TABLE prueba1 ADD CONSTRAINT PRIMARY KEY (c1) CONSTRAINT pk_prueba1;
ALTER TABLE prueba2 ADD CONSTRAINT PRIMARY KEY (c2) CONSTRAINT pk_prueba2;
ALTER TABLE prueba3 ADD CONSTRAINT PRIMARY KEY (c3) CONSTRAINT pk_prueba3;

-- les declaro referencias cruzadas
ALTER TABLE prueba1 ADD CONSTRAINT (FOREIGN KEY (c2) REFERENCES prueba2 CONSTRAINT fk_prueba1_prueba2);
ALTER TABLE prueba2 ADD CONSTRAINT (FOREIGN KEY (c3) REFERENCES prueba3 CONSTRAINT fk_prueba2_prueba3);
ALTER TABLE prueba3 ADD CONSTRAINT (FOREIGN KEY (c1) REFERENCES prueba1 CONSTRAINT fk_prueba3_prueba1);

-- intento cargar datos de prueba (esto dará error)
INSERT INTO prueba1 (c1, x1, x2, c2) VALUES ('CLAVE C1 1', CURRENT, 'prueba', 1);
INSERT INTO prueba2 (c2, x3, c3) VALUES (1, 'otra prueba', 'C3001');
INSERT INTO prueba3 (c3, x4, c1) VALUES ('C3001','+ pruebas','CLAVE C1 1');

-- creo un SP que inserta bien :D
create procedure cargar_prueba()
   begin work; 
      set constraints all deferred;
      INSERT INTO prueba1 (c1, x1, x2, c2) VALUES ('CLAVE C1 1', CURRENT, 'prueba', 1);
      INSERT INTO prueba2 (c2, x3, c3) VALUES (1, 'otra prueba', 'C3001');
      INSERT INTO prueba3 (c3, x4, c1) VALUES ('C3001','+ pruebas','CLAVE C1 1');
      set constraints all immediate; 
   commit work; 
end procedure;

-- ejecuto una prueba
execute procedure cargar_prueba();

-- veo el resultado
select * from prueba1;
select * from prueba2;
select * from prueba3;

-- borro tablas de prueba
drop table prueba1;
drop table prueba2;
drop table prueba3;

con esto doy mis comentarios por terminados… este select busca las tablas con campos carrera, plan, titulo del tipo varchar(5):

select tabname from systables where tabid in (
select tabid from syscolumns where colname=‘titulo’ and coltype=269 and collength=5
) and tabid in (
select tabid from syscolumns where colname=‘plan’ and coltype=269 and collength=5
) and tabid in (
select tabid from syscolumns where colname=‘carrera’ and coltype=269 and collength=5
) and tabtype=‘T’ and tabname like ‘sga%’;

esa consulta me da 12 tablas:
sga_atrib_mat_orie,sga_orie_tit_otorg,sga_areas_x_titulo,sga_atmatorie_mg,sga_opt_gen_orie,sga_opt_gen_orie_a,
sga_orient_cambios,sga_orient_alumno,sga_ciclos_orient,sga_orientaciones,sga_titulos_plan,sga_titulos_otorg

No solo por una cuestión de referencias (que no verifiqué si todas las tablas están referenciadas), sino de consistencia de datos, deberías haber hecho update en todas las tablas… actualizando en todas las tablas deberías haber podido cambiar el plan.