Проектирование базы данных SQL для SSIS - PullRequest
1 голос
/ 24 июня 2011

ОК, мой первый вопрос, так что здесь.

В настоящее время пользователи используют огромное приложение доступа.Они хотели веб-приложение с некоторыми функциями, основанными на данных Access и с некоторыми изменениями.

Хорошо, нет проблем.Я использовал помощник по миграции на SQL для преобразования данных, а затем написал несколько пакетов служб SSIS, которые выполняются с веб-конца, чтобы позволить приложению обновляться по мере необходимости.Все здесь хорошо.

Здесь я как бы озадачен.Есть 2 вида импорта, ежеквартально и ежегодно.Ежеквартально это хорошо, но ежегодный импорт вызывает проблемы.Годовой импорт может быть для утвержденного бюджета или для предлагаемого бюджета (каждый хранится в отдельной базе данных Access).У меня есть один пакет служб SSIS для каждого типа ежегодного импорта.Таблица, к которой относится информация, выглядит следующим образом.

CREATE TABLE Budget
(
    BudgetID           uniqueidentifier NOT NULL,
    ProjectNumber      int NOT NULL,
    SubProjectNumber   varchar(6) NOT NULL,
    FiscalYearBegin    int NOT NULL,
    FiscalYearEnd      int NOT NULL,
    Sequence           int NULL,
    QuarterImportDate  datetime NULL,
    ProposedBudget     money NULL,
    AdoptedBudget      money NULL,

    CONSTRAINT PK_Budget PRIMARY KEY CLUSTERED 
    (
        BudgetID ASC
    ),

    CONSTRAINT uc_Budget UNIQUE NONCLUSTERED 
    (
        ProjectNumber ASC,
        SubProjectNumber ASC,
        FiscalYearBegin ASC,
        FiscalYearEnd ASC,
        Sequence ASC
    )
)

Кроме того, может быть несколько версий бюджета на конкретный год в терминах Project, SubProject, FiscalYearBegin иFiscalYearEnd.Вот почему существует порядковый номер.

Таким образом, проблема становится, так как у меня есть 2 разных пакета служб SSIS, каждый из которых является оператором обновления для одного конкретного столбца (либо ProposedBudget, либо AdoptedBudget),У меня нет эффективного способа отследить правильную последовательность.

Пожалуйста, дайте мне знать, если я смогу сделать это как-нибудь понятнее, и любой совет будет отличным!

Спасибо.

Ответы [ 2 ]

0 голосов
/ 24 июня 2011

Примерно так, используя BudgetType. Конечно, вы, вероятно, создадите таблицу кодов для этих или битовое поле IsAdopted. Но вы поняли.

Select 
budgets.*
,row_number() over(partition by 
   ProjectNumber
  ,SubProjectNumber
  ,FiscalYearBegin
  ,FiscalYearEnd 
   order by QuarterImportDate) as SequenceNumber
From
(
  Select
  ProjectNumber
  ,SubProjectNumber
  ,FiscalYearBegin
  ,FiscalYearEnd
  ,QuarterImportDate
  ,'Proposed' as BudgetType
  ,ProposedBudget as Budget
  From sourceProposed

  Union

  Select
  ProjectNumber
  ,SubProjectNumber
  ,FiscalYearBegin
  ,FiscalYearEnd
  ,QuarterImportDate
  ,'Adopted' as BudgetType
  ,AdoptedBudget as Budget
  From sourceAdopted
) as budgets
0 голосов
/ 24 июня 2011

Примерно так получится следующий элемент с пустым AdoptedBudget, но я думаю, что вам понадобится курсор, когда есть несколько AdoptedBudget.Я думал о создании вложенного подзапроса с обновлением, но это не сработает, когда есть несколько AdoptedBudgets.Похоже, что в исходном приложении им следует выбирать ProposedBudget всякий раз, когда они добавляют AdoptedBudget, чтобы можно было создать связь.Таким образом, становится ясно, какой AdoptedBudget подходит к какому ProposedBudget, и это будет простое объединение.У меня почти такой же сценарий, но разница в том, что я не сохраняю все версии.Мне нужно только сохранить самый последний "ProposedBudget" и самый последний "AdoptedBudget".Немного сложнее попытаться упорядочить их все.

  --get the smallest SequenceId with an unfilled AdoptedBudget
  Select min(SequenceID), 
    ProjectNumber, 
    FiscalYearBegin, 
    SubProjectNumber --any other fields needed for the join
  From Budgets b
  Where AdoptedBudget is null
  Group By 
    ProjectNumber, 
    FiscalYearBegin, 
    SubProjectNumber --any other fields needed for the join


--This won't work I don't believe
Update Budgets
Set AdoptedBudget = BudgetAmount
From Budgets b
Inner Join SourceAdoptedBudgets ab on 
  b.ProjectNumber = ab.ProjectNumber
  b.FiscalYearBegin = ab.FiscalYearBegin
  b.FiscalYearEnd = ab.FiscalYearEnd
Inner Join
(
  --get the smallest SequenceId with an unfilled AdoptedBudget
  Select min(SequenceID), 
    ProjectNumber, 
    FiscalYearBegin, 
    SubProjectNumber --any other fields needed for the join
  From Budgets b
  Where AdoptedBudget is null
  Group By 
    ProjectNumber, 
    FiscalYearBegin, 
    SubProjectNumber --any other fields needed for the join
) as nextBudgets
on --the join fields again
...