У меня есть таблица Customers
, таблица Transactions
и таблица Payments
. Таблица Transactions
представляет платежи клиенту, а таблица Payments
представляет кредиты покупателю. (Обе таблицы имеют внешние ключи к таблице Customers
.)
Баланс клиента рассчитывается с использованием Customers.StartingBalance
плюс сумма всех расходов этого клиента в таблице Transactions
минус сумма всехплатежи этого клиента в таблице Payments
.
Теперь я хочу реализовать функцию архивирования, которая удаляет все транзакции и платежи до определенной даты, а затем обновляет Customers.StartingBalance
так, чтобы окончательный баланс (рассчитывался какописанный в предыдущем абзаце) остается прежним.
Вот что я имею до сих пор:
ALTER PROCEDURE [dbo].[ArchiveData] @ArchiveDateTime DATETIME
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
DECLARE @CustomerBalance TABLE
(
CustomerId INT,
Amount BIGINT
);
BEGIN TRANSACTION;
-- Archive transactions
DELETE Transactions WITH (TABLOCK)
OUTPUT deleted.CustomerId, deleted.TotalAmount INTO @CustomerBalance
WHERE [TimeStamp] < @ArchiveDateTime;
IF EXISTS (SELECT 1 FROM @CustomerBalance)
BEGIN
UPDATE Customers SET StartingBalance = StartingBalance +
(SELECT SUM(Amount) FROM @CustomerBalance cb WHERE Id = cb.CustomerId)
END;
DELETE FROM @CustomerBalance
-- Archive payments
DELETE Payments WITH (TABLOCK)
OUTPUT deleted.CustomerId, deleted.Amount INTO @CustomerBalance
WHERE [Date] < @ArchiveDateTime;
IF EXISTS (SELECT 1 FROM @CustomerBalance)
BEGIN
UPDATE Customers SET StartingBalance = StartingBalance -
(SELECT SUM(Amount) FROM @CustomerBalance cb WHERE Id = cb.CustomerId)
END;
-- Probably not needed
DELETE FROM @CustomerBalance
COMMIT TRANSACTION;
END
Поскольку SQL не является моей основной компетенцией, я хотел бы получить отзыв об этом. Это кажется "правильным"? Это кажется оптимальным? Кроме того, я не уверен в таких предложениях, как следующие.
UPDATE Customers SET StartingBalance = StartingBalance -
(SELECT SUM(Amount) FROM @CustomerBalance cb WHERE Id = cb.CustomerId)
Что это делает, если @CustomerBalance
не содержит строк для клиента?
Что это делает, если @CustomerBalance
содержит несколько строк для клиента?
Спасибо за любые предложения.