2015-07-24 6 views
5

Desidero creare una vista SQL basata su un database con tabelle della cronologia.Creazione di una vista basata sulle tabelle della cronologia

Qual è la soluzione migliore (veloce ed efficiente) per farlo. Non ho creato l'applicazione e non riesco ad aggiornare le tabelle del database. Posso solo creare viste.

Qui è il contesto:

La mia applicazione gestisce i contratti. Un contratto ha informazioni generali ed è collegato a contatti, riferimenti legali e portafogli. Al termine di un aggiornamento, viene aggiunta una nuova riga nelle tabelle della cronologia (nuovo ID_HIST). Se viene effettuato un aggiornamento sui contatti, riferimenti legali o portafogli, viene aggiunta una nuova riga nella tabella contract_HIST (con lo stesso ID_HIST).

Il mio scopo è la creazione di una vista per visualizzare gli aggiornamenti fatto su una riga (HIST ID) rispetto al precedente HIST ID come:

enter image description here

Così per ogni nuovo aggiornamento (per una specifica data desiderata, data grazie a ID HIST), possiamo vedere se sono state aggiornate le informazioni generali, i contatti, i riferimenti legali e/oi portfoli.

Di seguito la struttura del database:

enter image description here

enter image description here

Qui nella tabella uno o più portafogli può essere assegnato a un contratto per un stesso aggiornamento.

Per informazioni: se per esempio durante un nuovo aggiornamento, i contatti sono stati cancellati per un contratto, una nuova riga (con un nuovo ID_HIST) viene aggiunta in contratto_hist per questo contratto MA non viene aggiunta nessuna nuova riga nella tabella contact_hist . È lo stesso per riferimento legale e portafogli.

Qui la vista deve visualizzare:

enter image description here

Qui gli script per il database per il test:

-------------------------------------------------------- 
-- DDL for Table CONTACT_HIST 
-------------------------------------------------------- 

    CREATE TABLE "CONTACT_HIST" 
    ( "ID_HIST" NUMBER, 
    "ID_CONTRAT" NUMBER, 
    "NAME_CONTACT" VARCHAR2(20 BYTE) 
    ) SEGMENT CREATION IMMEDIATE 
    PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255 
NOCOMPRESS LOGGING 
    STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645 
    PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 
    BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT) 
    TABLESPACE "RAM" ; 
REM INSERTING into BO.CONTACT_HIST 
SET DEFINE OFF; 
Insert into BO.CONTACT_HIST (ID_HIST,ID_CONTRAT,NAME_CONTACT) values (1,1,'Bernard'); 
Insert into BO.CONTACT_HIST (ID_HIST,ID_CONTRAT,NAME_CONTACT) values (1,1,'Jean'); 
Insert into BO.CONTACT_HIST (ID_HIST,ID_CONTRAT,NAME_CONTACT) values (2,1,'Nicolas'); 
Insert into BO.CONTACT_HIST (ID_HIST,ID_CONTRAT,NAME_CONTACT) values (2,1,'Jean'); 
Insert into BO.CONTACT_HIST (ID_HIST,ID_CONTRAT,NAME_CONTACT) values (3,2,'Nicolas'); 
Insert into BO.CONTACT_HIST (ID_HIST,ID_CONTRAT,NAME_CONTACT) values (5,2,'Nicolas'); 

-------------------------------------------------------- 
-- DDL for Table CONTRAT_HIST 
-------------------------------------------------------- 

    CREATE TABLE "BO"."CONTRAT_HIST" 
    ( "ID_HIST" NUMBER, 
    "DATE_CREATION" DATE, 
    "ID_CONTRAT" NUMBER, 
    "TITRE_CONTRAT" VARCHAR2(250 BYTE), 
    "DESCRIPTION" VARCHAR2(250 BYTE), 
    "BUDGET" NUMBER 
    ) SEGMENT CREATION IMMEDIATE 
    PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255 
NOCOMPRESS LOGGING 
    STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645 
    PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 
    BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT) 
    TABLESPACE "RAM" ; 
REM INSERTING into BO.CONTRAT_HIST 
SET DEFINE OFF; 
Insert into BO.CONTRAT_HIST (ID_HIST,DATE_CREATION,ID_CONTRAT,TITRE_CONTRAT,DESCRIPTION,BUDGET) values (1,to_date('01-JAN-15','DD-MON-RR'),1,'Contrat 1 ','Contrat Informatique ',20000); 
Insert into BO.CONTRAT_HIST (ID_HIST,DATE_CREATION,ID_CONTRAT,TITRE_CONTRAT,DESCRIPTION,BUDGET) values (2,to_date('15-JAN-15','DD-MON-RR'),1,'Contrat 1 ','Contrat Informatique ',50000); 
Insert into BO.CONTRAT_HIST (ID_HIST,DATE_CREATION,ID_CONTRAT,TITRE_CONTRAT,DESCRIPTION,BUDGET) values (3,to_date('02-FEB-15','DD-MON-RR'),2,'Contrat 2 ','Contrat Santé ',10000); 
Insert into BO.CONTRAT_HIST (ID_HIST,DATE_CREATION,ID_CONTRAT,TITRE_CONTRAT,DESCRIPTION,BUDGET) values (4,to_date('01-MAR-15','DD-MON-RR'),2,'Contrat 2 ','Contrat Consommateur ',30000); 
Insert into BO.CONTRAT_HIST (ID_HIST,DATE_CREATION,ID_CONTRAT,TITRE_CONTRAT,DESCRIPTION,BUDGET) values (5,to_date('01-JUL-15','DD-MON-RR'),1,'Contrat 1 ','Contrat Informatique ',50000); 
-------------------------------------------------------- 
-- DDL for Index CONTRAT_HIST_PK 
-------------------------------------------------------- 

    CREATE UNIQUE INDEX "BO"."CONTRAT_HIST_PK" ON "BO"."CONTRAT_HIST" ("ID_HIST") 
    PCTFREE 10 INITRANS 2 MAXTRANS 255 COMPUTE STATISTICS 
    STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645 
    PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 
    BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT) 
    TABLESPACE "RAM" ; 
-------------------------------------------------------- 
-- Constraints for Table CONTRAT_HIST 
-------------------------------------------------------- 

    ALTER TABLE "BO"."CONTRAT_HIST" ADD CONSTRAINT "CONTRAT_HIST_PK" PRIMARY KEY ("ID_HIST") 
    USING INDEX PCTFREE 10 INITRANS 2 MAXTRANS 255 COMPUTE STATISTICS 
    STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645 
    PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 
    BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT) 
    TABLESPACE "RAM" ENABLE; 
    ALTER TABLE "BO"."CONTRAT_HIST" MODIFY ("ID_HIST" NOT NULL ENABLE); 

-------------------------------------------------------- 
-- DDL for Table LEGAL_REFERENCE_HIST 
-------------------------------------------------------- 

    CREATE TABLE "BO"."LEGAL_REFERENCE_HIST" 
    ( "ID_HIST" NUMBER, 
    "ID_CONTRAT" NUMBER, 
    "LEG_REF_NAME" VARCHAR2(250 BYTE) 
    ) SEGMENT CREATION IMMEDIATE 
    PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255 
NOCOMPRESS LOGGING 
    STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645 
    PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 
    BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT) 
    TABLESPACE "RAM" ; 
REM INSERTING into BO.LEGAL_REFERENCE_HIST 
SET DEFINE OFF; 
Insert into BO.LEGAL_REFERENCE_HIST (ID_HIST,ID_CONTRAT,LEG_REF_NAME) values (1,1,'45 - Technologies et Systeme d''Information'); 
Insert into BO.LEGAL_REFERENCE_HIST (ID_HIST,ID_CONTRAT,LEG_REF_NAME) values (2,2,'105 - Consommateur et Santé'); 
Insert into BO.LEGAL_REFERENCE_HIST (ID_HIST,ID_CONTRAT,LEG_REF_NAME) values (5,1,'27 - Services'); 

-------------------------------------------------------- 
-- DDL for Table PORTFOLIO_HIST 
-------------------------------------------------------- 

    CREATE TABLE "BO"."PORTFOLIO_HIST" 
    ( "ID_HIST" NUMBER, 
    "ID_CONTRAT" NUMBER, 
    "PORTFOLIO_ID" NUMBER, 
    "PORTFOLIO_NAME" VARCHAR2(250 BYTE), 
    "PORTFOLIO_VALUE" NUMBER 
    ) SEGMENT CREATION IMMEDIATE 
    PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255 
NOCOMPRESS LOGGING 
    STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645 
    PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 
    BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT) 
    TABLESPACE "RAM" ; 
REM INSERTING into BO.PORTFOLIO_HIST 
SET DEFINE OFF; 
Insert into BO.PORTFOLIO_HIST (ID_HIST,ID_CONTRAT,PORTFOLIO_ID,PORTFOLIO_NAME,PORTFOLIO_VALUE) values (2,1,1,'Portfolio 1',5000); 
Insert into BO.PORTFOLIO_HIST (ID_HIST,ID_CONTRAT,PORTFOLIO_ID,PORTFOLIO_NAME,PORTFOLIO_VALUE) values (2,1,2,'Portfolio 2',7000); 
Insert into BO.PORTFOLIO_HIST (ID_HIST,ID_CONTRAT,PORTFOLIO_ID,PORTFOLIO_NAME,PORTFOLIO_VALUE) values (4,2,1,'Portfolio 1',2000); 
Insert into BO.PORTFOLIO_HIST (ID_HIST,ID_CONTRAT,PORTFOLIO_ID,PORTFOLIO_NAME,PORTFOLIO_VALUE) values (4,2,2,'Portfolio 2',8000); 
commit; 
+2

Puoi fare un [violino] (http://sqlfiddle.com) fuori da questo? –

+0

ciao coeurdange57, che dire della mia soluzione accusa? ha aiutato ?? –

risposta

1

qui andiamo:

prima: creare una funzione memorizzata (o una funzione in un pacchetto) li ke questo:

create or replace function test_history(i_contract_id in number, 
             i_date_created in date, 
             i_type   in varchar2) 
    return varchar2 is 
    l_sql varchar2(1000); 
    l_result number; 
begin 
    l_sql := 'select 1 from test_history_tb where id_contract = :1 and date_creation = :2 and ' || 
      i_type || ' = :3 and rownum = 1'; 
    execute immediate l_sql 
    into l_result 
    using i_contract_id, i_date_created, 'update'; 

    return('update'); 

exception 
    when no_data_found then 
    return('no_update'); 
end; 

Secondo: creare la query in base alla funzione:

create view xxx as 

select id_contract, date_creation, 
     test_history(a.id_contract, a.date_creation, 'general_info') general_info, 
     test_history(a.id_contract, a.date_creation, 'contract') contract, 
     test_history(a.id_contract, a.date_creation, 'legal') legal, 
     test_history(a.id_contract, a.date_creation, 'portfolio') portfolio 
from test_history_tb a 
group by a.id_contract, a.date_creation; 

questa soluzione non è così veloce, perché per ogni riga abbiamo una chiamata di funzione. ma se si filtrano i dati con una clausola where, sarebbe un'alternativa.

i dati di esempio nella tabella: enter image description here

...ed ecco come appare la query sulla vista: enter image description here

+0

Hack intrecciato per utilizzare SQL dinamico all'interno di una funzione chiamata in un'istruzione select. Non sapevo nemmeno che fosse permesso. –

+0

Lo uso molto raramente e solo su tabelle con meno dati (o una clausola where), a causa delle prestazioni. –