2015-05-01 74 views
1

每天,我都會將(使用crontab,php腳本)保存到數據庫錯誤信息中。每一行是這樣的: (Bugidentification,日期,標題,誰,等...)如何創建sql數據的歷史記錄? (報告數據更改)

(如: Bugidentification,日期,標題,誰,等...

issue1,2015 - 04-01,布拉布拉,票據等..

issue2,2015-04-01,NNNNNNN,約翰,等等

issue3,2015-04-01,vvvvvvv,格雷格等。 ..

issue1,2015-04-02,blabla,bill,etc ...

issue2,2015年4月2日,NNNNNNN,約翰,等等

issue3,2015年4月2日,vvvvvvv,馬里奧,等等......(這裏現在是馬里奧)

issue2,2015年4月3日,NNNNNNN,約翰,等等...(issue1 dissapeared)

issue3,2015年4月3日,vvvvvvv,TOD等...(TOD是新信息)

issue4,2015-04-03,rrrrrrrr,john等...(issue4 is new)

... .......................................... )

基本上if我採取例如我上面貼的結果應該是這樣的4月2日的日期,4月3日之間的比較

新行:issue4

封閉式行:Issue1

更新的行是:Issue3(用tod代替馬里奧)

沒有變化的行是:Issue2

在我的情況下,有數百行,我相信我知道如何做到這一點,感謝PHP,但我的代碼將很長時間像創建foreach循環,並一個接一個地看到,如果有任何改變。我不知道我正在得到直接的解決方案。

所以我的問題是,有沒有簡單的方法來報告這些變化與「簡單」的代碼(如SQL特殊要求或任何項目代碼或簡單的PHP函數?)。

+0

可能你需要一個'SELECT'語句和一個'WHERE'條件,日期'BETWEEN'。通過這種方式,您將能夠從數據庫中僅獲取感興趣的行 – mucio

+0

感謝您的回覆,但我的觀點是在兩個日期之間精確比較,然後知道哪一行是新的,哪一行是關閉的,哪一行更新哪一行不變。 – Oeiloff

+0

最好的事情是,如果你也發佈了一個輸入參數的例子和你期望的最終結果 – mucio

回答

1

這個設計中有太多的假設。這些假設要求您比較不同日子之間的行,以便首先進行假設 - 更不用說,您必須將未更改的行從一天覆制到下一天,以便維護完成假設所需的每日不間斷條目。呼。規則1:不要在設計中建立假設。如果有什麼新東西的話,應該標註「嘿,我是新來的!」當數據發生改變時,「好的,改變了一些東西。」當問題終於結束時,「好吧,這就是我的,我完了。」

create table Bug_Static(-- Contains one entry for each bug 
    ID  int identity, 
    Opened date not null default sysdate, 
    Closed date [null | not null default date '9999-12-31'], 
    Title varchar(...), 
    Who id references Who_Table, 
    <other non-changing data>, 
    constraint PK_Bug_Static primary key(ID) 
); 
create table Bug_Versions(-- Contains changing data, like status 
    ID  int not null, 
    Effective date not null, 
    Status varchar not null, -- new,assigned,in work,closed,whatever 
    <other data that may change from day to day>, 
    constraint PK_Bug_Versions primary key(ID, Effective), 
    constraint FK_Bug_Versions_Static foreign key(ID) 
     references Bug_Static(ID) 
); 

現在您可以在任何給定日期選擇錯誤和當前數據(最後一次更改)。

select s.ID, s.Opened, s.Title, v.Effective, v.Status 
from Bug_Static s 
join Bug_Versions v 
    on v.ID = s.ID 
    and v.Effective =(
     select Max(Effective) 
     from Bug_Versions 
     where ID = v.ID 
      and Effective <= sysdate) 
where s.Closed < sysdate; 

where s.Closed < sysdate是可選的。給你的是在查詢執行的日期關閉的所有錯誤,但不是在那之前關閉的錯誤。這樣可以讓被封閉的bug不斷重複出現 - 除非這是你想要的。

更改sysdate值到特定的日期/時間,你將得到的數據,因爲它似乎爲日期和時間。

通常情況下,當創建一個bug,一行進入這兩個表。然後,只有新版本作爲狀態或任何其他數據更改輸入。如果一天沒有變化,則不會輸入任何內容。然後,當錯誤最終關閉時,靜態表的Closed字段會更新,並且版本表中會插入closed版本。我已經在Closed字段中顯示了兩個選項,即null或定義的「最大日期」爲9999年12月31日。您可以使用任意一個,但我喜歡max date方法。它簡化了查詢。

我也要與前面一對夫婦的意見,其連接表這兩個表。一個只顯示每個錯誤(Bug_Current)的最新版本,另一個顯示每個錯誤(Bug_History)的每個版本。使用Bug_Current上的觸發器,它可以是應用程序用來更改錯誤的觸發器。例如,它會改變任何版本化字段到新版本插入的更新。

的一點是,這是一個非常靈活的設計,你可以很容易地只顯示你想要你想要的數據,爲你想要的任何時間。

+0

您好, 非常感謝您的詳細反饋。 對我而言,設計的一部分不是來自我,我必須處理它。無論如何,我同意你的解決方案要更加優化。由於我無法改變現有的設計,我唯一的解決方案是創建PHP腳本。其實我的問題的起源是要知道簡單的命令是否可以解決它。看起來不是, – Oeiloff

+0

這就是爲什麼我強調每當我可以使用視圖的重要性。應用程序代碼不應直接訪問表。當他們這樣做時,如果允許的話,稍作改動就會花費大量的時間和精力。當他們接觸的都是視圖時,對錶格的改變是常規的。只需更新相關的視圖,應用程序代碼甚至不知道進行了更改。太簡單。 – TommCatt

相關問題