2015-07-24 13 views
5

Ich möchte eine SQL-Ansicht basierend auf einer Datenbank mit Verlaufstabellen erstellen.Erstellen einer Ansicht basierend auf den Verlaufstabellen

Welches ist die beste Lösung (schnell und effizient), das zu tun. Ich habe die Anwendung nicht erstellt und kann die Datenbanktabellen nicht aktualisieren. Ich kann nur Ansichten erstellen. Hier

ist der Kontext:

Meine Anwendung verwaltet Verträge. Ein Vertrag hat allgemeine Informationen und ist mit Kontakten, rechtlichen Referenzen und Portfolios verknüpft. Wenn eine Aktualisierung abgeschlossen ist, wird eine neue Zeile in den Verlaufstabellen hinzugefügt (neue ID_HIST). Wenn für die Kontakte, Rechtsreferenzen oder Portfolios ein Update durchgeführt wird, wird in der Tabelle contract_HIST (mit demselben ID_HIST) ebenfalls eine neue Zeile hinzugefügt.

Mein Ziel ist die Schaffung einer Ansicht, die Updates auf einer Zeile (ID HIST) im Vergleich zum vorherigen ID HIST wie getan anzuzeigen:

enter image description here

So für jedes neue Update (für eine bestimmte Datum gesucht, gegeben dank ID HIST), können wir sehen, ob die allgemeinen Informationen, die Kontakte, die rechtlichen Hinweise oder/und die Portfolios aktualisiert wurden.

Hier unten ist der Struktur der Datenbank:

enter image description here

enter image description here

Hier in der Tabelle ein oder mehrere Portfolios können für eine gleiche Update zu einem Vertrag zugeordnet werden.

Zur Information: Wenn beispielsweise bei einem neuen Update die Kontakte für einen Vertrag gelöscht wurden, wird in contract_hist für diesen Vertrag eine neue Zeile (mit einem neuen ID_HIST) hinzugefügt, aber keine neue Zeile in der Tabelle contact_hist hinzugefügt . Dasselbe gilt für Rechtsverweise und Portfolios.

Hier sollte die Ansicht anzuzeigen:

enter image description here

Hier die Skripte für die Datenbank für die Prüfung:

-------------------------------------------------------- 
-- 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

Können Sie daraus eine [Geige] (http://sqlfiddle.com) machen? –

+0

hallo coeurdange57, was ist mit meiner propositionierten Lösung? Hat es geholfen ?? –

Antwort

1

hier gehen wir:

zuerst: erstellen eine gespeicherte Funktion (oder eine Funktion in einem Paket) li diese ke:

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; 

Sekunde: Erstellen Sie Ihre Abfrage auf der Funktion basiert:

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; 

diese Lösung ist nicht so schnell, weil für jede Zeile wir einen Funktionsaufruf haben. Aber wenn Sie die Daten mit einer Where-Klausel filtern, wäre das eine Alternative.

die Beispieldaten in der Tabelle: enter image description here

...und so sieht die Abfrage in der Ansicht aus: enter image description here

+0

Twisted Hack, um dynamische SQL innerhalb einer Funktion zu verwenden, die Sie in einer SELECT-Anweisung aufrufen. Wusste nicht einmal das ist erlaubt. –

+0

Ich benutze das sehr selten und nur für Tabellen mit weniger Daten (oder eine Where-Klausel), wegen der Leistung. –

Verwandte Themen