Avatar billede komputerdk Mester
18. juli 2017 - 15:41 Der er 7 kommentarer

Nem historiktabel (ved changes, delete og nye) ?

Hi
Jeg importerer en fixed width format fil til en tabel (ca 100 kolonner) - denne tabel kører jeg en forespørgsel så files "deles" korrekt.

Der er et unikt løbenummer i filen.

Anyway - når jeg importerer en ny fil, hvordan får jeg lavet en historik tabel  - fx et gyldigt fra og til felt.

Den skal registere
1. Eksisterende ID ændrer underlæggende felter = gl record opdaterer TIL til dagsdato+1, ny record får FRA dags dato
2. Nyt id = ny record (fra ændres til dagsdato)
3. ID slettes (mangler i fil),  TIL felt opdateret til dags dato+1.


fx (punkt 1)
data før opdatering

[ID] [Vægt] [Fra] [Til]
1 ; 2000 ; 01-01-2017;null

Ny fil ændrer Vægt så bliver den
1;2000;01-01-2017; 18-07-2017
1;2500;19-07-2017;null

Punkt 2
ID 2 er ikke i tabellen før

2;8000;19-07-2017;null

Punkt 3
ID 1 slettes

Før
1;2000;01-01-2017; 18-07-2017
1;2500;19-07-2017;null

Efter
1;2000;01-01-2017; 18-07-2017
1;2500;19-07-2017;19-07-2017
Avatar billede keysersoze Guru
19. juli 2017 - 09:25 #1
Hvis jeg forstår dig korrekt så kan du prøve at kigge på triggers.
Avatar billede komputerdk Mester
26. juli 2017 - 09:33 #2
I triggeren skal der også være en kode der sammenligner det indsatte med det gamle datasæt ....
Avatar billede keysersoze Guru
26. juli 2017 - 09:46 #3
Var det et spørgsmål eller en konklusion?
Avatar billede komputerdk Mester
02. august 2017 - 17:36 #4
spørgsmål.... ;)
Avatar billede keysersoze Guru
04. august 2017 - 00:49 #5
Det burde du også kunne - det er lang tid siden jeg har arbejdet med triggers, men du kan prøve at kigge på COLUMNS_UPDATED eller selecte data fra inserted og deleted tabellerne.
Avatar billede Slettet bruger
15. august 2017 - 14:13 #6
Du skal bruge det som hedder SCD2 .

Eksempel på nettet:

https://www.purplefrogsystems.com/blog/2012/01/using-t-sql-merge-to-load-data-warehouse-dimensions/

og her et eksempel som kan håndtere hvis din kilde ikke har rækken mere.

INSERT INTO Customer
  ( FirstName
    ,LastName
    ,Title
    ,DoB
    ,Email
    ,LastUpdated
    ,IsRowCurrent
    ,ValidFrom
    ,ValidTo
  )
SELECT
    FirstName
    ,LastName
    ,Title
    ,DoB
    ,Email
    ,GETDATE()    --LastUpdated
    ,1            --IsRowCurrent
    ,GETDATE()    --ValidFrom
    ,'9999-12-31' --ValidTo
FROM (
  MERGE Customer        AS [Target]
  USING StagingCustomer AS [Source]
    ON Target.Email        = Source.Email
    AND Target.IsRowCurrent = 1
  WHEN MATCHED AND
      (
          Target.FirstName <> Source.FirstName
        OR Target.LastName  <> Source.LastName
        OR Target.Title    <> Source.Title
      )
      THEN UPDATE SET
        IsRowCurrent    = 0
        ,LastUpdated      = GETDATE()
        ,ValidTo          = GETDATE()
  WHEN NOT MATCHED BY TARGET
      THEN INSERT (
          FirstName
        ,LastName
        ,Title
        ,DoB
        ,Email
        ,LastUpdated
        ,IsRowCurrent
        ,ValidFrom
        ,ValidTo
        ) VALUES (
          Source.FirstName
        ,Source.LastName
        ,Source.Title
        ,Source.DoB
        ,Source.Email
        ,GETDATE()      --LastUpdated
        ,1              --IsRowCurrent
        ,GETDATE()      --ValidFrom
        ,'9999-12-31'  --ValidTo
        )
  WHEN NOT MATCHED BY SOURCE AND Target.IsRowCurrent = 1
      THEN UPDATE SET
          IsRowCurrent = 0
        ,LastUpdated  = GETDATE()
        ,ValidTo      = GETDATE()
  OUTPUT $action AS Action
        ,[Source].*
) AS MergeOutput
WHERE MergeOutput.Action = 'UPDATE'
  AND Email IS NOT NULL
;
Avatar billede Slettet bruger
15. august 2017 - 14:46 #7
og her er koden så du kan bruge til dit eget. Du kan evt. overveje at få en kolonne med ind som hedder isdeleted og så sæt dem som 0 i initial leverence og i not matced by target sætter du den så til 1

INSERT INTO [dbo].[targethistorik]
  ( ID,Vægt,Fra,Til,IsCurrent
  )
SELECT
    ID,VÆGT
  -- ,GETDATE()    --LastUpdated
    ,GETDATE()    --ValidFrom
    ,'9999-12-31' --ValidTo
    ,1            --IsRowCurrent
 
FROM (
  MERGE [dbo].[targethistorik]        AS [Target]
  USING Kildehisotrik AS [Source]
    ON Target.ID        = Source.ID
    AND Target.IsCurrent = 1
  WHEN MATCHED AND
      (
          Target.VÆGT <> Source.VÆGT
   
      )
      THEN UPDATE SET
        IsCurrent    = 0
      -- ,LastUpdated      = GETDATE()
        ,Til          = GETDATE()
  WHEN NOT MATCHED BY TARGET
      THEN INSERT (
          ID,VÆGT,IsCurrent,Fra,Til
        ) VALUES (
          Source.ID
        ,Source.VÆGT
     
     
        ,1              --IsRowCurrent
        ,GETDATE()      --ValidFrom
        ,'9999-12-31'  --ValidTo
        )
  WHEN NOT MATCHED BY SOURCE AND Target.IsCurrent = 1
      THEN UPDATE SET
          IsCurrent = 0
      -- ,LastUpdated  = GETDATE()
        ,Til      = GETDATE()
  OUTPUT $action AS Action
        ,[Source].*
) AS MergeOutput
WHERE MergeOutput.Action = 'UPDATE'
and ID is not null
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Computerworld tilbyder specialiserede kurser i database-management

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester