2015-12-25 10 views
0

請幫忙。我有兩張桌子。第一個被稱爲Reservation,第二個被稱爲LastOrders。如何使用過去的日期刪除行並將此行添加到其他表中?

在Date類型中有DATE_FROM列,在日期類型中也有DATE:)_ TO。我希望如果表中的日期在DATE_TO = SYSDATE列中保留,然後刪除此行並向表LastOrders插入新行,我認爲觸發器可以做到這一點,但我不知道如何。任何想法?非常感謝您,並有一個很好的聖誕節:)

TABLE RESERVATION 
Name      Null  Type   
-------------------------- -------- ------------- 
ID       NOT NULL VARCHAR2(25) 
DESCRIPTION    NOT NULL VARCHAR2(100)  
DATE_FROM     NOT NULL DATE   
DATE_TO     NOT NULL DATE 

TABLE LASTORDERS 
Name      Null  Type   
-------------------------- -------- ------------- 
ID       NOT NULL VARCHAR2(25) 
DESCRIPTION    NOT NULL VARCHAR2(100)  
DATE_FROM     NOT NULL DATE   
DATE_TO     NOT NULL DATE 
+0

表結構? – wogsland

+0

Date_From和Date_To代表什麼?你想要最新的Date_To值還是Date_To是「今天」的所有行?爲什麼你認爲一個觸發器可以處理它?......觸發事件是什麼事件? – TommCatt

回答

1

SQL Fiddle

的Oracle 11g R2架構設置

CREATE TABLE RESERVATION (
    ID   VARCHAR2(25) CONSTRAINT RESERVATION__ID__NN NOT NULL, 
    DESCRIPTION VARCHAR2(100) CONSTRAINT RESERVATION__DE__NN NOT NULL, 
    DATE_FROM DATE   CONSTRAINT RESERVATION__DF__NN NOT NULL, 
    DATE_TO  DATE   CONSTRAINT RESERVATION__DT__NN NOT NULL 
) 
/

CREATE TABLE LASTORDERS (
    ID   VARCHAR2(25) CONSTRAINT LASTORDERS__ID__NN NOT NULL, 
    DESCRIPTION VARCHAR2(100) CONSTRAINT LASTORDERS__DE__NN NOT NULL, 
    DATE_FROM DATE   CONSTRAINT LASTORDERS__DF__NN NOT NULL, 
    DATE_TO  DATE   CONSTRAINT LASTORDERS__DT__NN NOT NULL 
) 
/

CREATE PROCEDURE fulfilReservation(
    I_ID  IN RESERVATION.ID%TYPE, 
    O_SUCCESS OUT NUMBER 
) 
AS 
    r_reservation RESERVATION%ROWTYPE; 
BEGIN 
    DELETE FROM RESERVATION 
    WHERE ID = I_ID 
    AND SYSDATE BETWEEN DATE_FROM AND DATE_TO 
    RETURNING ID, DESCRIPTION, DATE_FROM, DATE_TO INTO r_reservation; 

    INSERT INTO lastorders VALUES r_reservation; 

    o_success := 1; 
EXCEPTION 
    WHEN NO_DATA_FOUND THEN 
    o_success := 0; 
END; 
/

INSERT INTO RESERVATION VALUES (1, 'Test', SYSDATE - 1, SYSDATE + 1) 
/

DECLARE 
    success NUMBER(1,0); 
BEGIN 
    fulfilReservation(1, success); 
END; 
/

查詢1

SELECT * FROM RESERVATION 

Results

No Results 

查詢2

SELECT * FROM LASTORDERS 

Results

| ID | DESCRIPTION |     DATE_FROM |     DATE_TO | 
|----|-------------|----------------------------|----------------------------| 
| 1 |  Test | December, 24 2015 18:59:07 | December, 26 2015 18:59:07 | 
+0

非常感謝!如何自動調用此過程? –

1

觸發器可以做這樣的工作,但它會在上表中的一些變化只火數據。如果您需要實時在表格之間移動數據,則必須使用作業。


    begin 
     dbms_scheduler.create_job(
     job_name => 'my_job', 
     job_type => 'PLSQL_BLOCK', 
     enabled => true, 
     repeat_interval => 'FREQ=DAILY; INTERVAL=1', 
     start_date => round(sysdate,'DD'), 
     job_action => 'begin 
      insert into LastOrders 
      select * 
      from Reservation 
      where DATE_TO = round(sysdate,''DD''); 

      delete Reservation where DATE_TO = round(sysdate,''DD'');  
      commit; 
     end;');  
    end; 

這項工作將每天00:00將數據從預留移到LastOrders。

+0

它正在工作!非常感謝你,新年快樂! :) –

0

Ooo,棘手的一個!

主要問題是你需要這個「實時」。您需要考慮數據在等式兩邊發生變化 - 也就是說,有新數據進入表格,應該與SYSDATE進行比較(這是簡單的部分)。另一邊是SYSDATE,每秒都在變化。所以,如果你需要你的數據儘可能準確,你基本上需要每秒檢查一次整個表,看是否有任何DATE_DO已經「到達」SYSDATE。這就是@Artem所建議的工作派上用場的地方。

運行作業每天一次意味着行將每天只有一次移動,並運行它的每一秒將意味着查詢表中的每一秒(潛在的性能開銷)。

所以,你必須聰明一點 -

  1. 上DATE_TO
  2. 添加一個索引確保在重複你正在做在桌子上 查詢使用綁定變量。即更改 作業中的查詢。
  3. 構建以智能的方式工作 - 比方說,你運行它每隔5 分鐘(因爲你不想讓你的潛在重查詢運行 每一秒),並且您檢查將在 達到SYSDATE線接下來的5分鐘。然後,您可以移動到僅包含這些行的 的臨時表,並且每秒鐘都有另一個作業運行。

聽起來有點複雜,但如果這個數據是按比例計劃的話,會爲您節省很多麻煩。

祝你好運,讓我知道你是否有任何問題。

相關問題