Как правильно обновлять родительскую таблицу на основе нескольких записей дочерних таблиц при отсутствии циклов?Как правильно обновлять родительскую таблицу на основе нескольких записей дочерних таблиц при отсутствии циклов
В приведенном ниже решении используются две таблицы temp и используются циклы, чтобы вернуть правильный баланс.
#customer-balance
является главной таблицей, а #CUSTOMER_DEBIT_ENTRIES
- это таблица с более чем одной записью.
Есть ли другой способ?
IF OBJECT_ID ('tempdb.dbo.#CUSTOMER_BALANCE') IS NOT NULL
DROP TABLE #CUSTOMER_BALANCE
IF OBJECT_ID ('tempdb.dbo.#CUSTOMER_DEBIT_ENTRIES') IS NOT NULL
DROP TABLE #CUSTOMER_DEBIT_ENTRIES
create table #CUSTOMER_BALANCE
([RECNUM] decimal(8,0) IDENTITY(1,1) NOT NULL,
[CUSTOMER_ID][nchar](8) NOT NULL,
[CUST_BALANCE] [decimal] (14,4) DEFAULT((0))
PRIMARY KEY CLUSTERED(RECNUM)
);
INSERT INTO #CUSTOMER_BALANCE
SELECT 'NGR',1500
UNION
SELECT 'ZGR',100
UNION
SELECT 'MKR',1000
UNION
SELECT 'DKR',1500
GO
SELECT * FROM #CUSTOMER_BALANCE
;create table #CUSTOMER_DEBIT_ENTRIES
([RECNUM] decimal(8,0) IDENTITY(1,1) NOT NULL,
[CUSTOMER_ID][nchar](8) NOT NULL,
[DEBIT_ENTRY] [decimal] (14,4) DEFAULT((0)),
[PROCESS_FLG] bit default 0,
PRIMARY KEY CLUSTERED(RECNUM)
);
INSERT INTO #CUSTOMER_DEBIT_ENTRIES
SELECT 'NGR',500,0
UNION
SELECT 'ZGR',10,0
UNION
SELECT 'MKR',100,0
UNION
SELECT 'DKR',500,0
UNION
SELECT 'NGR',200,0
UNION
SELECT 'ZGR',20,0
Go
SELECT RECNUM,'#CUSTOMER_BALANCE' AS TABLE_NAME,CUSTOMER_ID,CUST_BALANCE FROM #CUSTOMER_BALANCE
SELECT RECNUM,'#CUSTOMER_DEBIT_ENTRIES' AS TABLE_NAME,CUSTOMER_ID,DEBIT_ENTRY,PROCESS_FLG FROM #CUSTOMER_DEBIT_ENTRIES
-- WRONG RESULT BELOW
Update #CUSTOMER_BALANCE
SET CUST_BALANCE = c.CUST_BALANCE - d.DEBIT_ENTRY
FROM #CUSTOMER_BALANCE c inner join #CUSTOMER_DEBIT_ENTRIES d
on c.CUSTOMER_ID = d.CUSTOMER_ID
--CORRECT RESULTS BELOW USING WHILE LOOPS
DECLARE @counter INT, @counter1 INT, @RECNUM INT
SET @counter = 0
SET @RECNUM = 0
SET @counter1 = (SELECT COUNT(*) FROM #CUSTOMER_DEBIT_ENTRIES WHERE PROCESS_FLG = 0)
WHILE @counter < @counter1
BEGIN
SET @RECNUM = (Select Top 1 RECNUM FROM #CUSTOMER_DEBIT_ENTRIES where PROCESS_FLG = 0)
UPDATE #CUSTOMER_BALANCE
SET CUST_BALANCE = c.CUST_BALANCE - d.DEBIT_ENTRY
FROM #CUSTOMER_BALANCE c inner join (SELECT TOP 1 RECNUM, CUSTOMER_ID,DEBIT_ENTRY,PROCESS_FLG FROM #CUSTOMER_DEBIT_ENTRIES
WHERE RECNUM = @RECNUM AND PROCESS_FLG = 0) d on c.CUSTOMER_ID = d.CUSTOMER_ID
UPDATE #CUSTOMER_DEBIT_ENTRIES
SET PROCESS_FLG = 1 WHERE RECNUM = @RECNUM
set @counter = @counter + 1
END