ORACLE - ORA-02449

ORA-02449: unique/primary keys in table referenced by foreign keys
FUNDAMENTOS
Cuando la clave primaria de una tabla A está siendo referenciada por una clave foránea de una tabla B, entonces no puedes eliminar la tabla A.
CASO
A continuación tienes un caso ilustrativo:
SQL> drop table empleado purge;
drop table empleado purge
           *
ERROR en lÝnea 1:
ORA-02449: unique/primary keys in table referenced by foreign keys
ENCONTRANDO LAS TABLAS RELACIONADAS
Cuando tienes muchas tablas en tu esquema, y no recuerdas cuales son esas tablas que te impiden eliminar una tabla, necesitas una consulta que te permita encontrar esas tablas que te generan el problema y analizar el caso.
A continuación tienes la consulta que te puede ayudar:
SELECT B.TABLE_NAME, B.CONSTRAINT_NAME, B.CONSTRAINT_TYPE, A.COLUMN_NAME
  FROM USER_CONS_COLUMNS A
  JOIN USER_CONSTRAINTS B
    ON B.R_OWNER = A.OWNER
   AND B.R_CONSTRAINT_NAME = A.CONSTRAINT_NAME
   AND B.CONSTRAINT_TYPE = 'R'
 WHERE A.TABLE_NAME = 'NOMBRE_TABLA';
Debes reemplazar NOMBRE_TABLA por el nombre de la tabla que quieres eliminar. De esta manera puedes identificar las tablas relacionadas que aún no has eliminado.
CASO - CONTINUACIÓN
A continuación tienes un caso ilustrativo:
SQL> SELECT B.TABLE_NAME, B.CONSTRAINT_NAME, B.CONSTRAINT_TYPE, A.COLUMN_NAME
  2    FROM USER_CONS_COLUMNS A
  3    JOIN USER_CONSTRAINTS B
  4      ON B.R_OWNER = A.OWNER
  5     AND B.R_CONSTRAINT_NAME = A.CONSTRAINT_NAME
  6     AND B.CONSTRAINT_TYPE = 'R'
  7   WHERE A.TABLE_NAME = 'EMPLEADO';

TABLE_NAME      CONSTRAINT_NAME                CONSTRAINT_TYPE    COLUMN_NAME
--------------- ------------------------------ ------------------ --------------------
ASIGNADO        FK_ASIGNADO_EMPLEADO           R                  CHR_EMPLCODIGO
CUENTA          FK_CUENTE_EMPLEADO             R                  CHR_EMPLCODIGO
MOVIMIENTO      FK_MOVIMIENTO_EMPLEADO         R                  CHR_EMPLCODIGO
En este caso, existen 3 tablas que tienes claves foráneas que estan haciendo referencia a la tabla EMPLEADO.
CODIGO FUENTE - EUREKA-WEB-MYSQL-SPRING
En esta sección te presento un video de una aplicación web desarrollada SPRING FRAMEWORK y MYSQL.
Tú tienes acceso al código fuente de esta aplicación, después del video tienes el enlace.



SPRING FRAMEWORK - EJECUTANDO PROCEDIMIENTOS ALMACENADOS

SPRING FRAMEWORK - EJECUTANDO PROCEDIMIENTOS ALMACENADOS
FUNDAMENTOS
Puedes usar cualquiera de los métodos query de JdbcTemplate o el método update para ejecutar el procedimiento almacenado, teniendo en cuenta si retorna o no un resultado.
Los procedimientos de SQL Server o MySQL pueden retornar directamente el resultado de una consulta utilizando la sentencia SELECT.
También dispones de la clase StoreProcedure donde dispones de opciones de mayor control para la ejecución de procedimientos almacenados.
SINTAXIS
El objetivo es ejecutar procedimientos almacenados que no tengan parametros de salida.
A continuación tienes la sintaxis que debes utilizar.
jdbcTemplate.update("call procedimiento (?, ?, ...)", parámetros);
PROCEDIMIENTO A EJECUTAR
El ejemplo que muestro a continuación es utilizando Oracle y el modelo es EUREKABANK, que lo encuentras en:
El procedimiento es para registrar una transacción que ejecuta un retiro de una cuenta.
create or replace procedure usp_egcc_retiro
(p_cuenta varchar2, p_importe number,p_empleado varchar2, p_clave varchar2)
as
  v_msg varchar2(1000);
  v_saldo number(12,2);
  v_moneda char(2);
  v_cont number(5,0);
  v_estado varchar2(15);
  v_costoMov number(12,2);
  v_clave varchar2(10);
begin
  -- Lee datos de la cuenta
  select 
    dec_cuensaldo, chr_monecodigo, int_cuencontmov, 
    vch_cuenestado, chr_cuenclave
    into v_saldo, v_moneda, v_cont, v_estado, v_clave
    from cuenta
    where chr_cuencodigo = p_cuenta 
    for update;
  -- Verifica los datos de la cuenta
  if v_estado != 'ACTIVO' then
    raise_application_error(-20001,'Cuenta no esta activa.');
  end if;
  if v_clave != p_clave then
    raise_application_error(-20001,'Datos incorrectos.');
  end if;
  -- Costo de operación
  select dec_costimporte
    into v_costoMov
    from costomovimiento
    where chr_monecodigo = v_moneda;
  -- Verifica el saldo
  v_saldo := v_saldo - p_importe - v_costoMov;
  if v_saldo < 0.0 then
    raise_application_error(-20001,'Saldo insuficiente.');
  end if;
  -- Actualiza la cuenta
  update cuenta
    set dec_cuensaldo = v_saldo,
    int_cuencontmov = int_cuencontmov + 2
    where chr_cuencodigo = p_cuenta;
  -- Registra el movimiento de retiro
  v_cont := v_cont + 1;
  insert into movimiento(chr_cuencodigo,int_movinumero,dtt_movifecha,
    chr_emplcodigo,chr_tipocodigo,dec_moviimporte,chr_cuenreferencia)
    values(p_cuenta,v_cont,sysdate,p_empleado,'004',p_importe,null);
  -- Registra el costo de la operación
  v_cont := v_cont + 1;
  insert into movimiento(chr_cuencodigo,int_movinumero,dtt_movifecha,
    chr_emplcodigo,chr_tipocodigo,dec_moviimporte,chr_cuenreferencia)
    values(p_cuenta,v_cont,sysdate,p_empleado,'010',v_costoMov,null);
  -- Confirmar la Tx
  commit;
exception
  when others then
    v_msg := sqlerrm; -- capturar mensaje de error
    rollback; -- cancelar transacción
    raise_application_error(-20001,v_msg);
end;
EJECUCIÓN DEL PROCEDIMIENTO
A continuación tienes el código Java para ejecutar el procedimiento usp_egcc_retiro:
public void procRetiro
(String cuenta, double importe,String codEmp, String clave) {

  jdbcTemplate.update("call usp_egcc_retiro (?, ?, ?, ?)", 
    cuenta, importe, codEmp, clave);

}
Debes tener en cuenta que la transacción es controlada en el procedimiento almacenado.
VIDEO DEMOSTRATIVO
CODIGO FUENTE - EUREKA-WEB-MYSQL-SPRING
En esta sección te presento un video de una aplicación web desarrollada SPRING FRAMEWORK y MYSQL.
Tú tienes acceso al código fuente de esta aplicación, después del video tienes el enlace.



SPRING FRAMEWORK - JDBC TRANSACCIONES

SPRING FRAMEWORK - TRANSACCIONES
FUNDAMENTOS
Una transacción en un Sistema de Gestión de Bases de Datos (SGBD), es un conjunto de operaciones (instrucciones) que se ejecutan formando una unidad de trabajo, es decir, en forma indivisible o atómica.
CONFIGURACIÓN DEL CONTEXTO
A continuación tienes un ejemplo de la configuración del contexto.
<bean id="dataSource"
  class="org.springframework.jdbc.datasource.DriverManagerDataSource">
  <property name="driverClassName" 
            value="oracle.jdbc.driver.OracleDriver" />
  <property name="url" 
            value="jdbc:oracle:thin:@localhost:1521:XE" />
  <property name="username" value="eureka" />
  <property name="password" value="admin" />
  </bean>
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> <property name="dataSource" ref="dataSource"/> </bean>
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource" /> </bean>
<tx:annotation-driven transaction-manager="transactionManager" />
PROGRAMACIÓN
A continuación tienes el formato de como debes programar un método donde debes implementar una transacción.
@Transactional(
    propagation=Propagation.REQUIRED, 
    rollbackForClassName={"Exception"}
)
public void insertar( [ parámetros ] ) throws Exception {

  // Proceso

}
EJEMPLO ILUSTRATIVO
El ejemplo que muestro a continuación es utilizando Oracle y el modelo es EUREKABANK, que lo encuentras en:
@Transactional(
  rollbackFor = Exception.class, 
  propagation = Propagation.REQUIRES_NEW)
public void procDeposito(String cuenta, double importe, String codEmp) {
  // Variables
  String sql;
  Map map;
  double saldo;
  int cont;
  // Paso 1: Leer datos de la cuenta
  sql = "select dec_cuensaldo, int_cuencontmov  " 
      + "from cuenta where chr_cuencodigo = ? " 
      + "for update ";
  map = jdbcTemplate.queryForMap(sql, cuenta);
  saldo = Double.parseDouble(map.get("dec_cuensaldo").toString());
  cont = Integer.parseInt(map.get("int_cuencontmov").toString());
  // Paso 2: Actualizar cuenta
  saldo += importe;
  cont++;
  sql = "update cuenta set dec_cuensaldo = ?, " 
    + "int_cuencontmov = ? " 
    + "where chr_cuencodigo = ? ";
  jdbcTemplate.update(sql, saldo, cont, cuenta);
  // Paso 3: Registrar movimiento
  sql = "insert into movimiento(chr_cuencodigo,int_movinumero,"
      + "dtt_movifecha,chr_emplcodigo,chr_tipocodigo,dec_moviimporte) " 
      + "values(?,?,SYSDATE,?,'003',?)";
  jdbcTemplate.update(sql, cuenta, cont, codEmp, importe);
}

VIDEO DEMOSTRATIVO
CODIGO FUENTE - EUREKA-WEB-MYSQL-SPRING
En esta sección te presento un video de una aplicación web desarrollada SPRING FRAMEWORK y MYSQL.
Tú tienes acceso al código fuente de esta aplicación, después del video tienes el enlace.