Foreign Key

 Hola a todos!

 

Tengo un problemilla con unas tablas que nose como solucionar. Tengo una tabla llamada SMSC con sus campos (id, type) y quiero crear una clave foranea que dependiendo del dato que se introduzca, la información vaya a una tabla u otra. Alguien sabe como solucionar esto?

 

gracias de antemano. 

Las claves foráneas no pueden ser condicionales. No sé si he entendido bien lo que quieres hacer, pero si quieres garantizar la integridad referencial de diferentes tipos de datos hacia diferentes 'tablas maestras' lo normal sería que utilizaras un campo para cada tipo de dato.

De todas maneras, si me indicas todas las tablas y campos que quieres relacionar a lo mejor lo veo más claro.

Un saludo,

En respuesta a por Carlos

Hola carlos te comento mejor las tablas que quiero relacionar.

Me gustaría que dependiendo de los datos que se introdujeran en la tabla SMSC, esta indicase a SMSC_KANNEL O SMSC_HUB, ademas en un futuro se añadirian mas tablas (ejemplo: SMSC_CLAR)

SMSC_KANNEL                                       SMSC_HUB                                         SMSC

id                     number(11)                        id                   number(11)                     id               number(11)

smsc_name      varchar2(100)                     correlator        varchar2(20)                    type           varchar2(50)

shortcode         varchar2(10)                       shortcode        varchar2(10)                   path            varchar2(255)

host                 varchar2(255)                     mask              varchar2(100)                  smsc_id     number(11)

path                 varchar2(255)                     ok_time           varchar2(255)

user                 varchar2(255)                     allowed_dig      number(11)

pass                varchar2(255)                     status              varchar2(3)

mask               varchar2(100)         

ok_time           varchar2(255)

allowed_dig      number(11)

 

saludos y gracias

En respuesta a por mariomario89

Pues la cosa va por donde te decía. Como la FK no puede ser condicional ni apuntar a dos tablas distintas a la vez tendrías que crear en SMSC un campo para cada tabla externa. Serían SMSC_KANNEL_id y SMSC_HUB_id, por ejemplo, y para cada campo definir una clave foránea hacia su tabla.

Si por alguna razón necesitas mantener un maestro de identificadores con el campo 'smsc_id' como identificador compartido para ambas tablas otra opción sería crear una tabla de relaciones, y definir en ella una FK hacia SMSC, y otras hacia las otras dos tablas, cuyos id's también estarían en campos distintos, aunque para mi esta opción es complicarte un poco la vida.

Tabla_SMSC_REL smsc_id (FK hacia SMSC) smsc_kannel_id (FK hacia SMSC_KANNEL) smsc_hub_id (FK hacia SMSC_HUB)

 

Saludos,

En respuesta a por mariomario89

Parece una buena opción. Con un trigger no podrás asegurar la integridad referencial, pero sí que es verdad que puedes automatizar la introducción de datos haciendo que cada vez que se inserte un registro en la tabla 'maestra' SMSC el trigger cree un nuevo registro en la tabla que corresponda, según el tipo. Otro tema es que supongo que también tendrás que informar los otros campos de las tablas SMSC, no?

Si quieres probar puedes crear para la tabla SMSC un trigger del tipo 'AFTER INSERT'. Te enlazo un ejemplo de utilización de triggers, la documentación de Oracle sobre triggers, y copio un ejemplo completito de esta misma documentación:

CREATE OR REPLACE TRIGGER order_info_insert
   INSTEAD OF INSERT ON order_info
   DECLARE
     duplicate_info EXCEPTION;
     PRAGMA EXCEPTION_INIT (duplicate_info, -00001);
   BEGIN
     INSERT INTO customers
       (customer_id, cust_last_name, cust_first_name) 
     VALUES (
     :new.customer_id, 
     :new.cust_last_name,
     :new.cust_first_name);
   INSERT INTO orders (order_id, order_date, customer_id)
   VALUES (
     :new.order_id,
     :new.order_date,
     :new.customer_id);
   EXCEPTION
     WHEN duplicate_info THEN
       RAISE_APPLICATION_ERROR (
         num=> -20107,
         msg=> 'Duplicate customer or order ID');
   END order_info_insert;
/

 

Hola Mario, no entienfo bien lo que pides? pero te recuerdo que una clave foranea verifica que se cumpla con la

integridad referencial. es decir que no se pueda insertar  en una tabla "hija" un valor en un determinado campo si 

ese campo esta apuntando a una tabla "padre" y no existe un registo con ese valor es esta tabla.

si es esto lo que quieres hacer, lo puedes solucionar con un trigger, te paso como deberia de ser para que tengas

una idea,  tu corrige los errores.

create or replace trigger smsc
before insert on smsc
cuenta number:=0;
begin

 if :new.id<10000 then
  select count(*) into cuenta from smsc_kannel a where a.id=:new.id;
 else
  select count(*) into cuenta from smsc_hub a where a.id=:new.id;
 endif;

 if cuenta>0 then
  insert into smsc values(:new.id, :new.type,... );
 else
    RAISE_APPLICATION_ERROR (-20100,'No existe el ID en la tabla maestra');
 endif;
end;

 

Esto deberia andar solucionados los errores, si quieres simular la opcion ON DELETE CASCADE de la clave

foranea tendrias que hacer 2 trigger mas, para cuando borres en kannel o hub que te borre en smsc.

Bueno Mario espero te sirva.

Saludos