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

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