in

UGISS Community

Il sito della community dello User Group Italiano di SQL Server

Gestione e storicizzazione solo di alcuni campi

Last post 07-11-2008 17.03 by Navigator2. 4 replies.
Page 1 of 1 (5 items)
Sort Posts: Previous Next
  • 07-04-2008 21.06

    • raffaeu
    • Top 25 Contributor
    • Joined on 06-04-2007
    • Posts 44
    • Points 625

    Gestione e storicizzazione solo di alcuni campi

    La domanda e': gestire la storicizzazione di alcuni campi.

    Ho una tabella con 100 campi e devo gestire le modifiche solamente ad alcuni campi, nel senso che nel tempo eseguo degli update alla riga, che non cambia, ma cambia il valore di alcuni campi(2, 3). Pero' devo poter gestire lo storico di questi cambiamenti.

    Che soluzione utilizzate in questi casi, e perche'? Mi interessa molto un discorso improntato sulle performance nel fare poi le query o le viste. Ad esempio vorrei usare un campo SmallDateTime per gestire le modifiche al campo in una select del tipo MAX(dataCambiamento).

    Grazie. Big Smile

    Raffaele Garofalo
    NET Coder alle isole Bermuda
    MCAD.NET, MCTS Sharepoint
    blog: http://blog.raffaeu.com
    • Post Points: 35
  • 07-10-2008 22.42 In reply to

    Re: Gestione e storicizzazione solo di alcuni campi

    io in alcuni casi uso la clausola OUTPUT per tracciare i cambiamenti in una tabella di log.

    Le variazioni delle giacenze di un prodotto per esempio....
    se mi fanno un cambio di giacenza per una vendita o per un reso.... sulla riga di quel prodotto c'e' un update....
    oltre a modificare il campo di lastdateupdate, nello statement di update uso la clausola OUTPUT e metto vecchio valore e valore nuovo in una tabella di log.

    In quel modo ho lo storico della movimentazione per quel prodotto.

    Ciao

    Ale

    • Post Points: 5
  • 07-11-2008 8.45 In reply to

    • DiegoAllera
    • Top 25 Contributor
      Male
    • Joined on 10-20-2007
    • Belluno, IT
    • Posts 26
    • Points 360

    Re: Gestione e storicizzazione solo di alcuni campi

     Potresti anche usare un Trigger sull'evento di update, filtrando i dati che ti interessano dalla tabella virtuale deleted.

    Ad esempio:

    CREATE TRIGGER Riordino
       ON  Table1
       AFTER UPDATE
    AS
    BEGIN

        SET NOCOUNT ON;

        INSERT INTO Table2(id, medicationcode, qntOnStock, RequestedQnt, carriedoutqnt, completed, userid, orderdatetime, sent)
        SELECT 1, ins.medicationcode, 0, ins.reorderqnt, 0, 0, '', getdate(), 0 FROM deleted ins

    END

    In tale situazione ad ogni update di un record vado ad inserire i valori della tabella Table1(li selezione dalla tabella deleted), prima dell'update, nella tabella Table2 filtrando solo i dati che mi interessano.

    Diego
    • Post Points: 20
  • 07-11-2008 13.41 In reply to

    • raffaeu
    • Top 25 Contributor
    • Joined on 06-04-2007
    • Posts 44
    • Points 625

    Re: Gestione e storicizzazione solo di alcuni campi

    Ok, in pratica io ho uno standard da seguire, nel senso che ricevo i dati in una tabella nel seguendo modo

    [table](
    [id]
    ,[filed01]
    , [filed02]
    )

    Queste informazioni non possono essere cambiate perche' le riceviamo da dei customer. Qui pero' abbiamo un processo di Underwriting dei records quindi devo poter modificare solamente la [filed02] mantenendo il record originale. Quello a cui avevo pensato era una tabella chg_[filed] al cui interno in serisco un campo [id] che mi fa da Inner Join, un campo [value] con il nuovo valore ed un campo [date] popolato automaticamente con un getdate().

    Il problema e' che su una tabella con 100 fields e 30 fields sottoposte a underwriting devo costruire parallelamente 30 tabelle cgh_[field], una per ogni campo.

    Allo stesso tempo replicare tutto il record per sovrescrivere una o due fields, mi sembra un eccessivo dispendio di risorse, visto che l' underwriting viene fatto su una marea di records, a volte anche 300k ...

    Raffaele Garofalo
    NET Coder alle isole Bermuda
    MCAD.NET, MCTS Sharepoint
    blog: http://blog.raffaeu.com
    • Post Points: 20
  • 07-11-2008 17.03 In reply to

    Re: Gestione e storicizzazione solo di alcuni campi

     

    Ciao,

    prova a basarti su una soluzione di questo tipo

     

    Crei una tabella di LOG

    SET ANSI_NULLS ON

    GO

    SET QUOTED_IDENTIFIER ON

    GO

    SET ANSI_PADDING ON

    GO

    CREATE TABLE [dbo].[LogTabelle](

          [Id] [int] IDENTITY(1,1) NOT NULL,

          [Tabella] [varchar](200) NOT NULL,

          [Operatore] [varchar](100) NULL,

          [TipoOperazione] [varchar](10) NULL,

          [Record] [xml] NULL,

          [Data] [datetime] NULL DEFAULT (getdate()),

          [IdTabella] [int] NULL,

     CONSTRAINT [PK_LogAggiornamentiTabelle] PRIMARY KEY NONCLUSTERED

    (

          [Id] ASC

    )WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]

    ) ON [PRIMARY]

     

    GO

    SET ANSI_PADDING OFF

     

    E poi aggiungi un trigger alla tabella da tracciare come questo

     

    SET ANSI_NULLS ON

    GO

    SET QUOTED_IDENTIFIER ON

    GO

    ALTER TRIGGER [dbo].[Insert_Update_Delete_<nometabella>]

       ON  [dbo].[<nometabella>]

       AFTER INSERT,UPDATE, DELETE

    AS

    BEGIN

    SET NOCOUNT ON;

     

    begin try

      insert into dbo.LogTabelle(Tabella,Operatore,TipoOperazione,Record, IdTabella)

      SELECT '<nometabella>', SUSER_NAME(), CASE WHEN DEL.Id IS NULL THEN 'INSERT' ELSE 'UPDATE' END, XMLDOC, TAB.Id

      from dbo.<nometabella> TAB

           inner join inserted INS ON INS.Id = TAB.Id

           outer apply (select * from deleted DEL2 WHERE DEL2.Id = TAB.ID) DEL

           cross apply (select *

                        from dbo.<nometabella> TAB2

                        where TAB2.Id = TAB.Id

                        FOR XML RAW ('<nometabella>'), ELEMENTS, TYPE) AS RECXML(XMLDOC)

     

      insert into dbo.LogTabelle(Tabella,Operatore,TipoOperazione,Record, IdTabella)

      SELECT '<nometabella>', SUSER_NAME(), 'DELETE', XMLDOC, DEL.Id

      from deleted DEL

           cross apply (select *

                        from deleted TAB2

                        where TAB2.Id = DEL.Id

                        FOR XML RAW ('<nometabella>'), ELEMENTS, TYPE) AS RECXML(XMLDOC)

     

    end try

    begin catch

      -- gestione errore

    end catch

     

    END

     

    Con questa soluzione hai una tabella che contiene la traccia di tutte le modifiche effettuate ai record di qualsiasi tabella che tu voglia tenere sotto traccia

     

    Ciao

    Luca

    • Post Points: 5
Page 1 of 1 (5 items)
(C) 2007 User Group Italiano di SQL Server