Есть ли способ обновить любую комбинацию столбцов в таблице? - PullRequest
1 голос
/ 05 апреля 2019

Есть ли эффективный способ обновления любой комбинации столбцов в таблице?

Например, если вы возьмете таблицу Employees ниже. Я привел несколько примеров обновлений, которые могут встречаться в этой таблице. По мере увеличения размера таблицы увеличивается потенциальное количество уникальных условий обновления.

| EmployeeId | EmployeeName | TeamName | Title | ReportingManager | Salary |

Некоторые примеры функциональности с использованием таблицы выше:

  • Сотрудник повышен: обновите Title и Salary
  • Команда смены сотрудников под тем же менеджером отчетов: Обновление TeamName
  • Команда смены сотрудников под другим диспетчером отчетов: обновление TeamName и ReportingManager
  • Сотрудник получает нового менеджера отчетов: обновление ReportingManager
  • Сотрудник меняет имя: Обновление EmployeeName

Я слышал об использовании TVP с каждым перечисленным столбцом в таблице. TVP также имеет битовый флаг для обозначения того, что рассматриваемый столбец изменился, а затем поле значения, которое содержит новое значение для обновления столбца. Примерно так:

| ColumnName | WasValueChanged | Value |
| EmployeeName | 0 | NULL |
| TeamName | 1 | Team B |
| Title | 0 | NULL |
| ReportingManager | 1 | John Smith |
| Salary | 0 | NULL |

Это сделано, но это не самое чистое решение. А при сохранении и извлечении данных в C # есть ли способ сделать это без использования DataTable или передачи всего объекта Employee?

Ответы [ 2 ]

1 голос
/ 05 апреля 2019

Вы можете просто обновить все столбцы каждый раз.Вы просто обновляете те же значения, когда данные не меняются.

CREATE PROCEDURE UpdateEmployee(
     @EmployeeId        int,
     @EmployeeName      varchar(250),
     @TeamName          varchar(250),
     @Title             varchar(250),
     @ReportingManager  int,
     @Salary            decimal(18,4)
)

UPDATE Employees SET
    EmployeeName      = ISNULL( @EmployeeName    , EmployeeName    ),
    TeamName          = ISNULL( @TeamName        , TeamName        ),
    Title             = ISNULL( @Title           , Title           ),
    ReportingManager  = ISNULL( @ReportingManager, ReportingManager),
    Salary            = ISNULL( @Salary          , Salary          )
WHERE EmployeeId = @EmployeeId;

Однако вы можете упустить что-то важное.Чтобы отслеживать эти изменения и сохранять достоверность информации, вам нужна дополнительная таблица, которая может отслеживать все изменения.Представьте, что у менеджера отличные результаты, поэтому он перешел в известную команду, которая не преуспела.Сразу после этого кто-то просматривает результаты по командам и показывает этому менеджеру плохие результаты из-за его новой команды.Это приводит к тому, что менеджер увольняется или теряет бонус.

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

1 голос
/ 05 апреля 2019

Использование параметра табличного значения, на мой взгляд, является достойным решением. Каким-то образом вам нужно указать процедуре, какие столбцы обновлять, и их значение. Один из вариантов, если поля не обнуляемы, будет:

create procedure employee_update
    @title nvarchar(100) =null,
    @teamName nvarchar(100)=null
as
update employee
set title=case when(@title is null) then title else @title end,
    teamname=case when (@teamname is null) then teamname else @teamname end

Другим вариантом будет передача данных в виде большого двоичного объекта, такого как JSON или XML, тогда вы можете выполнить ту же логику, однако я все еще думаю, что TVP чище

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...