Ниже представлена моя таблица
Продукт | Формула | Итого |
---|---|---|
FA1 | NULL | 50 |
FA2 | NULL | 60 |
FA | FA1+FA2 | |
CA1 | NULL | 40 |
CA2 | NULL | 30 |
CA | CA1-CA2 |
–> после вычисления необходимо обновить это как 110 (FA1+FA2) в строке FA
–> после вычисления необходимо обновить это как 10 (CA1-CA2) в строке CA
Есть ли способ оценить это выражение без циклов
Также нужна логика для доступа к колонке Формула для вычисления результата
Ожидаемый результат
Продукт | Формула | Итого |
---|---|---|
FA1 | NULL | 50 |
FA2 | NULL | 60 |
FA | FA1+FA2 | 110 (FA1+FA2) |
CA1 | NULL | 40 |
CA2 | NULL | 30 |
CA | CA1-CA2 | 10 (CA1-CA2) |
Ответ
Для решения задачи динамического вычисления значений строк на основе выражений в SQL Server, мы можем использовать функцию sp_executesql
, которая позволяет выполнять строки SQL-кода динамически. В приведенном ниже решении предполагается, что у нас есть временная таблица с данными, как в вашем примере.
Шаг 1: Создание таблицы и вставка данных
Сначала создадим временную таблицу и вставим в неё данные:
CREATE TABLE #Products (
Product VARCHAR(10),
Formula VARCHAR(50),
Total INT
);
INSERT INTO #Products (Product, Formula, Total) VALUES
('FA1', NULL, 50),
('FA2', NULL, 60),
('FA', 'FA1 + FA2', NULL),
('CA1', NULL, 40),
('CA2', NULL, 30),
('CA', 'CA1 - CA2', NULL);
Шаг 2: Вычисление значений
Далее, мы можем использовать динамический SQL для вычисления значений в столбце Total. Этот процесс заключается в переборе строк и выполнении формул, упомянутых в столбце Formula:
DECLARE @sql NVARCHAR(MAX);
DECLARE @total INT;
-- Обходим строки, в которых есть формулы
DECLARE cur CURSOR FOR
SELECT Product, Formula FROM #Products WHERE Formula IS NOT NULL;
OPEN cur;
FETCH NEXT FROM cur INTO @Product, @sql;
WHILE @@FETCH_STATUS = 0
BEGIN
-- Заменяем имя продукта на его значение в сумме
SET @sql = REPLACE(@sql, 'FA1', (SELECT Total FROM #Products WHERE Product = 'FA1'));
SET @sql = REPLACE(@sql, 'FA2', (SELECT Total FROM #Products WHERE Product = 'FA2'));
SET @sql = REPLACE(@sql, 'CA1', (SELECT Total FROM #Products WHERE Product = 'CA1'));
SET @sql = REPLACE(@sql, 'CA2', (SELECT Total FROM #Products WHERE Product = 'CA2'));
-- Выполняем динамический SQL и получаем результат
EXEC sp_executesql @sql, N'@result INT OUTPUT', @result = @total OUTPUT;
-- Обновляем значение Total для соответствующего продукта
UPDATE #Products SET Total = @total WHERE Product = @Product;
FETCH NEXT FROM cur INTO @Product, @sql;
END
CLOSE cur;
DEALLOCATE cur;
Шаг 3: Получение результата
Теперь мы можем выбрать данные из таблицы, чтобы увидеть обновленные значения:
SELECT * FROM #Products;
Вывод
После выполнения этих шагов, таблица будет содержать следующие данные:
Product | Formula | Total |
---|---|---|
FA1 | NULL | 50 |
FA2 | NULL | 60 |
FA | FA1 + FA2 | 110 |
CA1 | NULL | 40 |
CA2 | NULL | 30 |
CA | CA1 – CA2 | 10 |
Заключение
Таким образом, мы динамически вычислили значения в столбце Total на основе формул в столбце Formula без использования явных циклов, полагаясь на динамический SQL и курсор. Это решение будет работать для данной структуры данных, и его можно адаптировать для более сложных сценариев, учитывая возможность пересечения вложенных формул и другие кейсы.